fix(ai-config): editar cualquier config dejaba al agente sin cerebro

es_agente_bot no se podía marcar desde ninguna pantalla —el formulario nunca
mandaba el campo— y el update lo escribía igual con el valor cero. O sea que
guardar cualquier config desde /app/ai-config apagaba el cerebro del bot de
Telegram y del chat del panel, y no había forma de volver a prenderlo salvo
tocando la base.

- El update solo escribe los campos que vinieron en el body.
- El formulario tiene la casilla y el selector de bot de Telegram.
- Marcar una desmarca la anterior: GetAgenteBotAiConfig hace First(), así que
  con dos marcadas ganaba la que estuviera primero en la tabla.

Y el otro comportamiento raro: cuando ningún módulo coincidía, se usaba
"cualquier config activa". Eso podía elegir la de embeddings o la de Whisper,
que no conversan — el error que llegaba era del proveedor y no se parecía en
nada a la causa. Ahora esas quedan excluidas del comodín y, si no queda
ninguna usable, el error dice qué módulo asignar y dónde.

De paso: la etiqueta "IA / vCard" mentía (ese módulo alimenta además soporte,
el chat del panel y las plantillas), el comentario de is_active decía "solo uno
activo a la vez" cuando hace falta uno por módulo, y GetActiveAiConfig no la
usaba nadie.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-08-17 21:16:15 -05:00
co-authored by Claude Opus 5
parent 6a3a8c9248
commit f5ffed7a13
4 changed files with 116 additions and 33 deletions
+23
View File
@@ -0,0 +1,23 @@
package models
import "testing"
// El fallback de GetAiConfigForService puede terminar usando una config que no
// declara el servicio pedido. Lo que no puede es agarrar una dedicada a
// embeddings o a Whisper: esos endpoints no conversan, y el error del proveedor
// no se parece en nada a la causa real.
func TestConfigsDeUsoEspecialNoSirvenDeComodin(t *testing.T) {
casos := map[string]bool{
"whisper": true,
"umind_embeddings": true,
"landing,umind_embeddings": true,
"": false,
"ia": false,
"landing,query_runner": false,
}
for modulo, want := range casos {
if got := esConfigDeUsoEspecial(modulo); got != want {
t.Errorf("esConfigDeUsoEspecial(%q) = %v, want %v", modulo, got, want)
}
}
}