ibrahimlasfar commited on
Commit
8f6aeec
·
1 Parent(s): 362b291

Update design and generation logic

Browse files
main.py CHANGED
@@ -1,17 +1,13 @@
1
  import os
2
  import logging
3
- from fastapi import FastAPI, Request, HTTPException
4
- from fastapi.responses import HTMLResponse, RedirectResponse, JSONResponse
5
  from fastapi.staticfiles import StaticFiles
6
  from fastapi.templating import Jinja2Templates
7
  from starlette.middleware.base import BaseHTTPMiddleware
8
  import gradio as gr
9
  from api.endpoints import router as api_router
10
  from utils.generation import generate, LATEX_DELIMS
11
- from utils.web_search import web_search
12
- from fastapi.security import OAuth2PasswordBearer
13
- from datetime import datetime, timedelta
14
- from jose import JWTError, jwt
15
 
16
  # إعداد التسجيل
17
  logging.basicConfig(level=logging.INFO)
@@ -23,41 +19,18 @@ logger.info("Files in /app/: %s", os.listdir("/app"))
23
  # إعداد العميل لـ Hugging Face Inference API
24
  HF_TOKEN = os.getenv("HF_TOKEN")
25
  if not HF_TOKEN:
26
- logger.error("HF_TOKEN is not set.")
27
  raise ValueError("HF_TOKEN is required for Inference API.")
28
 
29
- # إعدادات JWT لـ OAuth 2.0
30
- SECRET_KEY = os.getenv("JWT_SECRET_KEY", "your-secret-key") # غيّرها في الإنتاج
31
- ALGORITHM = "HS256"
32
- ACCESS_TOKEN_EXPIRE_MINUTES = 30
33
-
34
  # إعدادات الـ queue
35
  QUEUE_SIZE = int(os.getenv("QUEUE_SIZE", 80))
36
  CONCURRENCY_LIMIT = int(os.getenv("CONCURRENCY_LIMIT", 20))
37
 
38
- # إعداد OAuth2
39
- oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/oauth/token")
40
-
41
- # إعداد FastAPI
42
- app = FastAPI(
43
- title="MGZon Chatbot API",
44
- description="API for MGZon Chatbot with support for code generation, analysis, and MGZon-specific queries.",
45
- version="1.0.0",
46
- )
47
-
48
- # ربط الملفات الثابتة والقوالب
49
- app.mount("/static", StaticFiles(directory="static"), name="static")
50
- templates = Jinja2Templates(directory="templates")
51
-
52
- # تضمين API endpoints
53
- app.include_router(api_router)
54
-
55
- # إعداد CSS لـ Gradio
56
  css = """
57
- .gradio-container { max-width: 900px; margin: auto; }
58
- .chatbot { border: 2px solid #ff6f61; border-radius: 15px; background: rgba(255, 255, 255, 0.05); }
59
- .input-textbox { font-size: 18px; border-radius: 10px; }
60
- .submit-btn { background: linear-gradient(45deg, #ff6f61, #e55a50); }
61
  """
62
 
63
  # إعداد واجهة Gradio
@@ -67,21 +40,13 @@ chatbot_ui = gr.ChatInterface(
67
  chatbot=gr.Chatbot(
68
  label="MGZon Chatbot",
69
  type="messages",
70
- height=700,
71
  latex_delimiters=LATEX_DELIMS,
72
- avatar_images=(
73
- "https://raw.githubusercontent.com/Mark-Lasfar/MGZon/main/public/icons/mg.svg",
74
- "https://raw.githubusercontent.com/Mark-Lasfar/MGZon/main/public/icons/mg.svg",
75
- ),
76
  ),
77
  additional_inputs_accordion=gr.Accordion("⚙️ Settings", open=True),
78
  additional_inputs=[
79
- gr.Textbox(
80
- label="System prompt",
81
- value="You are a helpful assistant capable of code generation, analysis, review, and more. Support frameworks like React, Django, Flask, Rails, Laravel, and others.",
82
- lines=2,
83
- ),
84
- gr.Slider(label="Temperature", minimum=0.0, maximum=1.0, step=0.1, value=0.7),
85
  gr.Radio(label="Reasoning Effort", choices=["low", "medium", "high"], value="medium"),
86
  gr.Checkbox(label="Enable DeepSearch (web browsing)", value=True),
87
  gr.Slider(label="Max New Tokens", minimum=50, maximum=128000, step=50, value=4096),
@@ -94,24 +59,29 @@ chatbot_ui = gr.ChatInterface(
94
  ["Analyze the performance of a Django REST API."],
95
  ["Tell me about MGZon products and services."],
96
  ["Create a Flask route for user authentication."],
97
- ["Generate a Laravel controller for user management."],
98
  ["What are the latest trends in AI?"],
99
  ["Provide guidelines for publishing a technical blog post."],
100
  ["Who is the founder of MGZon?"],
101
  ],
102
  title="MGZon Chatbot",
103
- description=(
104
- "A versatile chatbot powered by GPT-OSS-20B and MGZON/Veltrix. Supports code generation, analysis, review, web search, and MGZon-specific queries. "
105
- "Built by <a href='https://mark-elasfar.web.app/' target='_blank'>Mark Al-Asfar</a>. "
106
- "Licensed under Apache 2.0. <strong>DISCLAIMER:</strong> Analysis may contain internal thoughts not suitable for final response."
107
- ),
108
  theme="gradio/soft",
109
  css=css,
110
  )
111
 
 
 
 
112
  # ربط Gradio مع FastAPI
113
  app = gr.mount_gradio_app(app, chatbot_ui, path="/gradio")
114
 
 
 
 
 
 
 
 
115
  # Middleware لمعالجة 404
116
  class NotFoundMiddleware(BaseHTTPMiddleware):
117
  async def dispatch(self, request: Request, call_next):
@@ -126,35 +96,6 @@ class NotFoundMiddleware(BaseHTTPMiddleware):
126
 
127
  app.add_middleware(NotFoundMiddleware)
128
 
129
- # OAuth 2.0 token endpoint (مثال أولي)
130
- @app.post("/oauth/token")
131
- async def token():
132
- """إنشاء رمز OAuth 2.0 (مثال أولي)."""
133
- access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
134
- access_token = jwt.encode(
135
- {"sub": "mgzon_user", "exp": datetime.utcnow() + access_token_expires},
136
- SECRET_KEY,
137
- algorithm=ALGORITHM,
138
- )
139
- return {"access_token": access_token, "token_type": "bearer"}
140
-
141
- # Health check endpoint
142
- @app.get("/api/health")
143
- async def health_check():
144
- """فحص حالة النموذج والخدمة."""
145
- try:
146
- # اختبار اتصال بسيط بنموذج افتراضي
147
- client = OpenAI(api_key=HF_TOKEN, base_url=FALLBACK_API_ENDPOINT, timeout=10.0)
148
- client.chat.completions.create(
149
- model=TERTIARY_MODEL_NAME,
150
- messages=[{"role": "user", "content": "Ping"}],
151
- max_tokens=10,
152
- )
153
- return JSONResponse({"status": "healthy", "model": TERTIARY_MODEL_NAME})
154
- except Exception as e:
155
- logger.error(f"Health check failed: {e}")
156
- return JSONResponse({"status": "unhealthy", "error": str(e)}, status_code=503)
157
-
158
  # Root endpoint
159
  @app.get("/", response_class=HTMLResponse)
160
  async def root(request: Request):
@@ -168,11 +109,7 @@ async def docs(request: Request):
168
  # Redirect لـ /gradio
169
  @app.get("/launch-chatbot", response_class=RedirectResponse)
170
  async def launch_chatbot():
171
- try:
172
- return RedirectResponse(url="/gradio")
173
- except Exception as e:
174
- logger.error(f"Failed to redirect to /gradio: {e}")
175
- raise HTTPException(status_code=500, detail="Failed to redirect to chatbot")
176
 
177
  # تشغيل الخادم
178
  if __name__ == "__main__":
 
1
  import os
2
  import logging
3
+ from fastapi import FastAPI, Request
4
+ from fastapi.responses import HTMLResponse, RedirectResponse
5
  from fastapi.staticfiles import StaticFiles
6
  from fastapi.templating import Jinja2Templates
7
  from starlette.middleware.base import BaseHTTPMiddleware
8
  import gradio as gr
9
  from api.endpoints import router as api_router
10
  from utils.generation import generate, LATEX_DELIMS
 
 
 
 
11
 
12
  # إعداد التسجيل
13
  logging.basicConfig(level=logging.INFO)
 
19
  # إعداد العميل لـ Hugging Face Inference API
20
  HF_TOKEN = os.getenv("HF_TOKEN")
21
  if not HF_TOKEN:
22
+ logger.error("HF_TOKEN is not set in environment variables.")
23
  raise ValueError("HF_TOKEN is required for Inference API.")
24
 
 
 
 
 
 
25
  # إعدادات الـ queue
26
  QUEUE_SIZE = int(os.getenv("QUEUE_SIZE", 80))
27
  CONCURRENCY_LIMIT = int(os.getenv("CONCURRENCY_LIMIT", 20))
28
 
29
+ # إعداد CSS
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  css = """
31
+ .gradio-container { max-width: 800px; margin: auto; }
32
+ .chatbot { border: 1px solid #ccc; border-radius: 10px; }
33
+ .input-textbox { font-size: 16px; }
 
34
  """
35
 
36
  # إعداد واجهة Gradio
 
40
  chatbot=gr.Chatbot(
41
  label="MGZon Chatbot",
42
  type="messages",
43
+ height=600,
44
  latex_delimiters=LATEX_DELIMS,
 
 
 
 
45
  ),
46
  additional_inputs_accordion=gr.Accordion("⚙️ Settings", open=True),
47
  additional_inputs=[
48
+ gr.Textbox(label="System prompt", value="You are a helpful assistant capable of code generation, analysis, review, and more.", lines=2),
49
+ gr.Slider(label="Temperature", minimum=0.0, maximum=1.0, step=0.1, value=0.9),
 
 
 
 
50
  gr.Radio(label="Reasoning Effort", choices=["low", "medium", "high"], value="medium"),
51
  gr.Checkbox(label="Enable DeepSearch (web browsing)", value=True),
52
  gr.Slider(label="Max New Tokens", minimum=50, maximum=128000, step=50, value=4096),
 
59
  ["Analyze the performance of a Django REST API."],
60
  ["Tell me about MGZon products and services."],
61
  ["Create a Flask route for user authentication."],
 
62
  ["What are the latest trends in AI?"],
63
  ["Provide guidelines for publishing a technical blog post."],
64
  ["Who is the founder of MGZon?"],
65
  ],
66
  title="MGZon Chatbot",
67
+ description="A versatile chatbot powered by MGZON/Veltrix for MGZon queries. Supports code generation, analysis, review, web search, and MGZon-specific queries. Licensed under Apache 2.0.",
 
 
 
 
68
  theme="gradio/soft",
69
  css=css,
70
  )
71
 
72
+ # إعد��د FastAPI
73
+ app = FastAPI(title="MGZon Chatbot API")
74
+
75
  # ربط Gradio مع FastAPI
76
  app = gr.mount_gradio_app(app, chatbot_ui, path="/gradio")
77
 
78
+ # ربط الملفات الثابتة والقوالب
79
+ app.mount("/static", StaticFiles(directory="static"), name="static")
80
+ templates = Jinja2Templates(directory="templates")
81
+
82
+ # تضمين API endpoints
83
+ app.include_router(api_router)
84
+
85
  # Middleware لمعالجة 404
86
  class NotFoundMiddleware(BaseHTTPMiddleware):
87
  async def dispatch(self, request: Request, call_next):
 
96
 
97
  app.add_middleware(NotFoundMiddleware)
98
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  # Root endpoint
100
  @app.get("/", response_class=HTMLResponse)
101
  async def root(request: Request):
 
109
  # Redirect لـ /gradio
110
  @app.get("/launch-chatbot", response_class=RedirectResponse)
111
  async def launch_chatbot():
112
+ return RedirectResponse(url="/gradio")
 
 
 
 
113
 
114
  # تشغيل الخادم
115
  if __name__ == "__main__":
requirements.txt CHANGED
@@ -10,4 +10,4 @@ beautifulsoup4==4.12.3
10
  tenacity==8.5.0
11
  selenium==4.25.0
12
  jinja2==3.1.4
13
- python-jose[cryptography]
 
10
  tenacity==8.5.0
11
  selenium==4.25.0
12
  jinja2==3.1.4
13
+ cachetools==5.5.0
static/js/scripts.js CHANGED
@@ -1,3 +1,4 @@
 
1
  function copyCode(button) {
2
  const code = button.previousElementSibling.querySelector('code').textContent;
3
  navigator.clipboard.writeText(code).then(() => {
@@ -6,12 +7,18 @@ function copyCode(button) {
6
  });
7
  }
8
 
 
9
  document.getElementById('chatbot-link')?.addEventListener('click', (e) => {
10
  e.preventDefault();
11
- window.location.href = '/gradio';
 
 
 
 
 
12
  });
13
 
14
- // تأثيرات للكروت
15
  document.querySelectorAll('.feature-card, .footer-card, .news-card').forEach(card => {
16
  card.addEventListener('mouseenter', () => {
17
  card.style.transform = 'scale(1.05) rotate(1deg)';
@@ -21,13 +28,10 @@ document.querySelectorAll('.feature-card, .footer-card, .news-card').forEach(car
21
  });
22
  });
23
 
24
- // إغلاق/فتح الـ sidebar على الموبايل
25
  document.addEventListener('DOMContentLoaded', () => {
26
  const sidebar = document.querySelector('.sidebar');
27
- const toggleBtn = document.createElement('button');
28
- toggleBtn.textContent = '☰';
29
- toggleBtn.className = 'sidebar-toggle';
30
- document.body.prepend(toggleBtn);
31
 
32
  toggleBtn.addEventListener('click', () => {
33
  sidebar.classList.toggle('active');
 
1
+ // Copy Code
2
  function copyCode(button) {
3
  const code = button.previousElementSibling.querySelector('code').textContent;
4
  navigator.clipboard.writeText(code).then(() => {
 
7
  });
8
  }
9
 
10
+ // Redirect to /gradio with loading animation
11
  document.getElementById('chatbot-link')?.addEventListener('click', (e) => {
12
  e.preventDefault();
13
+ const btn = e.target;
14
+ btn.querySelector('.loading').classList.remove('hidden');
15
+ btn.disabled = true;
16
+ setTimeout(() => {
17
+ window.location.href = '/gradio';
18
+ }, 1000); // تأخير بسيط عشان الـ animation
19
  });
20
 
21
+ // Card animations
22
  document.querySelectorAll('.feature-card, .footer-card, .news-card').forEach(card => {
23
  card.addEventListener('mouseenter', () => {
24
  card.style.transform = 'scale(1.05) rotate(1deg)';
 
28
  });
29
  });
30
 
31
+ // Sidebar toggle for mobile
32
  document.addEventListener('DOMContentLoaded', () => {
33
  const sidebar = document.querySelector('.sidebar');
34
+ const toggleBtn = document.querySelector('.sidebar-toggle');
 
 
 
35
 
36
  toggleBtn.addEventListener('click', () => {
37
  sidebar.classList.toggle('active');
templates/404.html CHANGED
@@ -4,26 +4,26 @@
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>404 - Page Not Found</title>
7
- <link rel="stylesheet" href="/static/css/styles.css">
8
  <link href="https://cdn.jsdelivr.net/npm/boxicons@2.1.4/css/boxicons.min.css" rel="stylesheet">
9
  </head>
10
- <body>
11
- <div class="container">
12
- <img src="https://raw.githubusercontent.com/Mark-Lasfar/MGZon/main/public/icons/mg.svg" alt="MGZon Logo" class="logo">
13
- <h1>404 - Page Not Found 😕</h1>
14
- <p>Oops! Looks like you wandered into the wrong corner of the internet.</p>
15
- <a href="/" class="btn">Back to Home</a>
16
  </div>
17
- <footer>
18
- <div class="footer-container">
19
- <img src="https://raw.githubusercontent.com/Mark-Lasfar/MGZon/main/public/icons/mg.svg" alt="MGZon Logo" class="footer-logo">
20
- <p>Developed by <a href="https://mark-elasfar.web.app/" target="_blank">Mark Al-Asfar</a> | Powered by MGZon AI</p>
21
- <div class="footer-social">
22
- <a href="https://github.com/Mark-Lasfar/MGZon"><i class="bx bxl-github"></i></a>
23
- <a href="https://x.com/MGZon"><i class="bx bxl-twitter"></i></a>
24
- <a href="https://www.facebook.com/people/Mark-Al-Asfar/pfbid02GMisUQ8AqWkNZjoKtWFHH1tbdHuVscN1cjcFnZWy9HkRaAsmanBfT6mhySAyqpg4l/"><i class="bx bxl-facebook"></i></a>
25
  </div>
26
- <p>© 2025 Mark Al-Asfar & MGZon AI. All rights reserved.</p>
27
  </div>
28
  </footer>
29
  <script src="/static/js/scripts.js"></script>
 
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>404 - Page Not Found</title>
7
+ <link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
8
  <link href="https://cdn.jsdelivr.net/npm/boxicons@2.1.4/css/boxicons.min.css" rel="stylesheet">
9
  </head>
10
+ <body class="bg-gray-900 text-white min-h-screen flex flex-col">
11
+ <div class="container max-w-6xl mx-auto text-center py-12 flex-1">
12
+ <img src="https://raw.githubusercontent.com/Mark-Lasfar/MGZon/main/public/icons/mg.svg" alt="MGZon Logo" class="w-32 h-32 mx-auto mb-6 animate-bounce">
13
+ <h1 class="text-5xl font-bold mb-4">404 - Page Not Found 😕</h1>
14
+ <p class="text-lg mb-8">Oops! Looks like you wandered into the wrong corner of the internet.</p>
15
+ <a href="/" class="inline-block bg-gradient-to-r from-orange-500 to-red-500 text-white px-8 py-4 rounded-full text-lg font-semibold hover:scale-105 transition transform">Back to Home</a>
16
  </div>
17
+ <footer class="bg-gradient-to-r from-blue-900 to-gray-900 py-12">
18
+ <div class="container max-w-6xl mx-auto text-center">
19
+ <img src="https://raw.githubusercontent.com/Mark-Lasfar/MGZon/main/public/icons/mg.svg" alt="MGZon Logo" class="w-24 h-24 mx-auto mb-6 animate-pulse">
20
+ <p class="mb-4">Developed by <a href="https://mark-elasfar.web.app/" target="_blank" class="text-orange-500 hover:underline">Mark Al-Asfar</a> | Powered by <a href="https://hager-zon.vercel.app/" target="_blank" class="text-orange-500 hover:underline">MGZon AI</a></p>
21
+ <div class="flex justify-center gap-6">
22
+ <a href="https://github.com/Mark-Lasfar/MGZon" class="text-2xl text-white hover:text-orange-500 transition"><i class="bx bxl-github"></i></a>
23
+ <a href="https://x.com/MGZon" class="text-2xl text-white hover:text-orange-500 transition"><i class="bx bxl-twitter"></i></a>
24
+ <a href="https://www.facebook.com/people/Mark-Al-Asfar/pfbid02GMisUQ8AqWkNZjoKtWFHH1tbdHuVscN1cjcFnZWy9HkRaAsmanBfT6mhySAyqpg4l/" class="text-2xl text-white hover:text-orange-500 transition"><i class="bx bxl-facebook"></i></a>
25
  </div>
26
+ <p class="mt-6">© 2025 Mark Al-Asfar & MGZon AI. All rights reserved.</p>
27
  </div>
28
  </footer>
29
  <script src="/static/js/scripts.js"></script>
templates/docs.html CHANGED
@@ -4,31 +4,57 @@
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>MGZon API Documentation</title>
7
- <link rel="stylesheet" href="/static/css/styles.css">
 
8
  <link href="https://cdn.jsdelivr.net/npm/boxicons@2.1.4/css/boxicons.min.css" rel="stylesheet">
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  </head>
10
- <body>
11
- <div class="sidebar">
12
- <img src="https://raw.githubusercontent.com/Mark-Lasfar/MGZon/main/public/icons/mg.svg" alt="MGZon Logo" class="sidebar-logo">
13
- <nav>
14
- <a href="/">Home</a>
15
- <a href="/docs" class="active">API Documentation</a>
16
- <a href="https://hager-zon.vercel.app/about">About MGZon</a>
17
- <a href="https://hager-zon.vercel.app/community">Community</a>
18
- <a href="https://mark-elasfar.web.app/" target="_blank">Mark Al-Asfar</a>
 
19
  </nav>
20
  </div>
21
- <div class="container">
22
- <h1>MGZon API Documentation 📚</h1>
23
- <p>
24
- Integrate MGZon Chatbot into your projects with our API. Supports Python (Django, Flask, FastAPI), JavaScript (React, Node.js, Express), Ruby (Rails), PHP (Laravel), and more. Explore the examples below to get started.
25
- </p>
26
- <div class="docs">
27
- <h2>Endpoints</h2>
28
- <div class="code-block">
29
- <h3>POST /api/chat</h3>
30
- <p>Send a chat message to the MGZon Chatbot and get a response.</p>
31
- <pre><code class="language-json">{
 
 
 
 
 
 
 
 
 
 
 
32
  "message": "Your query here",
33
  "system_prompt": "You are a helpful assistant",
34
  "history": [{"role": "user", "content": "Previous message"}, {"role": "assistant", "content": "Previous response"}],
@@ -36,12 +62,11 @@
36
  "max_new_tokens": 4096,
37
  "enable_browsing": false
38
  }</code></pre>
39
- <button class="copy-btn" onclick="copyCode(this)">Copy</button>
40
- </div>
41
- <div class="code-block">
42
- <h3>Python (requests) - Chat</h3>
43
- <p>Make a chat request using Python's requests library.</p>
44
- <pre><code class="language-python">import requests
45
 
46
  response = requests.post(
47
  "https://hager-zon.vercel.app/api/chat",
@@ -53,12 +78,11 @@ response = requests.post(
53
  }
54
  )
55
  print(response.json())</code></pre>
56
- <button class="copy-btn" onclick="copyCode(this)">Copy</button>
57
- </div>
58
- <div class="code-block">
59
- <h3>Python (Django) - Chat</h3>
60
- <p>Integrate with a Django project.</p>
61
- <pre><code class="language-python">import requests
62
  from django.http import JsonResponse
63
  from django.views import View
64
 
@@ -70,12 +94,11 @@ class ChatView(View):
70
  json={"message": data, "system_prompt": "You are a coding expert", "temperature": 0.7}
71
  )
72
  return JsonResponse(response.json())</code></pre>
73
- <button class="copy-btn" onclick="copyCode(this)">Copy</button>
74
- </div>
75
- <div class="code-block">
76
- <h3>Python (Flask) - Chat</h3>
77
- <p>Integrate with a Flask app.</p>
78
- <pre><code class="language-python">from flask import Flask, request, jsonify
79
  import requests
80
 
81
  app = Flask(__name__)
@@ -88,12 +111,11 @@ def chat():
88
  json={"message": data, "system_prompt": "You are a coding expert", "temperature": 0.7}
89
  )
90
  return jsonify(response.json())</code></pre>
91
- <button class="copy-btn" onclick="copyCode(this)">Copy</button>
92
- </div>
93
- <div class="code-block">
94
- <h3>JavaScript (React) - Chat</h3>
95
- <p>Integrate with a React app using fetch.</p>
96
- <pre><code class="language-javascript">import React, { useState } from 'react';
97
 
98
  function ChatComponent() {
99
  const [message, setMessage] = useState('');
@@ -124,12 +146,11 @@ function ChatComponent() {
124
  }
125
 
126
  export default ChatComponent;</code></pre>
127
- <button class="copy-btn" onclick="copyCode(this)">Copy</button>
128
- </div>
129
- <div class="code-block">
130
- <h3>JavaScript (Node.js/Express) - Chat</h3>
131
- <p>Integrate with a Node.js/Express server.</p>
132
- <pre><code class="language-javascript">const express = require('express');
133
  const fetch = require('node-fetch');
134
  const app = express();
135
 
@@ -152,12 +173,11 @@ app.post('/chat', async (req, res) => {
152
  });
153
 
154
  app.listen(3000, () => console.log('Server running on port 3000'));</code></pre>
155
- <button class="copy-btn" onclick="copyCode(this)">Copy</button>
156
- </div>
157
- <div class="code-block">
158
- <h3>Ruby (Rails) - Chat</h3>
159
- <p>Integrate with a Ruby on Rails app.</p>
160
- <pre><code class="language-ruby">require 'httparty'
161
 
162
  class ChatController < ApplicationController
163
  def create
@@ -174,12 +194,11 @@ class ChatController < ApplicationController
174
  render json: response.parsed_response
175
  end
176
  end</code></pre>
177
- <button class="copy-btn" onclick="copyCode(this)">Copy</button>
178
- </div>
179
- <div class="code-block">
180
- <h3>PHP (Laravel) - Chat</h3>
181
- <p>Integrate with a Laravel app.</p>
182
- <pre><code class="language-php">use Illuminate\Support\Facades\Http;
183
 
184
  class ChatController extends Controller
185
  {
@@ -194,88 +213,107 @@ class ChatController extends Controller
194
  return $response->json();
195
  }
196
  }</code></pre>
197
- <button class="copy-btn" onclick="copyCode(this)">Copy</button>
198
- </div>
199
- <div class="code-block">
200
- <h3>Bash (cURL) - Chat</h3>
201
- <pre><code class="language-bash">curl -X POST https://hager-zon.vercel.app/api/chat \
202
  -H "Content-Type: application/json" \
203
  -d '{"message":"Generate a React component","system_prompt":"You are a coding expert","temperature":0.7,"max_new_tokens":4096}'</code></pre>
204
- <button class="copy-btn" onclick="copyCode(this)">Copy</button>
205
- </div>
206
- <div class="code-block">
207
- <h3>POST /api/code</h3>
208
- <p>Generate or modify code for various frameworks.</p>
209
- <pre><code class="language-json">{
 
 
210
  "framework": "React",
211
  "task": "Create a login form component",
212
  "code": "// Existing code (optional)"
213
  }</code></pre>
214
- <button class="copy-btn" onclick="copyCode(this)">Copy</button>
215
- </div>
216
- <div class="code-block">
217
- <h3>POST /api/analysis</h3>
218
- <p>Analyze code or data with detailed insights.</p>
219
- <pre><code class="language-json">{
 
 
220
  "text": "Analyze this Python code: print('Hello World')"
221
  }</code></pre>
222
- <button class="copy-btn" onclick="copyCode(this)">Copy</button>
223
- </div>
224
- <div class="code-block">
225
- <h3>OAuth 2.0 Authentication</h3>
226
- <p>Authenticate with MGZon using OAuth 2.0.</p>
227
- <pre><code class="language-bash">curl -X POST https://hager-zon.vercel.app/oauth/token \
 
 
228
  -H "Content-Type: application/json" \
229
  -d '{"client_id": "YOUR_CLIENT_ID", "client_secret": "YOUR_CLIENT_SECRET", "grant_type": "client_credentials"}'</code></pre>
230
- <button class="copy-btn" onclick="copyCode(this)">Copy</button>
 
 
 
231
  </div>
232
  </div>
233
- <a href="/" class="btn">Back to Home</a>
234
  </div>
235
- <footer>
236
- <div class="footer-container">
237
- <img src="https://raw.githubusercontent.com/Mark-Lasfar/MGZon/main/public/icons/mg.svg" alt="MGZon Logo" class="footer-logo">
238
- <p>Developed by <a href="https://mark-elasfar.web.app/" target="_blank">Mark Al-Asfar</a> | Powered by <a href="https://hager-zon.vercel.app/" target="_blank">MGZon AI</a></p>
239
- <div class="footer-grid">
240
- <div class="footer-card">
241
- <i class="bx bx-mail-send"></i>
242
- <h3>Email Us</h3>
243
- <p>Contact: <a href="mailto:support@mgzon.com">support@mgzon.com</a></p>
244
  </div>
245
- <div class="footer-card">
246
- <i class="bx bx-phone"></i>
247
- <h3>Phone Support</h3>
248
  <p>Call: +1-800-123-4567</p>
249
  </div>
250
- <div class="footer-card">
251
- <i class="bx bx-group"></i>
252
- <h3>Community</h3>
253
- <p>Join: <a href="https://hager-zon.vercel.app/community">mgzon.com/community</a></p>
254
  </div>
255
- <div class="footer-card">
256
- <i class="bx bx-code-alt"></i>
257
- <h3>API Docs</h3>
258
- <p>Explore: <a href="/docs">mgzon.com/docs</a></p>
259
  </div>
260
- <div class="footer-card">
261
- <i class="bx bx-help-circle"></i>
262
- <h3>FAQ</h3>
263
- <p>Read: <a href="https://hager-zon.vercel.app/faq">mgzon.com/faq</a></p>
264
  </div>
265
- <div class="footer-card">
266
- <i class="bx bx-book"></i>
267
- <h3>Documentation</h3>
268
- <p>Learn: <a href="/docs">mgzon.com/docs</a></p>
269
  </div>
270
  </div>
271
- <div class="footer-social">
272
- <a href="https://github.com/Mark-Lasfar/MGZon"><i class="bx bxl-github"></i></a>
273
- <a href="https://x.com/MGZon"><i class="bx bxl-twitter"></i></a>
274
- <a href="https://www.facebook.com/people/Mark-Al-Asfar/pfbid02GMisUQ8AqWkNZjoKtWFHH1tbdHuVscN1cjcFnZWy9HkRaAsmanBfT6mhySAyqpg4l/"><i class="bx bxl-facebook"></i></a>
275
  </div>
276
- <p>© 2025 Mark Al-Asfar & MGZon AI. All rights reserved.</p>
277
  </div>
278
  </footer>
279
  <script src="/static/js/scripts.js"></script>
 
 
 
 
 
 
 
 
 
 
 
280
  </body>
281
  </html>
 
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>MGZon API Documentation</title>
7
+ <link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
8
+ <link href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism.min.css" rel="stylesheet">
9
  <link href="https://cdn.jsdelivr.net/npm/boxicons@2.1.4/css/boxicons.min.css" rel="stylesheet">
10
+ <style>
11
+ @keyframes slideIn {
12
+ from { transform: translateX(-100%); }
13
+ to { transform: translateX(0); }
14
+ }
15
+ .sidebar.active { transform: translateX(0); }
16
+ @media (max-width: 768px) {
17
+ .sidebar { transform: translateX(-100%); }
18
+ .sidebar.active { transform: translateX(0); animation: slideIn 0.3s ease; }
19
+ }
20
+ .tab-content { display: none; }
21
+ .tab-content.active { display: block; }
22
+ </style>
23
  </head>
24
+ <body class="bg-gray-900 text-white min-h-screen flex flex-col">
25
+ <button class="md:hidden fixed top-4 left-4 z-50 text-white text-2xl sidebar-toggle">☰</button>
26
+ <div class="sidebar fixed top-0 left-0 h-full w-64 bg-gradient-to-b from-blue-800 to-orange-500 text-white p-6 flex flex-col md:translate-x-0 transition-transform duration-300">
27
+ <img src="https://raw.githubusercontent.com/Mark-Lasfar/MGZon/main/public/icons/mg.svg" alt="MGZon Logo" class="w-20 h-20 mb-6 animate-pulse">
28
+ <nav class="flex flex-col gap-4">
29
+ <a href="/" class="px-4 py-2 rounded-lg hover:bg-orange-600 transition">Home</a>
30
+ <a href="/docs" class="px-4 py-2 rounded-lg bg-orange-600">API Documentation</a>
31
+ <a href="https://hager-zon.vercel.app/about" class="px-4 py-2 rounded-lg hover:bg-orange-600 transition">About MGZon</a>
32
+ <a href="https://hager-zon.vercel.app/community" class="px-4 py-2 rounded-lg hover:bg-orange-600 transition">Community</a>
33
+ <a href="https://mark-elasfar.web.app/" target="_blank" class="px-4 py-2 rounded-lg hover:bg-orange-600 transition">Mark Al-Asfar</a>
34
  </nav>
35
  </div>
36
+ <div class="flex-1 md:ml-64 p-6">
37
+ <div class="container max-w-6xl mx-auto">
38
+ <div class="text-center py-12">
39
+ <img src="https://raw.githubusercontent.com/Mark-Lasfar/MGZon/main/public/icons/mg.svg" alt="MGZon Logo" class="w-32 h-32 mx-auto mb-6 animate-bounce">
40
+ <h1 class="text-5xl font-bold mb-4 animate-fade-in">MGZon API Documentation 📚</h1>
41
+ <p class="text-lg mb-8">
42
+ Integrate MGZon Chatbot into your projects with our API. Supports Python (Django, Flask, FastAPI), JavaScript (React, Node.js, Express), Ruby (Rails), PHP (Laravel), and more.
43
+ </p>
44
+ </div>
45
+ <div class="docs my-12">
46
+ <h2 class="text-3xl font-bold text-center mb-8">Endpoints</h2>
47
+ <div class="flex flex-wrap gap-4 mb-8">
48
+ <button class="tab-btn bg-orange-500 text-white px-4 py-2 rounded-lg" data-tab="chat">Chat</button>
49
+ <button class="tab-btn bg-gray-700 text-white px-4 py-2 rounded-lg" data-tab="code">Code</button>
50
+ <button class="tab-btn bg-gray-700 text-white px-4 py-2 rounded-lg" data-tab="analysis">Analysis</button>
51
+ <button class="tab-btn bg-gray-700 text-white px-4 py-2 rounded-lg" data-tab="oauth">OAuth</button>
52
+ </div>
53
+ <div id="chat" class="tab-content active">
54
+ <div class="code-block bg-gray-800 p-6 rounded-lg shadow-lg mb-6">
55
+ <h3 class="text-xl font-semibold text-orange-500 mb-2">POST /api/chat</h3>
56
+ <p>Send a chat message to the MGZon Chatbot and get a response.</p>
57
+ <pre><code class="language-json">{
58
  "message": "Your query here",
59
  "system_prompt": "You are a helpful assistant",
60
  "history": [{"role": "user", "content": "Previous message"}, {"role": "assistant", "content": "Previous response"}],
 
62
  "max_new_tokens": 4096,
63
  "enable_browsing": false
64
  }</code></pre>
65
+ <button class="copy-btn bg-orange-500 text-white px-4 py-2 rounded-lg mt-4">Copy</button>
66
+ </div>
67
+ <div class="code-block bg-gray-800 p-6 rounded-lg shadow-lg mb-6">
68
+ <h3 class="text-xl font-semibold text-orange-500 mb-2">Python (requests)</h3>
69
+ <pre><code class="language-python">import requests
 
70
 
71
  response = requests.post(
72
  "https://hager-zon.vercel.app/api/chat",
 
78
  }
79
  )
80
  print(response.json())</code></pre>
81
+ <button class="copy-btn bg-orange-500 text-white px-4 py-2 rounded-lg mt-4">Copy</button>
82
+ </div>
83
+ <div class="code-block bg-gray-800 p-6 rounded-lg shadow-lg mb-6">
84
+ <h3 class="text-xl font-semibold text-orange-500 mb-2">Python (Django)</h3>
85
+ <pre><code class="language-python">import requests
 
86
  from django.http import JsonResponse
87
  from django.views import View
88
 
 
94
  json={"message": data, "system_prompt": "You are a coding expert", "temperature": 0.7}
95
  )
96
  return JsonResponse(response.json())</code></pre>
97
+ <button class="copy-btn bg-orange-500 text-white px-4 py-2 rounded-lg mt-4">Copy</button>
98
+ </div>
99
+ <div class="code-block bg-gray-800 p-6 rounded-lg shadow-lg mb-6">
100
+ <h3 class="text-xl font-semibold text-orange-500 mb-2">Python (Flask)</h3>
101
+ <pre><code class="language-python">from flask import Flask, request, jsonify
 
102
  import requests
103
 
104
  app = Flask(__name__)
 
111
  json={"message": data, "system_prompt": "You are a coding expert", "temperature": 0.7}
112
  )
113
  return jsonify(response.json())</code></pre>
114
+ <button class="copy-btn bg-orange-500 text-white px-4 py-2 rounded-lg mt-4">Copy</button>
115
+ </div>
116
+ <div class="code-block bg-gray-800 p-6 rounded-lg shadow-lg mb-6">
117
+ <h3 class="text-xl font-semibold text-orange-500 mb-2">JavaScript (React)</h3>
118
+ <pre><code class="language-javascript">import React, { useState } from 'react';
 
119
 
120
  function ChatComponent() {
121
  const [message, setMessage] = useState('');
 
146
  }
147
 
148
  export default ChatComponent;</code></pre>
149
+ <button class="copy-btn bg-orange-500 text-white px-4 py-2 rounded-lg mt-4">Copy</button>
150
+ </div>
151
+ <div class="code-block bg-gray-800 p-6 rounded-lg shadow-lg mb-6">
152
+ <h3 class="text-xl font-semibold text-orange-500 mb-2">JavaScript (Node.js/Express)</h3>
153
+ <pre><code class="language-javascript">const express = require('express');
 
154
  const fetch = require('node-fetch');
155
  const app = express();
156
 
 
173
  });
174
 
175
  app.listen(3000, () => console.log('Server running on port 3000'));</code></pre>
176
+ <button class="copy-btn bg-orange-500 text-white px-4 py-2 rounded-lg mt-4">Copy</button>
177
+ </div>
178
+ <div class="code-block bg-gray-800 p-6 rounded-lg shadow-lg mb-6">
179
+ <h3 class="text-xl font-semibold text-orange-500 mb-2">Ruby (Rails)</h3>
180
+ <pre><code class="language-ruby">require 'httparty'
 
181
 
182
  class ChatController < ApplicationController
183
  def create
 
194
  render json: response.parsed_response
195
  end
196
  end</code></pre>
197
+ <button class="copy-btn bg-orange-500 text-white px-4 py-2 rounded-lg mt-4">Copy</button>
198
+ </div>
199
+ <div class="code-block bg-gray-800 p-6 rounded-lg shadow-lg mb-6">
200
+ <h3 class="text-xl font-semibold text-orange-500 mb-2">PHP (Laravel)</h3>
201
+ <pre><code class="language-php">use Illuminate\Support\Facades\Http;
 
202
 
203
  class ChatController extends Controller
204
  {
 
213
  return $response->json();
214
  }
215
  }</code></pre>
216
+ <button class="copy-btn bg-orange-500 text-white px-4 py-2 rounded-lg mt-4">Copy</button>
217
+ </div>
218
+ <div class="code-block bg-gray-800 p-6 rounded-lg shadow-lg mb-6">
219
+ <h3 class="text-xl font-semibold text-orange-500 mb-2">Bash (cURL)</h3>
220
+ <pre><code class="language-bash">curl -X POST https://hager-zon.vercel.app/api/chat \
221
  -H "Content-Type: application/json" \
222
  -d '{"message":"Generate a React component","system_prompt":"You are a coding expert","temperature":0.7,"max_new_tokens":4096}'</code></pre>
223
+ <button class="copy-btn bg-orange-500 text-white px-4 py-2 rounded-lg mt-4">Copy</button>
224
+ </div>
225
+ </div>
226
+ <div id="code" class="tab-content">
227
+ <div class="code-block bg-gray-800 p-6 rounded-lg shadow-lg mb-6">
228
+ <h3 class="text-xl font-semibold text-orange-500 mb-2">POST /api/code</h3>
229
+ <p>Generate or modify code for various frameworks.</p>
230
+ <pre><code class="language-json">{
231
  "framework": "React",
232
  "task": "Create a login form component",
233
  "code": "// Existing code (optional)"
234
  }</code></pre>
235
+ <button class="copy-btn bg-orange-500 text-white px-4 py-2 rounded-lg mt-4">Copy</button>
236
+ </div>
237
+ </div>
238
+ <div id="analysis" class="tab-content">
239
+ <div class="code-block bg-gray-800 p-6 rounded-lg shadow-lg mb-6">
240
+ <h3 class="text-xl font-semibold text-orange-500 mb-2">POST /api/analysis</h3>
241
+ <p>Analyze code or data with detailed insights.</p>
242
+ <pre><code class="language-json">{
243
  "text": "Analyze this Python code: print('Hello World')"
244
  }</code></pre>
245
+ <button class="copy-btn bg-orange-500 text-white px-4 py-2 rounded-lg mt-4">Copy</button>
246
+ </div>
247
+ </div>
248
+ <div id="oauth" class="tab-content">
249
+ <div class="code-block bg-gray-800 p-6 rounded-lg shadow-lg mb-6">
250
+ <h3 class="text-xl font-semibold text-orange-500 mb-2">OAuth 2.0 Authentication</h3>
251
+ <p>Authenticate with MGZon using OAuth 2.0.</p>
252
+ <pre><code class="language-bash">curl -X POST https://hager-zon.vercel.app/oauth/token \
253
  -H "Content-Type: application/json" \
254
  -d '{"client_id": "YOUR_CLIENT_ID", "client_secret": "YOUR_CLIENT_SECRET", "grant_type": "client_credentials"}'</code></pre>
255
+ <button class="copy-btn bg-orange-500 text-white px-4 py-2 rounded-lg mt-4">Copy</button>
256
+ </div>
257
+ </div>
258
+ <a href="/" class="inline-block bg-gradient-to-r from-orange-500 to-red-500 text-white px-8 py-4 rounded-full text-lg font-semibold hover:scale-105 transition transform mt-8">Back to Home</a>
259
  </div>
260
  </div>
 
261
  </div>
262
+ <footer class="bg-gradient-to-r from-blue-900 to-gray-900 py-12 mt-auto">
263
+ <div class="container max-w-6xl mx-auto text-center">
264
+ <img src="https://raw.githubusercontent.com/Mark-Lasfar/MGZon/main/public/icons/mg.svg" alt="MGZon Logo" class="w-24 h-24 mx-auto mb-6 animate-pulse">
265
+ <p class="mb-4">Developed by <a href="https://mark-elasfar.web.app/" target="_blank" class="text-orange-500 hover:underline">Mark Al-Asfar</a> | Powered by <a href="https://hager-zon.vercel.app/" target="_blank" class="text-orange-500 hover:underline">MGZon AI</a></p>
266
+ <div class="grid grid-cols-2 md:grid-cols-3 gap-6">
267
+ <div class="bg-gray-800 p-6 rounded-lg shadow-lg">
268
+ <i class="bx bx-mail-send text-3xl text-orange-500 mb-4"></i>
269
+ <h3 class="text-lg font-semibold mb-2">Email Us</h3>
270
+ <p>Contact: <a href="mailto:support@mgzon.com" class="text-orange-500 hover:underline">support@mgzon.com</a></p>
271
  </div>
272
+ <div class="bg-gray-800 p-6 rounded-lg shadow-lg">
273
+ <i class="bx bx-phone text-3xl text-orange-500 mb-4"></i>
274
+ <h3 class="text-lg font-semibold mb-2">Phone Support</h3>
275
  <p>Call: +1-800-123-4567</p>
276
  </div>
277
+ <div class="bg-gray-800 p-6 rounded-lg shadow-lg">
278
+ <i class="bx bx-group text-3xl text-orange-500 mb-4"></i>
279
+ <h3 class="text-lg font-semibold mb-2">Community</h3>
280
+ <p>Join: <a href="https://hager-zon.vercel.app/community" class="text-orange-500 hover:underline">mgzon.com/community</a></p>
281
  </div>
282
+ <div class="bg-gray-800 p-6 rounded-lg shadow-lg">
283
+ <i class="bx bx-code-alt text-3xl text-orange-500 mb-4"></i>
284
+ <h3 class="text-lg font-semibold mb-2">API Docs</h3>
285
+ <p>Explore: <a href="/docs" class="text-orange-500 hover:underline">mgzon.com/docs</a></p>
286
  </div>
287
+ <div class="bg-gray-800 p-6 rounded-lg shadow-lg">
288
+ <i class="bx bx-help-circle text-3xl text-orange-500 mb-4"></i>
289
+ <h3 class="text-lg font-semibold mb-2">FAQ</h3>
290
+ <p>Read: <a href="https://hager-zon.vercel.app/faq" class="text-orange-500 hover:underline">mgzon.com/faq</a></p>
291
  </div>
292
+ <div class="bg-gray-800 p-6 rounded-lg shadow-lg">
293
+ <i class="bx bx-book text-3xl text-orange-500 mb-4"></i>
294
+ <h3 class="text-lg font-semibold mb-2">Documentation</h3>
295
+ <p>Learn: <a href="/docs" class="text-orange-500 hover:underline">mgzon.com/docs</a></p>
296
  </div>
297
  </div>
298
+ <div class="flex justify-center gap-6 mt-6">
299
+ <a href="https://github.com/Mark-Lasfar/MGZon" class="text-2xl text-white hover:text-orange-500 transition"><i class="bx bxl-github"></i></a>
300
+ <a href="https://x.com/MGZon" class="text-2xl text-white hover:text-orange-500 transition"><i class="bx bxl-twitter"></i></a>
301
+ <a href="https://www.facebook.com/people/Mark-Al-Asfar/pfbid02GMisUQ8AqWkNZjoKtWFHH1tbdHuVscN1cjcFnZWy9HkRaAsmanBfT6mhySAyqpg4l/" class="text-2xl text-white hover:text-orange-500 transition"><i class="bx bxl-facebook"></i></a>
302
  </div>
303
+ <p class="mt-6">© 2025 Mark Al-Asfar & MGZon AI. All rights reserved.</p>
304
  </div>
305
  </footer>
306
  <script src="/static/js/scripts.js"></script>
307
+ <script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/prism.min.js"></script>
308
+ <script>
309
+ document.querySelectorAll('.tab-btn').forEach(btn => {
310
+ btn.addEventListener('click', () => {
311
+ document.querySelectorAll('.tab-btn').forEach(b => b.classList.replace('bg-orange-500', 'bg-gray-700'));
312
+ btn.classList.replace('bg-gray-700', 'bg-orange-500');
313
+ document.querySelectorAll('.tab-content').forEach(tab => tab.classList.remove('active'));
314
+ document.getElementById(btn.dataset.tab).classList.add('active');
315
+ });
316
+ });
317
+ </script>
318
  </body>
319
  </html>
templates/index.html CHANGED
@@ -4,106 +4,139 @@
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>MGZon Chatbot - Powered by AI</title>
7
- <link rel="stylesheet" href="/static/css/styles.css">
 
8
  <link href="https://cdn.jsdelivr.net/npm/boxicons@2.1.4/css/boxicons.min.css" rel="stylesheet">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  </head>
10
- <body>
11
- <div class="sidebar">
12
- <img src="https://raw.githubusercontent.com/Mark-Lasfar/MGZon/main/public/icons/mg.svg" alt="MGZon Logo" class="sidebar-logo">
13
- <nav>
14
- <a href="/" class="active">Home</a>
15
- <a href="/docs">API Documentation</a>
16
- <a href="https://hager-zon.vercel.app/about">About MGZon</a>
17
- <a href="https://hager-zon.vercel.app/community">Community</a>
18
- <a href="https://mark-elasfar.web.app/" target="_blank">Mark Al-Asfar</a>
 
19
  </nav>
20
  </div>
21
- <div class="container">
22
- <h1>Welcome to MGZon Chatbot 🚀</h1>
23
- <p>
24
- MGZon Chatbot is your AI-powered assistant for code generation, analysis, and MGZon-specific queries. Built with Gradio and FastAPI, it supports multiple frameworks and languages. Ready to explore?
25
- </p>
26
- <a href="/gradio" id="chatbot-link" class="btn">Launch Chatbot</a>
27
- <div class="features">
28
- <h2>Features</h2>
29
- <div class="feature-grid">
30
- <div class="feature-card">
31
- <i class="bx bx-code-alt"></i>
32
- <h3>Code Generation</h3>
33
- <p>Generate code for React, Django, Flask, and more.</p>
34
- </div>
35
- <div class="feature-card">
36
- <i class="bx bx-search"></i>
37
- <h3>Web Search</h3>
38
- <p>Integrated web search for MGZon-related queries.</p>
39
- </div>
40
- <div class="feature-card">
41
- <i class="bx bx-analyse"></i>
42
- <h3>Analysis & Review</h3>
43
- <p>Detailed code and data analysis with insights.</p>
44
- </div>
45
  </div>
46
- </div>
47
- <div class="news">
48
- <h2>Latest MGZon News</h2>
49
- <div class="news-grid">
50
- <div class="news-card">
51
- <h3>New API Features</h3>
52
- <p>Explore our updated API with OAuth 2.0 support.</p>
53
- <a href="https://hager-zon.vercel.app/blog" target="_blank">Read More</a>
 
 
 
 
 
 
 
 
 
 
54
  </div>
55
- <div class="news-card">
56
- <h3>Community Meetup</h3>
57
- <p>Join our next virtual meetup on e-commerce trends.</p>
58
- <a href="https://hager-zon.vercel.app/community" target="_blank">Join Now</a>
 
 
 
 
 
 
 
 
 
 
59
  </div>
60
  </div>
61
  </div>
62
  </div>
63
- <footer>
64
- <div class="footer-container">
65
- <img src="https://raw.githubusercontent.com/Mark-Lasfar/MGZon/main/public/icons/mg.svg" alt="MGZon Logo" class="footer-logo">
66
- <p>Developed by <a href="https://mark-elasfar.web.app/" target="_blank">Mark Al-Asfar</a> | Powered by <a href="https://hager-zon.vercel.app/" target="_blank">MGZon AI</a></p>
67
- <div class="footer-grid">
68
- <div class="footer-card">
69
- <i class="bx bx-mail-send"></i>
70
- <h3>Email Us</h3>
71
- <p>Contact: <a href="mailto:support@mgzon.com">support@mgzon.com</a></p>
72
  </div>
73
- <div class="footer-card">
74
- <i class="bx bx-phone"></i>
75
- <h3>Phone Support</h3>
76
  <p>Call: +1-800-123-4567</p>
77
  </div>
78
- <div class="footer-card">
79
- <i class="bx bx-group"></i>
80
- <h3>Community</h3>
81
- <p>Join: <a href="https://hager-zon.vercel.app/community">mgzon.com/community</a></p>
82
  </div>
83
- <div class="footer-card">
84
- <i class="bx bx-code-alt"></i>
85
- <h3>API Docs</h3>
86
- <p>Explore: <a href="/docs">mgzon.com/docs</a></p>
87
  </div>
88
- <div class="footer-card">
89
- <i class="bx bx-help-circle"></i>
90
- <h3>FAQ</h3>
91
- <p>Read: <a href="https://hager-zon.vercel.app/faq">mgzon.com/faq</a></p>
92
  </div>
93
- <div class="footer-card">
94
- <i class="bx bx-book"></i>
95
- <h3>Documentation</h3>
96
- <p>Learn: <a href="/docs">mgzon.com/docs</a></p>
97
  </div>
98
  </div>
99
- <div class="footer-social">
100
- <a href="https://github.com/Mark-Lasfar/MGZon"><i class="bx bxl-github"></i></a>
101
- <a href="https://x.com/MGZon"><i class="bx bxl-twitter"></i></a>
102
- <a href="https://www.facebook.com/people/Mark-Al-Asfar/pfbid02GMisUQ8AqWkNZjoKtWFHH1tbdHuVscN1cjcFnZWy9HkRaAsmanBfT6mhySAyqpg4l/"><i class="bx bxl-facebook"></i></a>
103
  </div>
104
- <p>© 2025 Mark Al-Asfar & MGZon AI. All rights reserved.</p>
105
  </div>
106
  </footer>
107
  <script src="/static/js/scripts.js"></script>
 
108
  </body>
109
  </html>
 
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>MGZon Chatbot - Powered by AI</title>
7
+ <link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
8
+ <link href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism.min.css" rel="stylesheet">
9
  <link href="https://cdn.jsdelivr.net/npm/boxicons@2.1.4/css/boxicons.min.css" rel="stylesheet">
10
+ <style>
11
+ @keyframes slideIn {
12
+ from { transform: translateX(-100%); }
13
+ to { transform: translateX(0); }
14
+ }
15
+ .sidebar.active { transform: translateX(0); }
16
+ @media (max-width: 768px) {
17
+ .sidebar { transform: translateX(-100%); }
18
+ .sidebar.active { transform: translateX(0); animation: slideIn 0.3s ease; }
19
+ }
20
+ .loading::after {
21
+ content: '';
22
+ display: inline-block;
23
+ width: 16px;
24
+ height: 16px;
25
+ border: 2px solid #fff;
26
+ border-top-color: transparent;
27
+ border-radius: 50%;
28
+ animation: spin 1s linear infinite;
29
+ margin-left: 8px;
30
+ }
31
+ @keyframes spin {
32
+ to { transform: rotate(360deg); }
33
+ }
34
+ </style>
35
  </head>
36
+ <body class="bg-gray-900 text-white min-h-screen flex flex-col">
37
+ <button class="md:hidden fixed top-4 left-4 z-50 text-white text-2xl sidebar-toggle">☰</button>
38
+ <div class="sidebar fixed top-0 left-0 h-full w-64 bg-gradient-to-b from-blue-800 to-orange-500 text-white p-6 flex flex-col md:translate-x-0 transition-transform duration-300">
39
+ <img src="https://raw.githubusercontent.com/Mark-Lasfar/MGZon/main/public/icons/mg.svg" alt="MGZon Logo" class="w-20 h-20 mb-6 animate-pulse">
40
+ <nav class="flex flex-col gap-4">
41
+ <a href="/" class="px-4 py-2 rounded-lg hover:bg-orange-600 transition active:bg-orange-600">Home</a>
42
+ <a href="/docs" class="px-4 py-2 rounded-lg hover:bg-orange-600 transition">API Documentation</a>
43
+ <a href="https://hager-zon.vercel.app/about" class="px-4 py-2 rounded-lg hover:bg-orange-600 transition">About MGZon</a>
44
+ <a href="https://hager-zon.vercel.app/community" class="px-4 py-2 rounded-lg hover:bg-orange-600 transition">Community</a>
45
+ <a href="https://mark-elasfar.web.app/" target="_blank" class="px-4 py-2 rounded-lg hover:bg-orange-600 transition">Mark Al-Asfar</a>
46
  </nav>
47
  </div>
48
+ <div class="flex-1 md:ml-64 p-6">
49
+ <div class="container max-w-6xl mx-auto">
50
+ <div class="text-center py-12">
51
+ <img src="https://raw.githubusercontent.com/Mark-Lasfar/MGZon/main/public/icons/mg.svg" alt="MGZon Logo" class="w-32 h-32 mx-auto mb-6 animate-bounce">
52
+ <h1 class="text-5xl font-bold mb-4 animate-fade-in">Welcome to MGZon Chatbot 🚀</h1>
53
+ <p class="text-lg mb-8">
54
+ MGZon Chatbot is your AI-powered assistant for code generation, analysis, and MGZon-specific queries. Built with Gradio and FastAPI, it supports multiple frameworks and languages. Ready to explore?
55
+ </p>
56
+ <a href="/gradio" id="chatbot-link" class="inline-block bg-gradient-to-r from-orange-500 to-red-500 text-white px-8 py-4 rounded-full text-lg font-semibold hover:scale-105 transition transform">Launch Chatbot <span class="loading hidden"></span></a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  </div>
58
+ <div class="features my-12">
59
+ <h2 class="text-3xl font-bold text-center mb-8">Features</h2>
60
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-6">
61
+ <div class="bg-gray-800 p-6 rounded-lg shadow-lg hover:scale-105 transition transform">
62
+ <i class="bx bx-code-alt text-4xl text-orange-500 mb-4"></i>
63
+ <h3 class="text-xl font-semibold mb-2">Code Generation</h3>
64
+ <p>Generate code for React, Django, Flask, and more.</p>
65
+ </div>
66
+ <div class="bg-gray-800 p-6 rounded-lg shadow-lg hover:scale-105 transition transform">
67
+ <i class="bx bx-search text-4xl text-orange-500 mb-4"></i>
68
+ <h3 class="text-xl font-semibold mb-2">Web Search</h3>
69
+ <p>Integrated web search for MGZon-related queries.</p>
70
+ </div>
71
+ <div class="bg-gray-800 p-6 rounded-lg shadow-lg hover:scale-105 transition transform">
72
+ <i class="bx bx-analyse text-4xl text-orange-500 mb-4"></i>
73
+ <h3 class="text-xl font-semibold mb-2">Analysis & Review</h3>
74
+ <p>Detailed code and data analysis with insights.</p>
75
+ </div>
76
  </div>
77
+ </div>
78
+ <div class="news my-12">
79
+ <h2 class="text-3xl font-bold text-center mb-8">Latest MGZon News</h2>
80
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
81
+ <div class="bg-gray-800 p-6 rounded-lg shadow-lg hover:scale-105 transition transform">
82
+ <h3 class="text-xl font-semibold mb-2">New API Features</h3>
83
+ <p>Explore our updated API with OAuth 2.0 support.</p>
84
+ <a href="https://hager-zon.vercel.app/blog" target="_blank" class="text-orange-500 hover:underline">Read More</a>
85
+ </div>
86
+ <div class="bg-gray-800 p-6 rounded-lg shadow-lg hover:scale-105 transition transform">
87
+ <h3 class="text-xl font-semibold mb-2">Community Meetup</h3>
88
+ <p>Join our next virtual meetup on e-commerce trends.</p>
89
+ <a href="https://hager-zon.vercel.app/community" target="_blank" class="text-orange-500 hover:underline">Join Now</a>
90
+ </div>
91
  </div>
92
  </div>
93
  </div>
94
  </div>
95
+ <footer class="bg-gradient-to-r from-blue-900 to-gray-900 py-12 mt-auto">
96
+ <div class="container max-w-6xl mx-auto text-center">
97
+ <img src="https://raw.githubusercontent.com/Mark-Lasfar/MGZon/main/public/icons/mg.svg" alt="MGZon Logo" class="w-24 h-24 mx-auto mb-6 animate-pulse">
98
+ <p class="mb-4">Developed by <a href="https://mark-elasfar.web.app/" target="_blank" class="text-orange-500 hover:underline">Mark Al-Asfar</a> | Powered by <a href="https://hager-zon.vercel.app/" target="_blank" class="text-orange-500 hover:underline">MGZon AI</a></p>
99
+ <div class="grid grid-cols-2 md:grid-cols-3 gap-6">
100
+ <div class="bg-gray-800 p-6 rounded-lg shadow-lg">
101
+ <i class="bx bx-mail-send text-3xl text-orange-500 mb-4"></i>
102
+ <h3 class="text-lg font-semibold mb-2">Email Us</h3>
103
+ <p>Contact: <a href="mailto:support@mgzon.com" class="text-orange-500 hover:underline">support@mgzon.com</a></p>
104
  </div>
105
+ <div class="bg-gray-800 p-6 rounded-lg shadow-lg">
106
+ <i class="bx bx-phone text-3xl text-orange-500 mb-4"></i>
107
+ <h3 class="text-lg font-semibold mb-2">Phone Support</h3>
108
  <p>Call: +1-800-123-4567</p>
109
  </div>
110
+ <div class="bg-gray-800 p-6 rounded-lg shadow-lg">
111
+ <i class="bx bx-group text-3xl text-orange-500 mb-4"></i>
112
+ <h3 class="text-lg font-semibold mb-2">Community</h3>
113
+ <p>Join: <a href="https://hager-zon.vercel.app/community" class="text-orange-500 hover:underline">mgzon.com/community</a></p>
114
  </div>
115
+ <div class="bg-gray-800 p-6 rounded-lg shadow-lg">
116
+ <i class="bx bx-code-alt text-3xl text-orange-500 mb-4"></i>
117
+ <h3 class="text-lg font-semibold mb-2">API Docs</h3>
118
+ <p>Explore: <a href="/docs" class="text-orange-500 hover:underline">mgzon.com/docs</a></p>
119
  </div>
120
+ <div class="bg-gray-800 p-6 rounded-lg shadow-lg">
121
+ <i class="bx bx-help-circle text-3xl text-orange-500 mb-4"></i>
122
+ <h3 class="text-lg font-semibold mb-2">FAQ</h3>
123
+ <p>Read: <a href="https://hager-zon.vercel.app/faq" class="text-orange-500 hover:underline">mgzon.com/faq</a></p>
124
  </div>
125
+ <div class="bg-gray-800 p-6 rounded-lg shadow-lg">
126
+ <i class="bx bx-book text-3xl text-orange-500 mb-4"></i>
127
+ <h3 class="text-lg font-semibold mb-2">Documentation</h3>
128
+ <p>Learn: <a href="/docs" class="text-orange-500 hover:underline">mgzon.com/docs</a></p>
129
  </div>
130
  </div>
131
+ <div class="flex justify-center gap-6 mt-6">
132
+ <a href="https://github.com/Mark-Lasfar/MGZon" class="text-2xl text-white hover:text-orange-500 transition"><i class="bx bxl-github"></i></a>
133
+ <a href="https://x.com/MGZon" class="text-2xl text-white hover:text-orange-500 transition"><i class="bx bxl-twitter"></i></a>
134
+ <a href="https://www.facebook.com/people/Mark-Al-Asfar/pfbid02GMisUQ8AqWkNZjoKtWFHH1tbdHuVscN1cjcFnZWy9HkRaAsmanBfT6mhySAyqpg4l/" class="text-2xl text-white hover:text-orange-500 transition"><i class="bx bxl-facebook"></i></a>
135
  </div>
136
+ <p class="mt-6">© 2025 Mark Al-Asfar & MGZon AI. All rights reserved.</p>
137
  </div>
138
  </footer>
139
  <script src="/static/js/scripts.js"></script>
140
+ <script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/prism.min.js"></script>
141
  </body>
142
  </html>
utils/generation.py CHANGED
@@ -6,13 +6,18 @@ from openai import OpenAI
6
  from pydoc import html
7
  from tenacity import retry, stop_after_attempt, wait_exponential
8
  import logging
 
 
9
 
10
  logger = logging.getLogger(__name__)
11
 
 
 
 
12
  # تعريف LATEX_DELIMS
13
  LATEX_DELIMS = [
14
- {"left": "$$", "right": "$$", "display": True},
15
- {"left": "$", "right": "$", "display": False},
16
  {"left": "\\[", "right": "\\]", "display": True},
17
  {"left": "\\(", "right": "\\)", "display": False},
18
  ]
@@ -38,7 +43,7 @@ def select_model(query: str) -> tuple[str, str]:
38
  logger.info(f"Selected {MODEL_NAME} with endpoint {API_ENDPOINT} for general query: {query}")
39
  return MODEL_NAME, API_ENDPOINT
40
 
41
- @retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=4, max=10))
42
  def request_generation(
43
  api_key: str,
44
  api_base: str,
@@ -54,11 +59,28 @@ def request_generation(
54
  deep_search: bool = False,
55
  ) -> Generator[str, None, None]:
56
  from utils.web_search import web_search # تأخير الاستيراد
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  client = OpenAI(api_key=api_key, base_url=api_base, timeout=60.0)
58
  task_type = "general"
59
- if "code" in message.lower() or "programming" in message.lower() or any(ext in message.lower() for ext in ["python", "javascript", "react", "django", "flask"]):
60
  task_type = "code"
61
- enhanced_system_prompt = f"{system_prompt}\nYou are an expert programmer. Provide accurate, well-commented code with examples and explanations. Support frameworks like React, Django, Flask, and others as needed."
62
  elif any(keyword in message.lower() for keyword in ["analyze", "analysis", "تحليل"]):
63
  task_type = "analysis"
64
  enhanced_system_prompt = f"{system_prompt}\nProvide detailed analysis with step-by-step reasoning, examples, and data-driven insights."
@@ -80,14 +102,19 @@ def request_generation(
80
  input_messages.append(clean_msg)
81
 
82
  if deep_search:
83
- search_result = web_search(message)
84
- input_messages.append({"role": "user", "content": f"User query: {message}\nWeb search context: {search_result}"})
 
 
 
 
85
  else:
86
  input_messages.append({"role": "user", "content": message})
87
 
88
  tools = tools if tools and "gpt-oss" in model_name else []
89
  tool_choice = tool_choice if tool_choice in ["auto", "none", "any", "required"] and "gpt-oss" in model_name else "none"
90
 
 
91
  try:
92
  stream = client.chat.completions.create(
93
  model=model_name,
@@ -111,11 +138,13 @@ def request_generation(
111
  content = chunk.choices[0].delta.content
112
  if content == "<|channel|>analysis<|message|>":
113
  if not reasoning_started:
 
114
  yield "analysis"
115
  reasoning_started = True
116
  continue
117
  if content == "<|channel|>final<|message|>":
118
  if reasoning_started and not reasoning_closed:
 
119
  yield "assistantfinal"
120
  reasoning_closed = True
121
  continue
@@ -123,7 +152,8 @@ def request_generation(
123
  saw_visible_output = True
124
  buffer += content
125
 
126
- if "\n" in buffer or len(buffer) > 2000:
 
127
  yield buffer
128
  buffer = ""
129
  continue
@@ -140,10 +170,12 @@ def request_generation(
140
 
141
  if chunk.choices[0].finish_reason in ("stop", "tool_calls", "error"):
142
  if buffer:
 
143
  yield buffer
144
  buffer = ""
145
 
146
  if reasoning_started and not reasoning_closed:
 
147
  yield "assistantfinal"
148
  reasoning_closed = True
149
 
@@ -155,15 +187,20 @@ def request_generation(
155
  except Exception:
156
  args_text = str(last_tool_args)
157
  msg += f"\n\n• Tool requested: **{last_tool_name}**\n• Arguments: `{args_text}`"
 
158
  yield msg
159
 
160
  if chunk.choices[0].finish_reason == "error":
 
161
  yield f"Error: Unknown error"
162
  break
163
 
164
  if buffer:
 
165
  yield buffer
166
 
 
 
167
  except Exception as e:
168
  logger.exception(f"[Gateway] Streaming failed for model {model_name}: {e}")
169
  if model_name == MODEL_NAME:
@@ -186,11 +223,13 @@ def request_generation(
186
  content = chunk.choices[0].delta.content
187
  if content == "<|channel|>analysis<|message|>":
188
  if not reasoning_started:
 
189
  yield "analysis"
190
  reasoning_started = True
191
  continue
192
  if content == "<|channel|>final<|message|>":
193
  if reasoning_started and not reasoning_closed:
 
194
  yield "assistantfinal"
195
  reasoning_closed = True
196
  continue
@@ -198,31 +237,40 @@ def request_generation(
198
  saw_visible_output = True
199
  buffer += content
200
 
201
- if "\n" in buffer or len(buffer) > 2000:
 
202
  yield buffer
203
  buffer = ""
204
  continue
205
 
206
  if chunk.choices[0].finish_reason in ("stop", "error"):
207
  if buffer:
 
208
  yield buffer
209
  buffer = ""
210
 
211
  if reasoning_started and not reasoning_closed:
 
212
  yield "assistantfinal"
213
  reasoning_closed = True
214
 
215
  if not saw_visible_output:
 
216
  yield "No visible output produced."
217
  if chunk.choices[0].finish_reason == "error":
 
218
  yield f"Error: Unknown error with fallback model {fallback_model}"
219
  break
220
 
221
  if buffer:
 
222
  yield buffer
223
 
 
 
224
  except Exception as e2:
225
  logger.exception(f"[Gateway] Streaming failed for fallback model {fallback_model}: {e2}")
 
226
  yield f"Error: Failed to load both models ({model_name} and {fallback_model}): {e2}"
227
  try:
228
  client = OpenAI(api_key=api_key, base_url=FALLBACK_API_ENDPOINT, timeout=60.0)
@@ -240,25 +288,33 @@ def request_generation(
240
  content = chunk.choices[0].delta.content
241
  saw_visible_output = True
242
  buffer += content
243
- if "\n" in buffer or len(buffer) > 2000:
 
244
  yield buffer
245
  buffer = ""
246
  continue
247
  if chunk.choices[0].finish_reason in ("stop", "error"):
248
  if buffer:
 
249
  yield buffer
250
  buffer = ""
251
  if not saw_visible_output:
 
252
  yield "No visible output produced."
253
  if chunk.choices[0].finish_reason == "error":
 
254
  yield f"Error: Unknown error with tertiary model {TERTIARY_MODEL_NAME}"
255
  break
256
  if buffer:
 
257
  yield buffer
 
258
  except Exception as e3:
259
  logger.exception(f"[Gateway] Streaming failed for tertiary model {TERTIARY_MODEL_NAME}: {e3}")
 
260
  yield f"Error: Failed to load all models: {e3}"
261
  else:
 
262
  yield f"Error: Failed to load model {model_name}: {e}"
263
 
264
  def format_final(analysis_text: str, visible_text: str) -> str:
@@ -318,6 +374,21 @@ def generate(message, history, system_prompt, temperature, reasoning_effort, ena
318
  "required": ["task"],
319
  },
320
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
321
  }
322
  ] if "gpt-oss" in model_name else []
323
  tool_choice = "auto" if "gpt-oss" in model_name else "none"
 
6
  from pydoc import html
7
  from tenacity import retry, stop_after_attempt, wait_exponential
8
  import logging
9
+ from cachetools import TTLCache
10
+ import hashlib
11
 
12
  logger = logging.getLogger(__name__)
13
 
14
+ # إعداد Cache
15
+ cache = TTLCache(maxsize=100, ttl=600) # Cache بحجم 100 ومدة 10 دقايق
16
+
17
  # تعريف LATEX_DELIMS
18
  LATEX_DELIMS = [
19
+ {"left": "$$", "right": "$$", "display": True},
20
+ {"left": "$", "right": "$", "display": False},
21
  {"left": "\\[", "right": "\\]", "display": True},
22
  {"left": "\\(", "right": "\\)", "display": False},
23
  ]
 
43
  logger.info(f"Selected {MODEL_NAME} with endpoint {API_ENDPOINT} for general query: {query}")
44
  return MODEL_NAME, API_ENDPOINT
45
 
46
+ @retry(stop=stop_after_attempt(5), wait=wait_exponential(multiplier=2, min=4, max=30))
47
  def request_generation(
48
  api_key: str,
49
  api_base: str,
 
59
  deep_search: bool = False,
60
  ) -> Generator[str, None, None]:
61
  from utils.web_search import web_search # تأخير الاستيراد
62
+
63
+ # إنشاء مفتاح للـ cache بناءً على المدخلات
64
+ cache_key = hashlib.md5(json.dumps({
65
+ "message": message,
66
+ "system_prompt": system_prompt,
67
+ "model_name": model_name,
68
+ "chat_history": chat_history,
69
+ "temperature": temperature,
70
+ "max_new_tokens": max_new_tokens
71
+ }, sort_keys=True).encode()).hexdigest()
72
+
73
+ if cache_key in cache:
74
+ logger.info(f"Cache hit for query: {message[:50]}...")
75
+ for chunk in cache[cache_key]:
76
+ yield chunk
77
+ return
78
+
79
  client = OpenAI(api_key=api_key, base_url=api_base, timeout=60.0)
80
  task_type = "general"
81
+ if any(keyword in message.lower() for keyword in ["code", "programming", "python", "javascript", "react", "django", "flask"]):
82
  task_type = "code"
83
+ enhanced_system_prompt = f"{system_prompt}\nYou are an expert programmer. Provide accurate, well-commented code with examples and explanations. Support frameworks like React, Django, Flask, and others as needed. Format code with triple backticks (```) and specify the language."
84
  elif any(keyword in message.lower() for keyword in ["analyze", "analysis", "تحليل"]):
85
  task_type = "analysis"
86
  enhanced_system_prompt = f"{system_prompt}\nProvide detailed analysis with step-by-step reasoning, examples, and data-driven insights."
 
102
  input_messages.append(clean_msg)
103
 
104
  if deep_search:
105
+ try:
106
+ search_result = web_search(message)
107
+ input_messages.append({"role": "user", "content": f"User query: {message}\nWeb search context: {search_result}"})
108
+ except Exception as e:
109
+ logger.error(f"Web search failed: {e}")
110
+ input_messages.append({"role": "user", "content": message})
111
  else:
112
  input_messages.append({"role": "user", "content": message})
113
 
114
  tools = tools if tools and "gpt-oss" in model_name else []
115
  tool_choice = tool_choice if tool_choice in ["auto", "none", "any", "required"] and "gpt-oss" in model_name else "none"
116
 
117
+ cached_chunks = []
118
  try:
119
  stream = client.chat.completions.create(
120
  model=model_name,
 
138
  content = chunk.choices[0].delta.content
139
  if content == "<|channel|>analysis<|message|>":
140
  if not reasoning_started:
141
+ cached_chunks.append("analysis")
142
  yield "analysis"
143
  reasoning_started = True
144
  continue
145
  if content == "<|channel|>final<|message|>":
146
  if reasoning_started and not reasoning_closed:
147
+ cached_chunks.append("assistantfinal")
148
  yield "assistantfinal"
149
  reasoning_closed = True
150
  continue
 
152
  saw_visible_output = True
153
  buffer += content
154
 
155
+ if "\n" in buffer or len(buffer) > 1000: # تقليل حجم الـ buffer
156
+ cached_chunks.append(buffer)
157
  yield buffer
158
  buffer = ""
159
  continue
 
170
 
171
  if chunk.choices[0].finish_reason in ("stop", "tool_calls", "error"):
172
  if buffer:
173
+ cached_chunks.append(buffer)
174
  yield buffer
175
  buffer = ""
176
 
177
  if reasoning_started and not reasoning_closed:
178
+ cached_chunks.append("assistantfinal")
179
  yield "assistantfinal"
180
  reasoning_closed = True
181
 
 
187
  except Exception:
188
  args_text = str(last_tool_args)
189
  msg += f"\n\n• Tool requested: **{last_tool_name}**\n• Arguments: `{args_text}`"
190
+ cached_chunks.append(msg)
191
  yield msg
192
 
193
  if chunk.choices[0].finish_reason == "error":
194
+ cached_chunks.append(f"Error: Unknown error")
195
  yield f"Error: Unknown error"
196
  break
197
 
198
  if buffer:
199
+ cached_chunks.append(buffer)
200
  yield buffer
201
 
202
+ cache[cache_key] = cached_chunks # حفظ في الـ cache
203
+
204
  except Exception as e:
205
  logger.exception(f"[Gateway] Streaming failed for model {model_name}: {e}")
206
  if model_name == MODEL_NAME:
 
223
  content = chunk.choices[0].delta.content
224
  if content == "<|channel|>analysis<|message|>":
225
  if not reasoning_started:
226
+ cached_chunks.append("analysis")
227
  yield "analysis"
228
  reasoning_started = True
229
  continue
230
  if content == "<|channel|>final<|message|>":
231
  if reasoning_started and not reasoning_closed:
232
+ cached_chunks.append("assistantfinal")
233
  yield "assistantfinal"
234
  reasoning_closed = True
235
  continue
 
237
  saw_visible_output = True
238
  buffer += content
239
 
240
+ if "\n" in buffer or len(buffer) > 1000:
241
+ cached_chunks.append(buffer)
242
  yield buffer
243
  buffer = ""
244
  continue
245
 
246
  if chunk.choices[0].finish_reason in ("stop", "error"):
247
  if buffer:
248
+ cached_chunks.append(buffer)
249
  yield buffer
250
  buffer = ""
251
 
252
  if reasoning_started and not reasoning_closed:
253
+ cached_chunks.append("assistantfinal")
254
  yield "assistantfinal"
255
  reasoning_closed = True
256
 
257
  if not saw_visible_output:
258
+ cached_chunks.append("No visible output produced.")
259
  yield "No visible output produced."
260
  if chunk.choices[0].finish_reason == "error":
261
+ cached_chunks.append(f"Error: Unknown error with fallback model {fallback_model}")
262
  yield f"Error: Unknown error with fallback model {fallback_model}"
263
  break
264
 
265
  if buffer:
266
+ cached_chunks.append(buffer)
267
  yield buffer
268
 
269
+ cache[cache_key] = cached_chunks
270
+
271
  except Exception as e2:
272
  logger.exception(f"[Gateway] Streaming failed for fallback model {fallback_model}: {e2}")
273
+ cached_chunks.append(f"Error: Failed to load both models ({model_name} and {fallback_model}): {e2}")
274
  yield f"Error: Failed to load both models ({model_name} and {fallback_model}): {e2}"
275
  try:
276
  client = OpenAI(api_key=api_key, base_url=FALLBACK_API_ENDPOINT, timeout=60.0)
 
288
  content = chunk.choices[0].delta.content
289
  saw_visible_output = True
290
  buffer += content
291
+ if "\n" in buffer or len(buffer) > 1000:
292
+ cached_chunks.append(buffer)
293
  yield buffer
294
  buffer = ""
295
  continue
296
  if chunk.choices[0].finish_reason in ("stop", "error"):
297
  if buffer:
298
+ cached_chunks.append(buffer)
299
  yield buffer
300
  buffer = ""
301
  if not saw_visible_output:
302
+ cached_chunks.append("No visible output produced.")
303
  yield "No visible output produced."
304
  if chunk.choices[0].finish_reason == "error":
305
+ cached_chunks.append(f"Error: Unknown error with tertiary model {TERTIARY_MODEL_NAME}")
306
  yield f"Error: Unknown error with tertiary model {TERTIARY_MODEL_NAME}"
307
  break
308
  if buffer:
309
+ cached_chunks.append(buffer)
310
  yield buffer
311
+ cache[cache_key] = cached_chunks
312
  except Exception as e3:
313
  logger.exception(f"[Gateway] Streaming failed for tertiary model {TERTIARY_MODEL_NAME}: {e3}")
314
+ cached_chunks.append(f"Error: Failed to load all models: {e3}")
315
  yield f"Error: Failed to load all models: {e3}"
316
  else:
317
+ cached_chunks.append(f"Error: Failed to load model {model_name}: {e}")
318
  yield f"Error: Failed to load model {model_name}: {e}"
319
 
320
  def format_final(analysis_text: str, visible_text: str) -> str:
 
374
  "required": ["task"],
375
  },
376
  },
377
+ },
378
+ {
379
+ "type": "function",
380
+ "function": {
381
+ "name": "code_formatter",
382
+ "description": "Format code for readability and consistency",
383
+ "parameters": {
384
+ "type": "object",
385
+ "properties": {
386
+ "code": {"type": "string", "description": "Code to format"},
387
+ "language": {"type": "string", "description": "Programming language (e.g., Python, JavaScript)"},
388
+ },
389
+ "required": ["code", "language"],
390
+ },
391
+ },
392
  }
393
  ] if "gpt-oss" in model_name else []
394
  tool_choice = "auto" if "gpt-oss" in model_name else "none"