raiden3145 commited on
Commit
e06d76f
·
1 Parent(s): 9c10516

Simplify: use zephyr-7b-beta with ChatInterface

Browse files
Files changed (1) hide show
  1. app.py +29 -216
app.py CHANGED
@@ -1,6 +1,6 @@
1
  """
2
  AURA Chat — Hugging Face Space
3
- Asistente IA generalista con memoria conversacional, routing multi-modelo y evolución.
4
  """
5
 
6
  import os
@@ -12,8 +12,7 @@ from pathlib import Path
12
  from datetime import datetime
13
 
14
  import gradio as gr
15
-
16
- from src.model_router import ModelRouter
17
 
18
  logging.basicConfig(
19
  level=logging.INFO,
@@ -34,165 +33,42 @@ MAX_HISTORY = 10
34
  INTERACTIONS_FILE = "data/interactions.jsonl"
35
  PREFERENCES_FILE = "data/preferences.json"
36
 
37
- PRIMARY_MODEL = os.getenv("HF_MODEL", "microsoft/Phi-3-mini-4k-instruct")
38
  HF_TOKEN = os.getenv("HF_TOKEN", "")
39
 
40
- router = ModelRouter(
41
- primary_model=PRIMARY_MODEL,
42
- hf_token=HF_TOKEN,
43
- )
 
 
44
 
45
  DATA_DIR = Path("data")
46
  DATA_DIR.mkdir(exist_ok=True)
47
 
48
 
49
- def load_preferences() -> Dict:
50
- path = Path(PREFERENCES_FILE)
51
- if path.exists():
52
- try:
53
- return json.loads(path.read_text(encoding="utf-8"))
54
- except (json.JSONDecodeError, OSError):
55
- return {}
56
- return {}
57
-
58
-
59
- def save_preferences(prefs: Dict) -> None:
60
- try:
61
- Path(PREFERENCES_FILE).write_text(
62
- json.dumps(prefs, indent=2, ensure_ascii=False), encoding="utf-8"
63
- )
64
- except OSError as exc:
65
- logger.warning("Could not save preferences: %s", exc)
66
-
67
-
68
- def log_interaction(prompt: str, response: str, model: str, domain: str, latency: float) -> None:
69
- try:
70
- entry = {
71
- "timestamp": datetime.now().isoformat(),
72
- "prompt": prompt,
73
- "response_length": len(response),
74
- "model": model,
75
- "domain": domain,
76
- "latency_s": round(latency, 2),
77
- }
78
- with open(INTERACTIONS_FILE, "a", encoding="utf-8") as f:
79
- f.write(json.dumps(entry, ensure_ascii=False) + "\n")
80
- except OSError as exc:
81
- logger.warning("Could not log interaction: %s", exc)
82
-
83
-
84
- def get_interaction_stats() -> Dict:
85
- path = Path(INTERACTIONS_FILE)
86
- if not path.exists():
87
- return {"total": 0, "domains": {}, "models": {}}
88
-
89
- stats = {"total": 0, "domains": {}, "models": {}}
90
- try:
91
- for line in path.read_text(encoding="utf-8").splitlines():
92
- line = line.strip()
93
- if not line:
94
- continue
95
- try:
96
- entry = json.loads(line)
97
- stats["total"] += 1
98
- domain = entry.get("domain", "unknown")
99
- stats["domains"][domain] = stats["domains"].get(domain, 0) + 1
100
- model = entry.get("model", "unknown")
101
- stats["models"][model] = stats["models"].get(model, 0) + 1
102
- except json.JSONDecodeError:
103
- continue
104
- except OSError:
105
- pass
106
- return stats
107
-
108
-
109
- def chat_fn(
110
- message: str,
111
- history: List[Tuple[str, str]],
112
- system_prompt: str,
113
- temperature: float,
114
- max_tokens: int,
115
- ) -> Tuple[str, List[Tuple[str, str]]]:
116
- if not message or not message.strip():
117
- return "Por favor escribe un mensaje.", history
118
 
119
  messages = []
120
  for user_msg, bot_msg in history:
121
  messages.append({"role": "user", "content": user_msg})
122
  if bot_msg:
123
  messages.append({"role": "assistant", "content": bot_msg})
 
124
 
125
- sp = system_prompt if system_prompt and system_prompt.strip() else SYSTEM_PROMPT
126
-
127
- start = time.time()
128
  try:
129
- result = router.query(
130
- prompt=message,
131
- system_prompt=sp,
132
- max_tokens=int(max_tokens),
133
- temperature=float(temperature),
134
- history=messages,
135
  )
136
- latency = time.time() - start
137
-
138
- if result["error"]:
139
- response = (
140
- "⚠️ Lo siento, el modelo no está disponible en este momento. "
141
- "Esto puede ocurrir si el Space se quedó sin créditos de API. "
142
- "Por favor intenta de nuevo más tarde.\n\n"
143
- f"Detalle técnico: {result['error']}"
144
- )
145
- else:
146
- response = result["response"]
147
-
148
- log_interaction(
149
- prompt=message,
150
- response=response,
151
- model=result.get("model_used", "unknown"),
152
- domain=result.get("domain", "unknown"),
153
- latency=latency,
154
- )
155
- return response, history
156
-
157
  except Exception as e:
158
- logger.error("Chat error: %s", e, exc_info=True)
159
- return (
160
- "❌ Ocurrió un error inesperado. Por favor intenta de nuevo.\n\n"
161
- f"Error: {str(e)}",
162
- history,
163
- )
164
-
165
-
166
- def clear_chat() -> Tuple[List[Tuple[str, str]], str]:
167
- router.cache.clear()
168
- return [], ""
169
-
170
-
171
- def get_status() -> str:
172
- health = router.health_check()
173
- stats = get_interaction_stats()
174
-
175
- lines = [
176
- "## 📊 Estado del Sistema\n",
177
- f"**Modelo primario:** {health['primary_model']}",
178
- f"**Estado:** {'✅ Online' if health['primary_online'] else '⚠️ Degradado'}",
179
- f"**Cache:** {health['cache_size']} respuestas cacheadas",
180
- "",
181
- "### 📈 Estadísticas de uso",
182
- f"**Total interacciones:** {stats['total']}",
183
- ]
184
-
185
- if stats.get("domains"):
186
- lines.append("\n**Por dominio:**")
187
- for domain, count in sorted(stats["domains"].items(), key=lambda x: -x[1]):
188
- lines.append(f"- {domain}: {count}")
189
-
190
- if stats.get("models"):
191
- lines.append("\n**Por modelo:**")
192
- for model, count in sorted(stats["models"].items(), key=lambda x: -x[1]):
193
- lines.append(f"- {model}: {count}")
194
-
195
- return "\n".join(lines)
196
 
197
 
198
  CSS = """
@@ -217,77 +93,14 @@ with gr.Blocks(
217
  """
218
  )
219
 
220
- chatbot = gr.Chatbot(
221
- label="Conversación",
222
- height=450,
223
- bubble_full_width=False,
224
- show_copy_button=True,
225
- )
226
-
227
- msg = gr.Textbox(
228
- label="Tu mensaje",
229
- placeholder="Escribe tu mensaje aquí...",
230
- lines=2,
231
- max_lines=6,
232
- )
233
-
234
- with gr.Row():
235
- clear_btn = gr.Button("🗑️ Clear Chat", variant="secondary", scale=1)
236
- status_btn = gr.Button("📊 Estado", variant="secondary", scale=1)
237
- submit_btn = gr.Button("🚀 Enviar", variant="primary", scale=2)
238
-
239
- with gr.Accordion("⚙️ Configuración avanzada", open=False):
240
- system_prompt_input = gr.Textbox(
241
- label="System Prompt",
242
- value=SYSTEM_PROMPT,
243
- lines=3,
244
- max_lines=6,
245
- )
246
- with gr.Row():
247
- temperature_slider = gr.Slider(
248
- minimum=0.1, maximum=1.5, value=0.7, step=0.1, label="Temperatura"
249
- )
250
- max_tokens_slider = gr.Slider(
251
- minimum=64, maximum=2048, value=512, step=64, label="Máx. tokens"
252
- )
253
-
254
- status_output = gr.Markdown(visible=False)
255
-
256
- msg.submit(
257
- fn=chat_fn,
258
- inputs=[msg, chatbot, system_prompt_input, temperature_slider, max_tokens_slider],
259
- outputs=[msg, chatbot],
260
- ).then(
261
- fn=lambda: "",
262
- inputs=[],
263
- outputs=msg,
264
- queue=False,
265
- )
266
-
267
- submit_btn.click(
268
- fn=chat_fn,
269
- inputs=[msg, chatbot, system_prompt_input, temperature_slider, max_tokens_slider],
270
- outputs=[msg, chatbot],
271
- ).then(
272
- fn=lambda: "",
273
- inputs=[],
274
- outputs=msg,
275
- queue=False,
276
- )
277
-
278
- clear_btn.click(
279
- fn=clear_chat,
280
- inputs=[],
281
- outputs=[chatbot, msg],
282
- )
283
-
284
- def show_status():
285
- return gr.update(visible=True), get_status()
286
-
287
- status_btn.click(
288
- fn=show_status,
289
- inputs=[],
290
- outputs=[status_output],
291
  )
292
 
293
  gr.Markdown(
 
1
  """
2
  AURA Chat — Hugging Face Space
3
+ Simple, no external model dependencies - works on CPU free tier.
4
  """
5
 
6
  import os
 
12
  from datetime import datetime
13
 
14
  import gradio as gr
15
+ from huggingface_hub import InferenceClient
 
16
 
17
  logging.basicConfig(
18
  level=logging.INFO,
 
33
  INTERACTIONS_FILE = "data/interactions.jsonl"
34
  PREFERENCES_FILE = "data/preferences.json"
35
 
36
+ MODEL_ID = "HuggingFaceH4/zephyr-7b-beta" # Works on Inference API
37
  HF_TOKEN = os.getenv("HF_TOKEN", "")
38
 
39
+ client = None
40
+ if HF_TOKEN:
41
+ try:
42
+ client = InferenceClient(token=HF_TOKEN)
43
+ except Exception as e:
44
+ logger.warning("Could not initialize InferenceClient: %s", e)
45
 
46
  DATA_DIR = Path("data")
47
  DATA_DIR.mkdir(exist_ok=True)
48
 
49
 
50
+ def get_response(message: str, history: list, temperature: float, max_tokens: int) -> str:
51
+ if not client:
52
+ return "⚠️ No se pudo conectar al modelo. Verifica que HF_TOKEN esté configurado."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
 
54
  messages = []
55
  for user_msg, bot_msg in history:
56
  messages.append({"role": "user", "content": user_msg})
57
  if bot_msg:
58
  messages.append({"role": "assistant", "content": bot_msg})
59
+ messages.append({"role": "user", "content": message})
60
 
 
 
 
61
  try:
62
+ response = client.chat_completion(
63
+ model=MODEL_ID,
64
+ messages=messages,
65
+ max_tokens=max_tokens,
66
+ temperature=temperature,
 
67
  )
68
+ return response.choices[0].message.content.strip()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  except Exception as e:
70
+ logger.error("Error querying model: %s", e)
71
+ return f"⚠️ Error al consultar el modelo: {str(e)}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
 
73
 
74
  CSS = """
 
93
  """
94
  )
95
 
96
+ gr.ChatInterface(
97
+ fn=get_response,
98
+ title=None,
99
+ description=None,
100
+ additional_inputs=[
101
+ gr.Slider(minimum=0.1, maximum=1.5, value=0.7, step=0.1, label="Temperatura"),
102
+ gr.Slider(minimum=64, maximum=2048, value=512, step=64, label="Máx. tokens"),
103
+ ],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  )
105
 
106
  gr.Markdown(