feat: NLU routing + audio/image transcription via AI

- NluRouter in AiBot: builds permission-filtered flow catalog, asks AI
  to route user intent to exact flow key or return chat response
- MediaTranscriber: downloads WA media, transcribes audio (Whisper/Gemini),
  extracts image intent (OpenAI/Gemini/Claude vision)
- BotRouter hybrid: text → NormalBot → NLU fallback if no match;
  audio/image → transcribe → NLU route; sends transcript preview first
- Admin IA tab: NLU checkbox with description
- Per-company nlu flag saved in config_json

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-07-04 21:50:01 -05:00
co-authored by Claude Sonnet 4.6
parent 2b859e3dc0
commit 9e36a965c9
5 changed files with 488 additions and 6 deletions
+13
View File
@@ -3142,6 +3142,7 @@ HTML;
$fallbackVal = self::h($config['fallback'] ?? '');
$aiPromptVal = self::h($config['ai_prompt'] ?? '');
$aiForMediaChecked = ($config['ai_for_media'] ?? true) ? 'checked' : '';
$nluChecked = !empty($config['nlu']) ? 'checked' : '';
$aiModelVal = self::h($config['ai_model'] ?? 'gpt-4o-mini');
$aiTempVal = self::h((string)($config['ai_temperature'] ?? 0.7));
$aiProviderVal = self::h($config['ai_provider'] ?? '');
@@ -3731,6 +3732,18 @@ HTML;
Si está desactivado, el bot muestra el menú de categoría directamente.
</div>
</div>
<div class="form-group" style="margin-top:12px;padding:14px;background:#f0f4ff;border:1px solid #c7d7f7;border-radius:10px">
<label style="display:flex;align-items:center;gap:10px;cursor:pointer">
<input type="checkbox" name="nlu" value="1" {$nluChecked}>
<span style="font-weight:700">🧠 Habilitar NLU enrutamiento por IA</span>
</label>
<div style="font-size:11px;color:#4a5568;margin-top:6px;line-height:1.6">
Cuando el usuario escribe algo que el bot no reconoce, la IA lo ubica en el menú o flujo correcto según sus permisos.<br>
Audio transcripción automática (Whisper/Gemini) enrutado.<br>
Imagen la IA extrae el contexto enrutado.<br>
<strong>Requiere bot_type = hybrid y proveedor de IA configurado.</strong>
</div>
</div>
</div>
<!-- ─── GENERAL ──────────────────────────────────────────────────────── -->