feat: OCR y Whisper como herramientas opcionales por canal en uMind
Cada canal (Telegram/WhatsApp) de un agente ahora puede activar, de forma independiente, que los audios entrantes se transcriban con el Whisper ASR propio y que a las imágenes entrantes se les extraiga texto con el servicio OCR propio, antes de pasarle el mensaje al agente. Antes esos mensajes se ignoraban en silencio. - UmindCanal gana usar_whisper_audio/usar_ocr_imagenes (default off). - WhatsApp: se descarga el media vía Graph API (resolución de URL + fetch con el mismo access_token del canal) y se enruta a Whisper/OCR según type. - Telegram: se descarga el archivo vía getFile + CDN de archivos del bot, mismo enrutamiento para voice/audio/photo. - Panel: checkboxes en el alta de canal y toggles inline por canal ya creado, en la tab Canales del agente. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
d493d6dee6
commit
84506a98e2
@@ -463,16 +463,19 @@ func GetUmindCanalesHandler(c *fiber.Ctx) error {
|
||||
out[i] = fiber.Map{
|
||||
"ID": canal.ID, "agente_id": canal.AgenteID, "tipo": canal.Tipo, "activo": canal.Activo,
|
||||
"webhook_url": webhookURL, "ultimo_error": canal.UltimoError,
|
||||
"usar_whisper_audio": canal.UsarWhisperAudio, "usar_ocr_imagenes": canal.UsarOcrImagenes,
|
||||
}
|
||||
}
|
||||
return c.JSON(fiber.Map{"items": out})
|
||||
}
|
||||
|
||||
type umindCanalReq struct {
|
||||
AgenteID uint `json:"agente_id"`
|
||||
Tipo string `json:"tipo"`
|
||||
Credenciales map[string]string `json:"credenciales"`
|
||||
Activo bool `json:"activo"`
|
||||
AgenteID uint `json:"agente_id"`
|
||||
Tipo string `json:"tipo"`
|
||||
Credenciales map[string]string `json:"credenciales"`
|
||||
Activo bool `json:"activo"`
|
||||
UsarWhisperAudio bool `json:"usar_whisper_audio"`
|
||||
UsarOcrImagenes bool `json:"usar_ocr_imagenes"`
|
||||
}
|
||||
|
||||
func CreateUmindCanalHandler(c *fiber.Ctx) error {
|
||||
@@ -502,7 +505,10 @@ func CreateUmindCanalHandler(c *fiber.Ctx) error {
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
canal := &models.UmindCanal{AgenteID: req.AgenteID, Tipo: req.Tipo, Activo: true, CredencialesEnc: credencialesEnc}
|
||||
canal := &models.UmindCanal{
|
||||
AgenteID: req.AgenteID, Tipo: req.Tipo, Activo: true, CredencialesEnc: credencialesEnc,
|
||||
UsarWhisperAudio: req.UsarWhisperAudio, UsarOcrImagenes: req.UsarOcrImagenes,
|
||||
}
|
||||
if err := models.CreateUmindCanal(canal); err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
@@ -525,7 +531,7 @@ func UpdateUmindCanalHandler(c *fiber.Ctx) error {
|
||||
if err := c.BodyParser(&req); err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "body inválido"})
|
||||
}
|
||||
updates := map[string]interface{}{"activo": req.Activo}
|
||||
updates := map[string]interface{}{"activo": req.Activo, "usar_whisper_audio": req.UsarWhisperAudio, "usar_ocr_imagenes": req.UsarOcrImagenes}
|
||||
if len(req.Credenciales) > 0 {
|
||||
enc, err := services.CifrarCredencialesCanal(req.Credenciales)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user