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:
@@ -117,6 +117,11 @@ func Migrate() {
|
||||
&models.Arquitectura{},
|
||||
// Vinculación de Telegram para staff interno
|
||||
&models.TelegramStaffToken{},
|
||||
// uMind: chat con IA embebible por tenant (widget web + RAG)
|
||||
&models.UmindTenant{},
|
||||
&models.UmindDocumento{},
|
||||
&models.UmindChunk{},
|
||||
&models.UmindMensaje{},
|
||||
}
|
||||
for _, m := range modelosPrincipales {
|
||||
if err := app.Http.Database.DB.Migrator().AutoMigrate(m); err != nil {
|
||||
@@ -1267,3 +1272,40 @@ func SeedPagosExternos() {
|
||||
}
|
||||
log.Println("[SEED] Seed de Pagos externos completado.")
|
||||
}
|
||||
|
||||
// SeedUmind registra el submódulo del panel de administración de uMind
|
||||
// (tenants, base de conocimiento y conversaciones del widget embebible).
|
||||
func SeedUmind() {
|
||||
db := app.Http.Database.DB
|
||||
var modulo models.Modules
|
||||
if err := db.Where("title = ?", "Automatización IA").First(&modulo).Error; err != nil {
|
||||
log.Println("[SEED] Módulo 'Automatización IA' no encontrado, se omite SeedUmind")
|
||||
return
|
||||
}
|
||||
url := "/app/umind"
|
||||
var sub models.Submodules
|
||||
if err := db.Where("url = ?", url).First(&sub).Error; err != nil {
|
||||
sub = models.Submodules{
|
||||
Title: "uMind",
|
||||
Description: "Chat con IA embebible por sitio, con base de conocimiento propia (RAG)",
|
||||
Url: url,
|
||||
ModuleId: modulo.ID,
|
||||
ModifiedAt: time.Now(),
|
||||
}
|
||||
if err := db.Create(&sub).Error; err != nil {
|
||||
log.Printf("[SEED] Error creando submódulo 'uMind': %v", err)
|
||||
return
|
||||
}
|
||||
log.Printf("[SEED] Submódulo 'uMind' creado")
|
||||
} else if sub.ModuleId != modulo.ID {
|
||||
db.Model(&sub).Update("module_id", modulo.ID)
|
||||
}
|
||||
var rol models.Roles
|
||||
if err := db.Where("name = ?", "Administrador").First(&rol).Error; err != nil {
|
||||
log.Printf("[SEED] Rol 'Administrador' no encontrado, se omite asignación: %v", err)
|
||||
} else {
|
||||
asignarSubmodulosSiFaltan(&rol, []models.Submodules{sub})
|
||||
log.Printf("[SEED] Submódulo 'uMind' asignado al rol 'Administrador'")
|
||||
}
|
||||
log.Println("[SEED] Seed de uMind completado.")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user