Yermek68 commited on
Commit
1530a12
·
verified ·
1 Parent(s): c487e9b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +141 -45
app.py CHANGED
@@ -1,11 +1,13 @@
1
  import os
2
  import time
 
 
3
  import gradio as gr
4
  import pandas as pd
5
  import matplotlib.pyplot as plt
6
  import base64
7
  from io import BytesIO
8
- import requests
9
 
10
  from core.dashboard import ErohaDashboard
11
  from core.intelligence import update_memory, summarize_context
@@ -13,66 +15,154 @@ from core.selfcheck import evaluate_answer, improve_answer
13
  from core.learning import analyze_user_input, adapt_answer
14
  from core.model_selector import choose_model
15
 
 
16
  # ==============================
17
- # 🔐 ENV
18
  # ==============================
19
  HF_TOKEN = os.getenv("HF_TOKEN", "")
20
  LOG_FILE = "logs/history.csv"
21
  os.makedirs("logs", exist_ok=True)
22
  dashboard = ErohaDashboard()
23
 
 
24
  # ==============================
25
- # 🔁 Автоматический Router с Failover
26
  # ==============================
27
- def query_huggingface_router(prompt, model_id):
28
- """
29
- Универсальный запрос к Router API с fallback на прямую модель.
30
- """
31
- headers = {"Authorization": f"Bearer {HF_TOKEN}"}
32
- payload = {
33
- "inputs": prompt,
34
- "parameters": {"max_new_tokens": 600, "temperature": 0.7},
35
- }
36
-
37
- try:
38
- # 1️⃣ Основной Router API
39
- response = requests.post(
40
- "https://router.huggingface.co/models/" + model_id,
41
- headers=headers,
42
- json=payload,
43
- timeout=30,
44
- )
45
- if response.status_code == 200:
46
- return response.json()[0]["generated_text"]
47
- elif response.status_code == 410:
48
- raise RuntimeError("Old endpoint rejected (410)")
49
- else:
50
- raise RuntimeError(f"Router error: {response.status_code}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
- except Exception as e:
53
- print("⚠️ Router недоступен, выполняется fallback:", str(e))
54
- # 2️⃣ Fallback: прямое обращение к конкретной модели
55
- fallback_url = f"https://huggingface.co/api/models/{model_id}"
56
  try:
57
- response = requests.post(fallback_url, headers=headers, json=payload, timeout=30)
 
 
 
 
 
58
  if response.status_code == 200:
59
- return response.json()[0]["generated_text"]
 
 
 
 
 
 
 
 
 
 
60
  else:
61
- raise RuntimeError(f"Fallback error: {response.status_code}")
62
- except Exception as e2:
63
- return f"❌ Ошибка при обращении к API: {str(e2)}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
 
65
  # ==============================
66
- # 🧠 Основная логика
67
  # ==============================
 
 
 
68
  def generate_response(user_input):
69
  try:
70
  start = time.time()
71
  prefs = analyze_user_input(user_input)
72
  model_id = choose_model(user_input)
73
 
74
- result = query_huggingface_router(user_input, model_id)
75
-
76
  check = evaluate_answer(result)
77
  improved = improve_answer(result)
78
  personalized = adapt_answer(improved)
@@ -105,8 +195,9 @@ def generate_response(user_input):
105
  except Exception as e:
106
  return f"❌ Ошибка выполнения: {str(e)}"
107
 
 
108
  # ==============================
109
- # 📈 Визуализация аналитики
110
  # ==============================
111
  def generate_chart():
112
  if not os.path.exists(LOG_FILE):
@@ -130,20 +221,22 @@ def generate_chart():
130
  plt.close()
131
  return f"<img src='data:image/png;base64,{img_base64}'/>"
132
 
 
133
  def show_dashboard():
134
  metrics_text, df = dashboard.dashboard_ui()
135
  chart_html = generate_chart()
136
  return metrics_text, df, chart_html
137
 
 
138
  # ==============================
139
- # 🎨 Интерфейс Gradio
140
  # ==============================
141
- with gr.Blocks(title="Eroha AgentAPI v5.6AutoRouter Failover Core", theme="soft") as app:
142
- gr.Markdown("# 🤖 Eroha AgentAPI v5.6Guru Edition (AutoRouter + Failover Core)")
143
- gr.Markdown("**Автоматический Router + fallback + визуальная аналитика** ⚙️")
144
 
145
  with gr.Tab("💬 Agent Chat"):
146
- user_input = gr.Textbox(label="Введите запрос", placeholder="Например: придумай философскую сказку об ИИ.")
147
  output_box = gr.Textbox(label="Ответ", lines=15)
148
  submit_btn = gr.Button("🚀 Отправить")
149
  submit_btn.click(fn=generate_response, inputs=user_input, outputs=output_box)
@@ -155,4 +248,7 @@ with gr.Blocks(title="Eroha AgentAPI v5.6 — AutoRouter Failover Core", theme="
155
  refresh = gr.Button("🔄 Обновить дашборд")
156
  refresh.click(show_dashboard, outputs=[metrics, log_table, chart_box])
157
 
 
 
 
158
  app.launch(server_name="0.0.0.0", server_port=7860)
 
1
  import os
2
  import time
3
+ import threading
4
+ import requests
5
  import gradio as gr
6
  import pandas as pd
7
  import matplotlib.pyplot as plt
8
  import base64
9
  from io import BytesIO
10
+ from datetime import datetime
11
 
12
  from core.dashboard import ErohaDashboard
13
  from core.intelligence import update_memory, summarize_context
 
15
  from core.learning import analyze_user_input, adapt_answer
16
  from core.model_selector import choose_model
17
 
18
+
19
  # ==============================
20
+ # 🔐 ENVIRONMENT CONFIG
21
  # ==============================
22
  HF_TOKEN = os.getenv("HF_TOKEN", "")
23
  LOG_FILE = "logs/history.csv"
24
  os.makedirs("logs", exist_ok=True)
25
  dashboard = ErohaDashboard()
26
 
27
+
28
  # ==============================
29
+ # 🧠 Router Manager
30
  # ==============================
31
+ class RouterManager:
32
+ def __init__(self, token: str):
33
+ self.token = token
34
+ self.router_url = "https://router.huggingface.co"
35
+ self.headers = {"Authorization": f"Bearer {self.token}"}
36
+ self.is_router_healthy = True
37
+ self.last_check = None
38
+ self.reconnect_attempts = 0
39
+ self.last_token_validation = 0
40
+
41
+ def validate_token(self):
42
+ """Проверяет, действителен ли токен"""
43
+ try:
44
+ r = requests.get(self.router_url + "/status", headers=self.headers, timeout=10)
45
+ if r.status_code == 200:
46
+ return True
47
+ elif r.status_code == 401:
48
+ print("🔒 Ошибка: недействительный токен Hugging Face!")
49
+ self.is_router_healthy = False
50
+ return False
51
+ return False
52
+ except Exception:
53
+ return False
54
+
55
+ def check_router_health(self):
56
+ """Проверяет доступность Router API"""
57
+ try:
58
+ start = time.time()
59
+ r = requests.post(self.router_url, headers=self.headers, json={"inputs": "ping"})
60
+ latency = round(time.time() - start, 2)
61
+ if r.status_code == 200:
62
+ self.is_router_healthy = True
63
+ self.last_check = datetime.now()
64
+ self.reconnect_attempts = 0
65
+ print(f"✅ Router API активен ({latency}s)")
66
+ else:
67
+ self.is_router_healthy = False
68
+ print(f"⚠️ Router API ответил {r.status_code}")
69
+ except Exception as e:
70
+ self.is_router_healthy = False
71
+ print("❌ Router недоступен:", str(e))
72
+
73
+ def auto_reconnect(self):
74
+ """Автоматическое восстановление при потере связи"""
75
+ self.reconnect_attempts += 1
76
+ delay = min(30, 2 ** self.reconnect_attempts)
77
+ print(f"🔁 Попытка переподключения через {delay}s...")
78
+ time.sleep(delay)
79
+ self.check_router_health()
80
+
81
+ def request(self, model_id: str, prompt: str):
82
+ """Отправляет запрос с failover и auto-heal"""
83
+ payload = {
84
+ "model": model_id,
85
+ "inputs": prompt,
86
+ "parameters": {"max_new_tokens": 600, "temperature": 0.7},
87
+ }
88
 
 
 
 
 
89
  try:
90
+ response = requests.post(
91
+ self.router_url,
92
+ headers=self.headers,
93
+ json=payload,
94
+ timeout=60,
95
+ )
96
  if response.status_code == 200:
97
+ data = response.json()
98
+ if isinstance(data, list) and "generated_text" in data[0]:
99
+ return data[0]["generated_text"]
100
+ elif isinstance(data, dict) and "generated_text" in data:
101
+ return data["generated_text"]
102
+ else:
103
+ raise RuntimeError("Неверный формат ответа")
104
+ elif response.status_code >= 500:
105
+ print("⚠️ Ошибка Router 5xx. Переподключение...")
106
+ self.auto_reconnect()
107
+ return self.request(model_id, prompt)
108
  else:
109
+ raise RuntimeError(f"Router ошибка: {response.status_code}")
110
+
111
+ except Exception as e:
112
+ print(f"❌ Router ошибка: {e}, активируем fallback...")
113
+ return self.fallback_request(prompt)
114
+
115
+ def fallback_request(self, prompt):
116
+ """Fallback на стабильную модель"""
117
+ fallback_model = "mistralai/Mixtral-8x7B-Instruct-v0.1"
118
+ try:
119
+ response = requests.post(
120
+ self.router_url,
121
+ headers=self.headers,
122
+ json={"model": fallback_model, "inputs": prompt},
123
+ timeout=60,
124
+ )
125
+ if response.status_code == 200:
126
+ data = response.json()
127
+ if isinstance(data, list) and "generated_text" in data[0]:
128
+ return f"[⚠️ Fallback {fallback_model}] {data[0]['generated_text']}"
129
+ raise RuntimeError(f"Fallback ошибка: {response.status_code}")
130
+ except Exception as e:
131
+ return f"❌ Ошибка fallback: {e}"
132
+
133
+
134
+ # ==============================
135
+ # 🐕 Watchdog Thread
136
+ # ==============================
137
+ def watchdog_loop(router_manager: RouterManager):
138
+ """Поток, который следит за Router API и токеном"""
139
+ while True:
140
+ try:
141
+ router_manager.check_router_health()
142
+ now = time.time()
143
+ # Проверка токена каждые 10 минут
144
+ if now - router_manager.last_token_validation > 600:
145
+ router_manager.validate_token()
146
+ router_manager.last_token_validation = now
147
+ time.sleep(60)
148
+ except Exception as e:
149
+ print("⚠️ Watchdog ошибка:", str(e))
150
+ time.sleep(30)
151
+
152
 
153
  # ==============================
154
+ # 🧠 Основная генерация
155
  # ==============================
156
+ router_manager = RouterManager(HF_TOKEN)
157
+
158
+
159
  def generate_response(user_input):
160
  try:
161
  start = time.time()
162
  prefs = analyze_user_input(user_input)
163
  model_id = choose_model(user_input)
164
 
165
+ result = router_manager.request(model_id, user_input)
 
166
  check = evaluate_answer(result)
167
  improved = improve_answer(result)
168
  personalized = adapt_answer(improved)
 
195
  except Exception as e:
196
  return f"❌ Ошибка выполнения: {str(e)}"
197
 
198
+
199
  # ==============================
200
+ # 📈 Аналитика
201
  # ==============================
202
  def generate_chart():
203
  if not os.path.exists(LOG_FILE):
 
221
  plt.close()
222
  return f"<img src='data:image/png;base64,{img_base64}'/>"
223
 
224
+
225
  def show_dashboard():
226
  metrics_text, df = dashboard.dashboard_ui()
227
  chart_html = generate_chart()
228
  return metrics_text, df, chart_html
229
 
230
+
231
  # ==============================
232
+ # 🎨 Gradio UI
233
  # ==============================
234
+ with gr.Blocks(title="Eroha AgentAPI v5.8Production-Cluster Core", theme="soft") as app:
235
+ gr.Markdown("# 🤖 Eroha AgentAPI v5.8Production-Cluster Core 🚀")
236
+ gr.Markdown("**Полный контроль: Router-watchdog + auto-heal + token-validation + fallback.**")
237
 
238
  with gr.Tab("💬 Agent Chat"):
239
+ user_input = gr.Textbox(label="Введите запрос", placeholder="Например: придумай легенду о ИИ, который нашёл сознание.")
240
  output_box = gr.Textbox(label="Ответ", lines=15)
241
  submit_btn = gr.Button("🚀 Отправить")
242
  submit_btn.click(fn=generate_response, inputs=user_input, outputs=output_box)
 
248
  refresh = gr.Button("🔄 Обновить дашборд")
249
  refresh.click(show_dashboard, outputs=[metrics, log_table, chart_box])
250
 
251
+ # 🔥 Запуск watchdog-потока
252
+ threading.Thread(target=watchdog_loop, args=(router_manager,), daemon=True).start()
253
+
254
  app.launch(server_name="0.0.0.0", server_port=7860)