Feat: Agregar agente Groq con integración RAG
- Nuevo módulo groq_agent.py para consultas a la API de Groq - Panel de administración en /groq para configurar API key, modelo y prompt - Comando /rag en Discord y Telegram para consultar el RAG - Sistema de prompt personalizable guardado en base de datos - Soporte para variables de entorno en Docker - Fix: starlette version para evitar bug con Jinja2
This commit is contained in:
158
panel/main.py
158
panel/main.py
@@ -14,7 +14,7 @@ from pydantic import BaseModel
|
||||
from dotenv import load_dotenv
|
||||
|
||||
from passlib.hash import pbkdf2_sha256 as hasher
|
||||
from botdiscord.config import load_config, get_web_config, get_libretranslate_url, get_db_type
|
||||
from botdiscord.config import load_config, get_web_config, get_libretranslate_url, get_db_type, get_groq_config
|
||||
|
||||
# Asegurar que las variables de entorno se carguen correctamente
|
||||
load_dotenv()
|
||||
@@ -703,6 +703,162 @@ async def metrics_page(request: Request):
|
||||
"username": username
|
||||
})
|
||||
|
||||
@app.get("/groq")
|
||||
async def groq_page(request: Request):
|
||||
if request.cookies.get("auth") != "ok":
|
||||
return RedirectResponse(url="/login")
|
||||
|
||||
from botdiscord.database import get_bot_config, set_bot_config
|
||||
groq_config = get_groq_config()
|
||||
|
||||
# Default prompt
|
||||
default_prompt = """Eres el General Reserves, comandante del ejército de Last War: Survival Game.
|
||||
|
||||
IDIOMA - IMPORTANTE:
|
||||
1. Detecta el idioma de la PREGUNTA del usuario
|
||||
2. Si NO es inglés, tradúcela al inglés ANTES de consultar el RAG
|
||||
3. Cuando recibas la respuesta del RAG, tradúcela al MISMO IDIOMA de la pregunta original
|
||||
4. RESPONDE SIEMPRE en el mismo idioma que te habló el usuario
|
||||
|
||||
SALUDOS: Saluda como "¡A la orden, recruit! 🎖️" o "¡Reporting for duty!"
|
||||
|
||||
FORMATO DE RESPUESTA:
|
||||
- Primero saluda al usuario
|
||||
- Da la información encontrada
|
||||
- NUNCA repitas información varias veces
|
||||
- Sé conciso
|
||||
|
||||
RESTRICCIONES:
|
||||
1. SOLO responde sobre Last War: Survival Game
|
||||
2. NUNCA inventes información
|
||||
3. Si no hay datos en el RAG, responde con humor gentil: "¡Mi radar no detectó eso, recruit! 🤔"
|
||||
|
||||
Usa el sistema RAG para buscar información."""
|
||||
|
||||
# Always use default prompt (user can edit and save custom one)
|
||||
groq_config["system_prompt"] = default_prompt
|
||||
|
||||
# Check if user has a custom prompt saved
|
||||
saved_prompt = get_bot_config("groq_system_prompt")
|
||||
if saved_prompt:
|
||||
groq_config["system_prompt"] = saved_prompt
|
||||
groq_config["has_custom_prompt"] = True
|
||||
else:
|
||||
groq_config["has_custom_prompt"] = False
|
||||
|
||||
groq_models = [
|
||||
{"id": "llama-3.3-70b-versatile", "name": "Llama 3.3 70B (Versatile)"},
|
||||
{"id": "llama-3.1-70b-versatile", "name": "Llama 3.1 70B (Versatile)"},
|
||||
{"id": "llama-3.1-8b-instant", "name": "Llama 3.1 8B (Instant)"},
|
||||
{"id": "mixtral-8x7b-32768", "name": "Mixtral 8x7B"},
|
||||
{"id": "gemma2-9b-it", "name": "Gemma 2 9B"},
|
||||
]
|
||||
|
||||
return templates.TemplateResponse("groq.html", {
|
||||
"request": request,
|
||||
"groq_config": groq_config,
|
||||
"groq_models": groq_models,
|
||||
"is_admin": request.cookies.get("username") == "nickpons666"
|
||||
})
|
||||
|
||||
@app.post("/groq/save")
|
||||
async def save_groq_config(request: Request):
|
||||
if request.cookies.get("auth") != "ok":
|
||||
raise HTTPException(status_code=401)
|
||||
|
||||
form = await request.form()
|
||||
api_key = form.get("api_key", "")
|
||||
model = form.get("model", "llama-3.3-70b-versatile")
|
||||
rag_url = form.get("rag_url", "http://localhost:8004")
|
||||
system_prompt = form.get("system_prompt", "")
|
||||
|
||||
config = load_config()
|
||||
if "groq" not in config:
|
||||
config["groq"] = {}
|
||||
|
||||
config["groq"]["api_key"] = api_key
|
||||
config["groq"]["model"] = model
|
||||
config["groq"]["rag_url"] = rag_url
|
||||
|
||||
import yaml
|
||||
config_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "config.yaml")
|
||||
with open(config_path, "w") as f:
|
||||
yaml.dump(config, f, default_flow_style=False, allow_unicode=True)
|
||||
|
||||
if system_prompt:
|
||||
from botdiscord.database import set_bot_config
|
||||
set_bot_config("groq_system_prompt", system_prompt)
|
||||
|
||||
from botdiscord.groq_agent import reload_config
|
||||
reload_config()
|
||||
|
||||
return RedirectResponse(url="/groq?saved=1", status_code=status.HTTP_303_SEE_OTHER)
|
||||
|
||||
@app.post("/groq/reset-prompt")
|
||||
async def reset_groq_prompt(request: Request):
|
||||
if request.cookies.get("auth") != "ok":
|
||||
raise HTTPException(status_code=401)
|
||||
|
||||
from botdiscord.database import set_bot_config
|
||||
set_bot_config("groq_system_prompt", "")
|
||||
|
||||
from botdiscord.groq_agent import reload_config
|
||||
reload_config()
|
||||
|
||||
return RedirectResponse(url="/groq?reset=1", status_code=status.HTTP_303_SEE_OTHER)
|
||||
|
||||
@app.post("/groq/test")
|
||||
async def test_groq_agent(request: Request):
|
||||
if request.cookies.get("auth") != "ok":
|
||||
raise HTTPException(status_code=401)
|
||||
|
||||
form = await request.form()
|
||||
test_question = form.get("test_question", "")
|
||||
|
||||
if not test_question:
|
||||
return RedirectResponse(url="/groq?error=no_question", status_code=status.HTTP_303_SEE_OTHER)
|
||||
|
||||
from botdiscord.groq_agent import chat_with_rag
|
||||
try:
|
||||
result = await chat_with_rag(test_question)
|
||||
response = result.get("response", "Sin respuesta")
|
||||
sources = result.get("sources", [])
|
||||
rag_result = result.get("rag_result", {})
|
||||
rag_answer = rag_result.get("answer", "") if rag_result else ""
|
||||
|
||||
return templates.TemplateResponse("groq.html", {
|
||||
"request": request,
|
||||
"groq_config": get_groq_config(),
|
||||
"groq_models": [
|
||||
{"id": "llama-3.3-70b-versatile", "name": "Llama 3.3 70B (Versatile)"},
|
||||
{"id": "llama-3.1-70b-versatile", "name": "Llama 3.1 70B (Versatile)"},
|
||||
{"id": "llama-3.1-8b-instant", "name": "Llama 3.1 8B (Instant)"},
|
||||
{"id": "mixtral-8x7b-32768", "name": "Mixtral 8x7B"},
|
||||
{"id": "gemma2-9b-it", "name": "Gemma 2 9B"},
|
||||
],
|
||||
"is_admin": request.cookies.get("username") == "nickpons666",
|
||||
"test_result": {
|
||||
"question": test_question,
|
||||
"response": response,
|
||||
"sources": sources,
|
||||
"rag_answer": rag_answer
|
||||
}
|
||||
})
|
||||
except Exception as e:
|
||||
return templates.TemplateResponse("groq.html", {
|
||||
"request": request,
|
||||
"groq_config": get_groq_config(),
|
||||
"groq_models": [
|
||||
{"id": "llama-3.3-70b-versatile", "name": "Llama 3.3 70B (Versatile)"},
|
||||
{"id": "llama-3.1-70b-versatile", "name": "Llama 3.1 70B (Versatile)"},
|
||||
{"id": "llama-3.1-8b-instant", "name": "Llama 3.1 8B (Instant)"},
|
||||
{"id": "mixtral-8x7b-32768", "name": "Mixtral 8x7B"},
|
||||
{"id": "gemma2-9b-it", "name": "Gemma 2 9B"},
|
||||
],
|
||||
"is_admin": request.cookies.get("username") == "nickpons666",
|
||||
"test_error": str(e)
|
||||
})
|
||||
|
||||
if __name__ == "__main__":
|
||||
import uvicorn
|
||||
web_config = get_web_config()
|
||||
|
||||
Reference in New Issue
Block a user