fix(telegram): si una herramienta falla, el bot lo dice aunque el modelo no

Confirmado que la factura nunca se creó: la lista de /app/facturas no
filtra nada que pudiera esconderla. La herramienta falló y el modelo
informó "FACTURA GUARDADA EXITOSAMENTE" igual.

El commit anterior le prohíbe eso por prompt, pero un prompt es una
sugerencia. Esto es la garantía: el código junta los errores que
devolvieron las herramientas durante la conversación y los agrega a la
respuesta. Si algo no se completó, se ve, diga lo que diga el modelo.

No reemplaza al prompt — el modelo sigue debiendo explicar el fallo con
sus palabras. Es la red por debajo, para que un "guardado exitosamente"
sobre algo que no se guardó no pueda pasar desapercibido otra vez.

Sigue sin saberse por qué falló aquella vez, porque hasta hoy el resultado
de las herramientas no se registraba. Con el log y este aviso, el próximo
intento lo va a decir en el momento.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-08-15 21:12:23 -05:00
co-authored by Claude Sonnet 5
parent 560dc261e9
commit d0c9ed5656
2 changed files with 51 additions and 0 deletions
+22
View File
@@ -43,3 +43,25 @@ func TestExisteHerramientaParaFacturaSinAdjunto(t *testing.T) {
}
}
}
// El modelo puede informar éxito aunque la herramienta haya fallado — pasó con
// una factura que nunca se creó. El aviso lo escribe el código a partir del
// resultado real, así que no depende de que el modelo se porte bien.
func TestErrorDeTool(t *testing.T) {
casos := []struct {
nombre string
resultado string
esperado string
}{
{"error de la herramienta", `{"error": "cliente_id requerido"}`, "cliente_id requerido"},
{"resultado exitoso", `{"ok": true, "factura_id": 12}`, ""},
{"lista de datos", `{"items": [], "total": 0}`, ""},
{"resultado no JSON", `algo suelto`, ""},
{"error vacío no cuenta", `{"error": ""}`, ""},
}
for _, cas := range casos {
if got := errorDeTool(cas.resultado); got != cas.esperado {
t.Errorf("%s: errorDeTool(%s) = %q, esperaba %q", cas.nombre, cas.resultado, got, cas.esperado)
}
}
}