BATUTOchatbot / app.py
ivanoctaviogaitansantos's picture
Actualizar app.py
7cb360c verified
raw
history blame
10.1 kB
import gradio as gr
import os
import json
from datetime import datetime
import logging
import threading
# Configuraci贸n de logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Importar m贸dulos personalizados
from model_manager import ModelManager
from api_agent import APIAgent
from prompt_generator import PromptGenerator
# Inicializar componentes
model_manager = ModelManager()
api_agent = APIAgent()
prompt_generator = PromptGenerator()
class BATUTOChatbot:
def __init__(self):
self.conversation_history = []
self.config = {
'deepseek_api_key': '',
'openai_api_key': '',
'max_tokens': 400,
'temperature': 0.7
}
def update_config(self, deepseek_key, openai_key, max_tokens, temperature):
"""Actualiza la configuraci贸n desde la UI"""
updated = False
if deepseek_key:
self.config['deepseek_api_key'] = deepseek_key
updated = True
if openai_key:
self.config['openai_api_key'] = openai_key
updated = True
if max_tokens:
self.config['max_tokens'] = int(max_tokens)
updated = True
if temperature:
self.config['temperature'] = float(temperature)
updated = True
# Actualizar agentes
model_manager.set_config(self.config)
api_agent.set_config(self.config)
return 'Configuraci贸n actualizada' if updated else 'Sin cambios'
def get_system_status(self):
"""Obtiene el estado del sistema"""
has_deepseek = bool(self.config.get('deepseek_api_key'))
has_openai = bool(self.config.get('openai_api_key'))
models_loaded = model_manager.loaded
status_html = f'''
<div style='padding: 15px; border-radius: 10px; background: #f8f9fa; border: 2px solid #e9ecef;'>
<h4 style='margin-top: 0;'>Estado del Sistema</h4>
<p><strong>Modelos locales:</strong> {'Cargados' if models_loaded else 'Cargando...'}</p>
<p><strong>DeepSeek API:</strong> {'Configurada' if has_deepseek else 'No configurada'}</p>
<p><strong>OpenAI API:</strong> {'Configurada' if has_openai else 'No configurada'}</p>
<p><strong>Mensajes en sesi贸n:</strong> {len(self.conversation_history)}</p>
</div>
'''
return status_html
def chat_response(self, message, history):
"""Genera respuesta del chatbot optimizado para HF"""
if not message.strip():
return ''
# Mostrar indicador de typing
yield 'Procesando...'
try:
# Detectar intenci贸n y mejorar prompt
intent = prompt_generator.detect_intent(message)
enhanced_prompt = prompt_generator.enhance_prompt(message, intent)
# Intentar usar APIs primero
api_result = api_agent.generate_response(enhanced_prompt, intent['is_code'])
if api_result['response']:
# Usar respuesta de API
response_text = api_result['response']
source = api_result['source']
else:
# Usar modelo local como fallback
response_text = model_manager.generate_local_response(
enhanced_prompt,
intent['is_code'],
max_length=200
)
source = 'local'
# Agregar metadata a la respuesta
metadata = f'\n\n---\nFuente: {source.upper()}'
if intent['is_code']:
metadata += f' | Tipo: C贸digo'
else:
metadata += f' | Tipo: Conversaci贸n'
full_response = response_text + metadata
# Guardar en historial
self.conversation_history.append({
'timestamp': datetime.now().isoformat(),
'user': message,
'bot': response_text,
'source': source,
'intent': intent
})
yield full_response
except Exception as e:
error_msg = f'Error: {str(e)}'
logger.error(f'Error en chat_response: {e}')
yield error_msg
def clear_conversation(self):
"""Limpia la conversaci贸n"""
self.conversation_history.clear()
return None, []
# Crear instancia del chatbot
chatbot = BATUTOChatbot()
# Cargar modelos al inicio (async)
def load_models_async():
logger.info('Cargando modelos en segundo plano...')
model_manager.load_models()
logger.info('Modelos cargados exitosamente')
# Iniciar carga de modelos
model_loader = threading.Thread(target=load_models_async, daemon=True)
model_loader.start()
# Configuraci贸n de la interfaz Gradio para HF
with gr.Blocks(
title='BATUTO Chatbot - Asistente Educativo',
theme=gr.themes.Soft(),
css='''
.gradio-container {
max-width: 1000px !important;
margin: auto;
}
.chat-container {
height: 500px;
}
.status-panel {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
padding: 20px;
border-radius: 10px;
color: white;
}
'''
) as demo:
gr.Markdown('''
# BATUTO Chatbot - Asistente Educativo
**Sistema inteligente con modelos locales y APIs externas**
*Desplegado en Hugging Face Spaces - Versi贸n Optimizada*
''')
with gr.Row():
with gr.Column(scale=2):
# 脕rea de chat
gr.Markdown('### Conversaci贸n')
chatbot_interface = gr.Chatbot(
label='Chat con BATUTO',
height=400,
show_copy_button=True,
container=True
)
msg = gr.Textbox(
label='Escribe tu mensaje',
placeholder='Pregunta sobre programaci贸n, explica conceptos, pide ejemplos...',
lines=2,
max_lines=4
)
with gr.Row():
submit_btn = gr.Button('Enviar', variant='primary')
clear_btn = gr.Button('Limpiar', variant='secondary')
with gr.Column(scale=1):
# Panel de estado
gr.Markdown('### Estado del Sistema')
status_display = gr.HTML()
# Configuraci贸n r谩pida
with gr.Accordion('Configuraci贸n R谩pida', open=False):
with gr.Group():
deepseek_key = gr.Textbox(
label='DeepSeek API Key',
type='password',
placeholder='sk-...',
info='Opcional - para respuestas mejoradas'
)
openai_key = gr.Textbox(
label='OpenAI API Key',
type='password',
placeholder='sk-...',
info='Opcional - alternativa'
)
with gr.Row():
max_tokens = gr.Slider(
label='Tokens m谩x',
minimum=100,
maximum=800,
value=400,
step=50
)
temperature = gr.Slider(
label='Temperatura',
minimum=0.1,
maximum=1.0,
value=0.7,
step=0.1
)
save_config_btn = gr.Button('Guardar Config', size='sm')
config_output = gr.Textbox(label='Estado', interactive=False)
# Informaci贸n
with gr.Accordion('C贸mo usar', open=True):
gr.Markdown('''
**Ejemplos:**
- Mu茅strame una funci贸n Python para ordenar listas
- Explica qu茅 es machine learning
- Corrige este c贸digo: [tu c贸digo]
**Fuentes:**
1. DeepSeek API (si se configura)
2. OpenAI API (si se configura)
3. Modelos locales (fallback)
''')
# Event handlers
def handle_submit(message, history):
if not message.strip():
return '', history
return '', history + [[message, None]]
# Conectar el bot贸n de enviar
submit_btn.click(
handle_submit,
inputs=[msg, chatbot_interface],
outputs=[msg, chatbot_interface]
).then(
chatbot.chat_response,
inputs=[msg, chatbot_interface],
outputs=[chatbot_interface]
)
# Enter tambi茅n env铆a
msg.submit(
handle_submit,
inputs=[msg, chatbot_interface],
outputs=[msg, chatbot_interface]
).then(
chatbot.chat_response,
inputs=[msg, chatbot_interface],
outputs=[chatbot_interface]
)
# Limpiar chat
clear_btn.click(
chatbot.clear_conversation,
outputs=[msg, chatbot_interface]
)
# Configuraci贸n
save_config_btn.click(
chatbot.update_config,
inputs=[deepseek_key, openai_key, max_tokens, temperature],
outputs=[config_output]
).then(
chatbot.get_system_status,
outputs=[status_display]
)
# Actualizar estado al cargar
demo.load(
chatbot.get_system_status,
outputs=[status_display]
)
# Configuraci贸n espec铆fica para Hugging Face Spaces
if __name__ == '__main__':
demo.launch(
server_name='0.0.0.0',
server_port=7860,
share=True,
show_error=True,
debug=False
)