Agrega uMind: chat con IA embebible por tenant (F1 — widget web + RAG)

Multi-tenant dentro de soft_usite, reutilizando la infraestructura ya
existente (AiConfig, motor de function-calling del agente de Telegram)
en vez de un servicio nuevo aparte:

- UmindTenant: sitio/cliente con dominios permitidos, config de IA para
  el chat y personalidad/tono.
- Ingesta: crawler simple (mismo dominio, N páginas) + chunking +
  embeddings (config global con módulo "umind_embeddings", pensada
  para OpenAI ya que Claude no ofrece embeddings) guardados como JSON,
  con búsqueda por similitud coseno en memoria (sin pgvector todavía).
- Agente acotado: única herramienta buscar_conocimiento, sin acceso a
  nada interno — si no encuentra la respuesta, lo dice en vez de
  inventar.
- Widget público (/widget/umind.js + /widget/:site_key/*), autenticado
  por site_key + validación de dominio (Origin/Referer), no por
  secreto, ya que la key viaja en el HTML público del sitio instalado.
- Panel /app/umind: tenants, estado de ingesta, historial de
  conversaciones por sesión.
This commit is contained in:
Lizandro GD
2026-08-07 16:18:16 +00:00
parent 0eef3f80a3
commit 5ee5880dc2
17 changed files with 1806 additions and 4 deletions
+10
View File
@@ -96,4 +96,14 @@ func RutasPublicas(web fiber.Router) {
web.Get("/landing/download/:token", apiControllers.LandingDownload)
// Config de IA activa (para Landing Generator)
web.Get("/landing/ai-config", apiControllers.LandingGetAiConfig)
// ─── uMind: widget de chat embebible por tenant ───────────────────────────
// Público por diseño (lo llama el navegador del visitante de un sitio de
// terceros) — la protección es site_key + validación de dominio, no
// sesión. Excluido de AuthApi() por vivir fuera del grupo /api.
web.Get("/widget/umind.js", apiControllers.UmindWidgetScript)
widget := web.Group("/widget/:site_key")
widget.Options("*", middlewares.UmindWidgetCORS)
widget.Get("/init", middlewares.AuthUmindWidget, apiControllers.UmindWidgetInit)
widget.Post("/mensaje", middlewares.AuthUmindWidget, apiControllers.UmindWidgetMensaje)
}