Saltearse al contenido

Agente de ventas

El Agente de ventas es el módulo agente_wa. La clave conserva el nombre viejo porque es la clave de gating; el nombre que ves en el catálogo es «Agente de ventas». Hoy atiende el chat del sitio; WhatsApp se suma cuando conectas tu número de WhatsApp Business.

Un solo cerebro y varios canales. SalesAgent compone cada turno con la persona, el conocimiento del sitio, el método de venta y la ficha del lead; el historial sale de conversation_messages, sea cual sea el canal.

  • Chat del sitio. WebChatResponder implementa el contrato de núcleo ConversationResponder y lo usa SiteChat.
  • WhatsApp. El webhook de Meta crea el lead y la conversación, llama al mismo cerebro y entrega por WhatsAppSender. También existe simulate, que es «Probar el agente».
  • Captura. Deja el lead con su etapa y dispara LeadCaptured; un lead repetido se deduplica.
  • Medios entrantes. Una nota de voz se transcribe; una foto se describe con visión. Si algo falla, la línea de tiempo conserva (nota de voz recibida) en vez de quedar vacía.
  • Herramientas sobre el lead: move_stage, add_note, draft_quote, propose_message y escalate_to_human. propose_message solo propone: la persona aprueba en el chat de la ficha.
  • El módulo encendido en el sitio. El gate pasa por authorizeModule (sitio → perfil/rol → FeatureAccess). Los sitios internos están exentos y el seeder los enciende.
  • WhatsApp: número de WhatsApp Business, whatsapp_phone_number_id en el sitio, WHATSAPP_VERIFY_TOKEN y WHATSAPP_APP_SECRET.
  • Configuración por sitio: agent_instructions, agent_knowledge y agent_autonomous (por defecto, apagado). Se editan con PUT /sites/{site}/agent, que es solo para el equipo de Merez, o con php artisan site:agent y site:knowledge.
  • IA: el modelo lo elige ModelProviders (DeepSeek y, de respaldo, OpenAI), y cada llamada queda medida en ai_model_calls.
  • Para el aviso de atención humana: la preferencia human_needed encendida y un destinatario.

Con el módulo apagado, un mensaje de WhatsApp entrante no recibe respuesta del bot: la comprobación corta en silencio, porque no hay una petición HTTP del cliente que pueda recibir un 403. El mensaje igual entra al CRM. En el chat del sitio, el agente no contesta. Los endpoints con gate responden 403 y el interruptor aparece bloqueado con Requiere….

Ojo con la otra palanca: con el módulo encendido pero agent_autonomous en false, el agente redacta un borrador y no lo envía, y encola el aviso de que hace falta una persona.

  • No hay validación del texto. agent_instructions y agent_knowledge entran tal cual al prompt; lo que escribas ahí es lo que el agente afirmará, precios incluidos.
  • El precio sí tiene reja. draft_quote pasa por Condor::validateQuote: por debajo del costo, la cotización no se crea. En producto de terceros la única regla dura es «por encima del costo».
  • Etapa ajena. move_stage busca la etapa dentro del sitio del lead; un stage_id de otro sitio se rechaza y el lead queda intacto.
  • El webhook no falla a propósito. Sin phone_number_id no hay forma de saber de qué sitio es el mensaje: solo deja un registro y sigue, sin 404, para no provocar reintentos de Meta.
  • El agente interno por lead se retiró el 2026-10-20; el chat de la ficha hace ese trabajo. Las herramientas siguen vivas.
  • No hay prueba contra un WhatsApp real: el envío saliente está simulado con Http::fake().