From a8cc5c6289c455de467bfd227d443bd28a9463da Mon Sep 17 00:00:00 2001 From: Lizandro Guarnizo <77708265+lizandrogd@users.noreply.github.com> Date: Fri, 21 Aug 2026 19:41:13 -0500 Subject: [PATCH] =?UTF-8?q?fix(umind):=20la=20respuesta=20gen=C3=A9rica=20?= =?UTF-8?q?no=20quedaba=20en=20la=20conversaci=C3=B3n,=20y=20eso=20perpetu?= =?UTF-8?q?aba=20el=20error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cuando el agente caía en "dame un poco más de detalle", esa respuesta no se guardaba. En Conversaciones quedaban las preguntas del visitante una tras otra sin ninguna respuesta, así que el dueño no tenía forma de enterarse de que su agente estaba fallando — justo la pantalla donde debería verlo. Lo grave es lo otro: ese historial se le reenvía al modelo en cada turno. Un modelo que ve cuatro preguntas seguidas y ninguna respuesta lee una conversación rota, se confunde y vuelve a fallar. El primer error se perpetuaba solo, y por eso una vez que empezaba ya no salía más. Ahora se guarda siempre lo que el visitante recibió, sea la respuesta buena o la genérica. Las sesiones que ya quedaron con el historial roto se normalizan solas: la ventana es de 6 mensajes, así que después de un par de intercambios buenos los huecos salen de contexto. Co-Authored-By: Claude Opus 5 --- pkg/services/umind_agent_service.go | 9 +++++- pkg/services/umind_historial_test.go | 42 ++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 pkg/services/umind_historial_test.go diff --git a/pkg/services/umind_agent_service.go b/pkg/services/umind_agent_service.go index 9667b14..6c4859a 100644 --- a/pkg/services/umind_agent_service.go +++ b/pkg/services/umind_agent_service.go @@ -374,10 +374,17 @@ func ProcessWidgetMessage(agente *models.UmindAgente, sessionID, userText string // Antes de dar el mensaje genérico, usar lo que el modelo ya escribió. if strings.TrimSpace(ultimoTextoParcial) != "" { finalResponse = ultimoTextoParcial - _ = models.SaveUmindMensaje(agente.ID, sessionID, "assistant", finalResponse) } else { finalResponse = "Un momento, por favor — dame un poco más de detalle sobre lo que necesitas." } + // Se guarda igual, aunque sea el mensaje genérico. Sin esto quedaba una + // conversación con varios mensajes del visitante y ninguna respuesta: + // no se veía en Conversaciones —el dueño no se enteraba de que su + // agente estaba fallando— y, peor, ese historial roto se le reenviaba + // al modelo en el turno siguiente. Un modelo que ve cuatro preguntas + // seguidas sin una sola respuesta se confunde y vuelve a fallar, así + // que el primer error se perpetuaba solo. + _ = models.SaveUmindMensaje(agente.ID, sessionID, "assistant", finalResponse) } return finalResponse, nil } diff --git a/pkg/services/umind_historial_test.go b/pkg/services/umind_historial_test.go new file mode 100644 index 0000000..ce6e34a --- /dev/null +++ b/pkg/services/umind_historial_test.go @@ -0,0 +1,42 @@ +package services + +import ( + "os" + "strings" + "testing" +) + +// Todo lo que ve el visitante tiene que quedar guardado, incluido el mensaje +// genérico de cuando algo falla. Sin eso pasaban dos cosas, y la segunda es la +// grave: +// +// 1. En Conversaciones se veían las preguntas sin ninguna respuesta, así que +// el dueño no se enteraba de que su agente estaba fallando. +// 2. Ese historial roto se le reenviaba al modelo en el turno siguiente. Un +// modelo que ve cuatro preguntas seguidas sin una sola respuesta se +// confunde y vuelve a fallar: el primer error se perpetuaba solo. +func TestLaRespuestaAlVisitanteSiempreQuedaGuardada(t *testing.T) { + b, err := os.ReadFile("umind_agent_service.go") + if err != nil { + t.Fatal(err) + } + fuente := string(b) + + // El bloque del fallback tiene que guardar. + i := strings.Index(fuente, `if finalResponse == "" {`) + if i < 0 { + t.Fatal("no encontré el bloque de fallback") + } + bloque := fuente[i:] + if j := strings.Index(bloque, "\n\treturn finalResponse"); j > 0 { + bloque = bloque[:j] + } + if !strings.Contains(bloque, "SaveUmindMensaje") { + t.Error("el mensaje genérico no se guarda: la conversación queda con preguntas sin respuesta y el historial roto se reenvía al modelo") + } + + // Y el mensaje del visitante también, desde antes del bucle. + if !strings.Contains(fuente, `SaveUmindMensaje(agente.ID, sessionID, "user", userText)`) { + t.Error("no se guarda el mensaje del visitante") + } +}