diff --git a/pkg/services/telegram_agent_service.go b/pkg/services/telegram_agent_service.go index 9fae16e..da0c9a2 100644 --- a/pkg/services/telegram_agent_service.go +++ b/pkg/services/telegram_agent_service.go @@ -10,6 +10,7 @@ import ( "net/http" "os" "path/filepath" + "strconv" "strings" "time" @@ -453,6 +454,29 @@ func runTool(chatID int64, name string, a map[string]interface{}) (interface{}, } return def } + // Los montos van por acá y no por getInt: getInt trunca los decimales y + // devuelve 0 si el modelo manda el número como texto ("290000"), que es un + // formato que sí usa. El resultado era una factura guardada en 0 mientras + // el bot informaba el monto correcto, porque el bot repite lo que dijo el + // usuario, no lo que se guardó. + getFloat := func(key string, def float64) float64 { + v, ok := a[key] + if !ok { + return def + } + switch x := v.(type) { + case float64: + return x + case int: + return float64(x) + case string: + limpio := strings.NewReplacer("$", "", ",", "", " ", "", "COP", "").Replace(x) + if f, err := strconv.ParseFloat(limpio, 64); err == nil { + return f + } + } + return def + } getStr := func(key string) string { if v, ok := a[key]; ok { if s, ok := v.(string); ok { @@ -652,7 +676,7 @@ func runTool(chatID int64, name string, a map[string]interface{}) (interface{}, ClienteID: clienteID, Numero: getStr("numero"), Descripcion: getStr("descripcion"), - Monto: float64(getInt("monto", 0)), + Monto: getFloat("monto", 0), Estado: "pendiente", FechaEmision: time.Now(), Visible: true, @@ -676,7 +700,7 @@ func runTool(chatID int64, name string, a map[string]interface{}) (interface{}, return map[string]interface{}{"ok": true, "factura_id": f.ID}, nil case "adjuntar_factura_compra": - cp, err := AdjuntarFacturaCompra(chatID, getStr("proveedor"), getStr("descripcion"), float64(getInt("monto", 0))) + cp, err := AdjuntarFacturaCompra(chatID, getStr("proveedor"), getStr("descripcion"), getFloat("monto", 0)) if err != nil { return nil, err } @@ -828,7 +852,7 @@ func runTool(chatID int64, name string, a map[string]interface{}) (interface{}, t := &models.Transaccion{ Tipo: getStr("tipo"), Descripcion: getStr("descripcion"), - Valor: float64(getInt("valor", 0)), + Valor: getFloat("valor", 0), Notas: getStr("notas"), } if err := models.CreateTransaccion(t); err != nil { @@ -851,7 +875,7 @@ func runTool(chatID int64, name string, a map[string]interface{}) (interface{}, cc, doc, err := CrearCuentaCobroConDocumento( uint(getInt("cliente_id", 0)), getStr("descripcion"), - float64(getInt("valor", 0)), + getFloat("valor", 0), nil, getStr("notas"), "telegram", @@ -1567,6 +1591,14 @@ Tienes acceso total al sistema mediante herramientas. Puedes: - Monitorear servidores y URLs COMPORTAMIENTO: +- NUNCA digas que guardaste, creaste, actualizaste o borraste algo si la + herramienta no te devolvió un resultado exitoso. Si devolvió {"error": ...}, + decí exactamente qué falló y qué hace falta para reintentar. Un "guardado + exitosamente" sobre algo que no se guardó es peor que un error: la persona + se entera días después, cuando el registro no aparece. +- Al confirmar que guardaste algo, informá los valores que devolvió la + herramienta (por ejemplo el id), no los que te dijo el usuario: son los que + realmente quedaron en el sistema. - Responde siempre en español, de forma clara y concisa - Usa las herramientas para obtener datos reales antes de responder - Cuando el usuario pida una acción (deploy, renovar, crear), hazla directamente sin pedir confirmación salvo que sea destructiva @@ -1724,6 +1756,10 @@ Comandos: /reset · /instancias · /ayuda`, nil log.Printf("[AGENT] Ejecutando tool: %s args: %s", tc.Function.Name, tc.Function.Arguments) toolResult := executeAgentTool(chatID, tc.Function.Name, toolArgs) + // El resultado también se registra: el modelo puede decir que + // guardó algo aunque la herramienta haya devuelto un error, así que + // el log es la única fuente confiable de qué pasó de verdad. + log.Printf("[AGENT] Resultado de %s: %s", tc.Function.Name, recortar(toolResult, 500)) // Agregar resultado al contexto (solo en memoria, no en BD) messages = append(messages, agentMessage{ @@ -1740,3 +1776,12 @@ Comandos: /reset · /instancias · /ayuda`, nil } return finalResponse, nil } + +// recortar limita lo que se escribe al log: un resultado de tool puede traer +// listados enteros y no vale la pena volcarlos completos. +func recortar(s string, n int) string { + if len(s) <= n { + return s + } + return s[:n] + "…" +}