openapi: 3.1.0
info:
  title: WAzion API
  description: |
    WAzion is a WhatsApp Business automation and AI assistant platform. This API exposes
    410 tools via the Model Context Protocol (MCP) over JSON-RPC 2.0, allowing you to
    manage every aspect of your WAzion dashboard programmatically.

    ## Protocol

    All requests use **JSON-RPC 2.0** over a single POST endpoint. The server implements
    the MCP Streamable HTTP transport (spec 2025-03-26).

    ## Authentication

    Include your API token as a Bearer token in the `Authorization` header. You can find
    your token in the WAzion Dashboard under **Settings**.

    ## Quick Start

    ```bash
    curl -X POST https://www.wazion.com/api/mcp/ \
      -H "Content-Type: application/json" \
      -H "Authorization: Bearer YOUR_TOKEN" \
      -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"get_shop_status","arguments":{}},"id":1}'
    ```
  version: 1.1.0
  contact:
    name: WAzion Support
    url: https://www.wazion.com
    email: support@wazion.com
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT

servers:
  - url: https://www.wazion.com/api/mcp
    description: Production

security:
  - bearerAuth: []

tags:
  - name: account
    description: Datos de cuenta y facturacion
  - name: activity
    description: Resumenes de actividad, tendencias y metricas operativas
  - name: advanced
    description: Webhooks, funciones personalizadas, CRM
  - name: agents
    description: Gestion de agentes de atencion
  - name: ai_analysis
    description: Resumenes y analisis de sentimiento con inteligencia artificial
  - name: automation
    description: WhatsApp Auto y workflows de automatizacion
  - name: calendar
    description: Eventos y citas programadas
  - name: conversations
    description: Buscar, ver y analizar conversaciones con clientes
  - name: crm
    description: Gestion de contactos del CRM interno
  - name: customers
    description: Informacion de clientes, comentarios, tags y busqueda
  - name: email
    description: Gestion de cuentas de correo electronico, auto-responder y estadisticas de email
  - name: general
    description: Ajustes basicos del dashboard
  - name: integrations
    description: Conexiones con servicios externos
  - name: knowledge
    description: Gestión de archivos y documentos de la base de conocimiento
  - name: mass_marketing
    description: Campanas masivas por WhatsApp, listas de contactos y configuracion de envios
  - name: notifications
    description: Gestion de notificaciones del sistema
  - name: plugins
    description: Plugins y extensiones
  - name: products
    description: Busqueda de productos y estadisticas de consultas
  - name: prompt
    description: Configuracion del asistente IA
  - name: referrals
    description: Programa de referidos - genera enlaces y consulta ganancias
  - name: smart_followup
    description: Analisis automatico de conversaciones para detectar intencion de compra y enviar seguimientos personalizados
  - name: stats
    description: Metricas y analytics
  - name: storage
    description: Gestion de archivos y almacenamiento
  - name: support
    description: Contacto con soporte tecnico
  - name: tasks
    description: Gestion de tareas y recordatorios asociados a clientes
  - name: tickets
    description: Tickets internos cliente-IA-agente para gestionar escalados sin vigilar WhatsApp manualmente
  - name: voice
    description: Asistente IA que atiende llamadas (telefono y boton web), consulta pedidos y deriva a WhatsApp lo que no se gestione por voz. BYOK Vapi.
  - name: whatsapp_ops
    description: Estado de sesiones, logs de mensajes y ejecucion de workflows

paths:
  /:
    post:
      operationId: jsonRpcRequest
      summary: JSON-RPC 2.0 endpoint
      description: |
        All WAzion API operations go through this single endpoint using JSON-RPC 2.0.

        ### Available methods

        | Method | Auth Required | Description |
        |--------|--------------|-------------|
        | `initialize` | No | MCP handshake |
        | `tools/list` | Yes | List all available tools |
        | `tools/call` | Yes | Execute a tool |
        | `resources/list` | Yes | List available resources |
        | `resources/read` | Yes | Read a resource (e.g. shop://profile) |
        | `ping` | Yes | Health check |

        ### Tool execution

        Use `tools/call` with `params.name` set to the tool name and `params.arguments`
        containing the tool parameters.

        ### Confirmations

        Some destructive actions require confirmation. On the first call, the server
        returns a warning message. Call again with `confirm: true` in the arguments
        to execute.

        ### Batch requests

        You can send an array of JSON-RPC requests for batch processing.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - $ref: '#/components/schemas/JsonRpcRequest'
                - type: array
                  items:
                    $ref: '#/components/schemas/JsonRpcRequest'
            examples:
              initialize:
                summary: MCP handshake
                value:
                  jsonrpc: "2.0"
                  method: initialize
                  params:
                    protocolVersion: "2025-03-26"
                    capabilities: {}
                    clientInfo:
                      name: my-app
                      version: "1.0.0"
                  id: 1

              tools_list:
                summary: List all tools
                value:
                  jsonrpc: "2.0"
                  method: tools/list
                  params: {}
                  id: 2

              send_message:
                summary: Send a WhatsApp message
                value:
                  jsonrpc: "2.0"
                  method: tools/call
                  params:
                    name: send_whatsapp_message
                    arguments:
                      phone: "+34600000000"
                      message: "Hello from WAzion API!"
                      session_id: 1
                  id: 3

              list_conversations:
                summary: List recent conversations
                value:
                  jsonrpc: "2.0"
                  method: tools/call
                  params:
                    name: get_recent_conversations
                    arguments:
                      limit: 10
                  id: 4
      responses:
        '200':
          description: JSON-RPC response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JsonRpcResponse'
        '401':
          description: Missing or invalid Bearer token
        '405':
          description: Method not allowed (only POST accepted)

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: API token from WAzion Dashboard > Settings

  schemas:
    JsonRpcRequest:
      type: object
      required: [jsonrpc, method, id]
      properties:
        jsonrpc:
          type: string
          enum: ["2.0"]
        method:
          type: string
          enum: [initialize, tools/list, tools/call, resources/list, resources/read, ping]
        params:
          type: object
        id:
          oneOf:
            - type: string
            - type: integer

    JsonRpcResponse:
      type: object
      properties:
        jsonrpc:
          type: string
          enum: ["2.0"]
        result:
          description: Success payload (present on success)
        error:
          type: object
          properties:
            code:
              type: integer
            message:
              type: string
            data: {}
          description: Error payload (present on failure)
        id:
          oneOf:
            - type: string
            - type: integer

    # ── Tool Schemas ──────────────────────────────────

    AddAiTicketAgentResolutionArgs:
      description: |
        **add_ai_ticket_agent_resolution** [tickets] (mutation)
        Registra una resolucion interna del agente y encola un seguimiento al cliente. La IA genera el mensaje final al cliente a partir de esta resolucion antes de enviarlo.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        ticket_id:
          type: integer
          description: "ID del ticket"
        body:
          type: string
          description: "Resolucion interna del agente que se usara para generar el mensaje al cliente"
        resolve_after_notify:
          type: boolean
          description: "Si true, marca el ticket como resuelto tras notificar al cliente"
          default: true
      required: ["action", "ticket_id", "body"]

    AddAiTicketNoteArgs:
      description: |
        **add_ai_ticket_note** [tickets] (mutation)
        Anade una nota interna al ticket. No se envia al cliente y puede contener informacion privada para el agente/IA.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        ticket_id:
          type: integer
          description: "ID del ticket"
        body:
          type: string
          description: "Nota interna"
      required: ["action", "ticket_id", "body"]

    AddContactsToListArgs:
      description: |
        **add_contacts_to_list** [mass_marketing] (mutation)
        Añade uno o más contactos a una lista de marketing
      type: object
      properties:
        action:
          type: string
        list_id:
          type: integer
          description: "ID de la lista"
        contacts:
          type: array
          description: "Array de contactos [{phone, name}]"
      required: ["action", "list_id", "contacts"]

    AddCustomerCommentArgs:
      description: |
        **add_customer_comment** [customers] (mutation)
        Anade un nuevo comentario interno a la ficha de un cliente
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        phone:
          type: string
          description: "Numero de telefono del cliente"
        comment:
          type: string
          description: "Texto del comentario"
        agent_name:
          type: string
          description: "Nombre del agente que deja el comentario (default: Assistant)"
          default: "Assistant"
        query:
          type: string
          description: "Texto de busqueda"
        limit:
          type: integer
          description: "Maximo de resultados"
        tag_name:
          type: string
          description: "Nombre del tag"
        tag_color:
          type: string
          description: "Color del tag en formato hexadecimal"
        primary_phone:
          type: string
          description: "Telefono principal para merge"
        secondary_phone:
          type: string
          description: "Telefono secundario para merge"
      required: ["action", "phone", "comment"]

    AddCustomerTagArgs:
      description: |
        **add_customer_tag** [customers] (mutation)
        Anade una etiqueta (tag) a un cliente para clasificarlo
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        phone:
          type: string
          description: "Numero de telefono del cliente"
        tag_name:
          type: string
          description: "Nombre del tag"
        tag_color:
          type: string
          description: "Color del tag en hex (default: #2563eb)"
          default: "#2563eb"
        comment:
          type: string
          description: "Texto del comentario"
        agent_name:
          type: string
          description: "Nombre del agente"
        query:
          type: string
          description: "Texto de busqueda"
        limit:
          type: integer
          description: "Maximo de resultados"
        primary_phone:
          type: string
          description: "Telefono principal para merge"
        secondary_phone:
          type: string
          description: "Telefono secundario para merge"
      required: ["action", "phone", "tag_name"]

    AddEmailNoteArgs:
      description: |
        **add_email_note** [email] (mutation)
        Agrega una nota interna a un hilo de email. Solo visible para agentes.
      type: object
      properties:
        action:
          type: string
          description: "Debe ser 'add'"
        thread_id:
          type: integer
          description: "ID del hilo"
        note_text:
          type: string
          description: "Texto de la nota"
        agent_name:
          type: string
          description: "Nombre del agente"
        agent_color:
          type: string
          description: "Color del agente"
        avatar_url:
          type: string
          description: "URL del avatar del agente"
      required: ["action", "thread_id", "note_text"]

    AddToBlacklistArgs:
      description: |
        **add_to_blacklist** [mass_marketing] (mutation)
        Bloquea un numero de telefono para que no reciba campanas de marketing masivo
      type: object
      properties:
        action:
          type: string
          description: "Accion fija: add"
        phone:
          type: string
          description: "Numero de telefono a bloquear (con prefijo internacional, ej: +34612345678)"
        reason:
          type: string
          description: "Motivo del bloqueo (opcional, max 500 caracteres)"
      required: ["action", "phone"]

    AddWhatsappOptoutArgs:
      description: |
        **add_whatsapp_optout** [whatsapp_ops] (mutation)
        Anade un numero a la lista de opt-out para que no reciba mensajes automaticos
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        phone:
          type: string
          description: "Numero de telefono con prefijo internacional"
        reason:
          type: string
          description: "Motivo del opt-out"
      required: ["action", "phone"]

    ApplyPromptInstructionArgs:
      description: |
        **apply_prompt_instruction** [prompt] (query)
        Modifica el prompt existente segun una instruccion en lenguaje natural. ESTA ES LA ACCION CORRECTA cuando el usuario quiere añadir, cambiar o quitar algo del prompt (ej: 'add a rule about...', 'anade horario', 'add a shop-level rule', 'quita la parte de devoluciones', 'hazlo mas formal'). NO guarda los cambios - solo devuelve el prompt modificado como preview. Despues de obtener el resultado, DEBES llamar a save_prompt para guardar los cambios.
      type: object
      properties:
        prompt:
          type: string
          description: "El prompt a modificar. Si no se proporciona, el endpoint lee automaticamente el prompt actual de la tienda. No es necesario llamar a get_prompt primero."
        instruction:
          type: string
          description: "La instruccion de que modificar en el prompt"
      required: ["instruction"]

    ApplyTrainingSuggestionArgs:
      description: |
        **apply_training_suggestion** [knowledge] (mutation)
        Aplica una sugerencia de entrenamiento de IA. Segun el nivel, crea un snippet de conocimiento o actualiza el prompt del asistente.
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
        suggestion_id:
          type: integer
          description: "ID de la sugerencia a aplicar"
      required: ["action", "suggestion_id"]

    ApproveCampaignArgs:
      description: |
        **approve_campaign** [mass_marketing] (mutation)
        Aprueba una campaña pendiente de aprobación para que pueda ser enviada
      type: object
      properties:
        action:
          type: string
        campaign_id:
          type: integer
          description: "ID de la campaña a aprobar"
      required: ["action", "campaign_id"]

    ApproveKnowledgeSnippetArgs:
      description: |
        **approve_knowledge_snippet** [knowledge] (mutation)
        Aprueba un snippet de conocimiento pendiente y lo activa
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        id:
          type: integer
          description: "ID del snippet a aprobar"
      required: ["action", "id"]

    ArchiveCampaignArgs:
      description: |
        **archive_campaign** [mass_marketing] (mutation)
        Archiva una campaña completada para mantener la lista limpia
      type: object
      properties:
        action:
          type: string
        campaign_id:
          type: integer
          description: "ID de la campaña a archivar"
      required: ["action", "campaign_id"]

    ArchiveWhatsappChatArgs:
      description: |
        **archive_whatsapp_chat** [whatsapp_ops] (mutation)
        Archiva o desarchiva un chat de WhatsApp indicando solo el telefono. La API resuelve automaticamente la sesion conectada, el session_key y las identidades internas de WhatsApp.
      type: object
      properties:
        action:
          type: string
        phone:
          type: string
          description: "Telefono del chat a archivar/desarchivar en formato E.164 o con prefijo internacional (ej: +34612345678). OBLIGATORIO"
        archive:
          type: boolean
          description: "true para archivar, false para desarchivar. Por defecto true"
        session_id:
          type: integer
          description: "ID de sesion especifica (opcional). Si se omite, la API usa la sesion conectada mas reciente para ese telefono o la primera conectada"
      required: ["action", "phone"]

    AssignAiTicketArgs:
      description: |
        **assign_ai_ticket** [tickets] (mutation)
        Asigna un ticket interno a un agente.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        ticket_id:
          type: integer
          description: "ID del ticket"
        assigned_agent_id:
          type: integer
          description: "ID del agente asignado. Usa 0 para desasignar"
      required: ["action", "ticket_id", "assigned_agent_id"]

    AssignCalendarAgentArgs:
      description: |
        **assign_calendar_agent** [calendar] (mutation)
        Asigna un agente a un calendario con un rol especifico
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        calendar_id:
          type: integer
          description: "ID del calendario"
        agent_id:
          type: integer
          description: "ID del agente"
        role:
          type: string
          description: "Rol: owner, can_book, view_only"
      required: ["action", "calendar_id", "agent_id"]

    AssignEmailThreadArgs:
      description: |
        **assign_email_thread** [email] (mutation)
        Asigna un hilo de email a un agente especifico. Usar assign_to=null para desasignar.
      type: object
      properties:
        action:
          type: string
          description: "Debe ser 'assign'"
        thread_id:
          type: integer
          description: "ID del hilo"
        assign_to:
          type: integer
          description: "ID del agente (shop_agents.id). Omitir o null para desasignar."
        agent_hash:
          type: string
          description: "Hash del agente a asignar (null para desasignar)"
      required: ["action", "thread_id"]

    AssignMarketingSessionArgs:
      description: |
        **assign_marketing_session** [mass_marketing] (mutation)
        Habilita o deshabilita una sesión de WhatsApp para envío de campañas de marketing
      type: object
      properties:
        action:
          type: string
        session_id:
          type: integer
          description: "ID de la sesión WhatsApp"
        enable_mass_marketing:
          type: boolean
          description: "true para habilitar, false para deshabilitar"
      required: ["action", "session_id", "enable_mass_marketing"]

    AutoCategorizeConversationsArgs:
      description: |
        **auto_categorize_conversations** [ai_analysis] (query)
        Categoriza conversaciones recientes por tema, intento y prioridad usando IA
      type: object
      properties:
        action:
          type: string
        hours:
          type: integer
          description: "Horas a analizar (default 24)"
        limit:
          type: integer
          description: "Conversaciones a categorizar (default 10, max 20)"
        phone:
          type: string
          description: "Filtrar por telefono del cliente"
        summary_type:
          type: string
          description: "Tipo de resumen: quick (rapido), actionable (con acciones), detailed (detallado)"
          enum: ["quick", "actionable", "detailed"]
        days:
          type: integer
          description: "Numero de dias a analizar"
        tone:
          type: string
          description: "Tono para la respuesta"
        target_language:
          type: string
          description: "Idioma destino para traduccion"
        last_n:
          type: integer
          description: "Ultimos N mensajes a procesar"
      required: ["action"]

    AutoTagCustomerArgs:
      description: |
        **auto_tag_customer** [ai_analysis] (query)
        Analiza la conversacion con IA y sugiere tags relevantes para el cliente
      type: object
      properties:
        action:
          type: string
        phone:
          type: string
          description: "Telefono del cliente"
        summary_type:
          type: string
          description: "Tipo de resumen: quick (rapido), actionable (con acciones), detailed (detallado)"
          enum: ["quick", "actionable", "detailed"]
        days:
          type: integer
          description: "Numero de dias a analizar"
        tone:
          type: string
          description: "Tono para la respuesta"
        hours:
          type: integer
          description: "Ultimas N horas a analizar"
        limit:
          type: integer
          description: "Maximo de resultados"
        target_language:
          type: string
          description: "Idioma destino para traduccion"
        last_n:
          type: integer
          description: "Ultimos N mensajes a procesar"
      required: ["action", "phone"]

    BackfillEmailPhonesArgs:
      description: |
        **backfill_email_phones** [email] (mutation)
        Procesa hasta 50 hilos de email sin telefono asociado e intenta resolver el contacto a partir de la direccion del remitente, consultando CRM, plataforma e-commerce y mappings cacheados. Util tras conectar una plataforma o anadir contactos al CRM.
      type: object
      properties:
        action:
          type: string
          description: "Debe ser 'backfill_phones'"
      required: ["action"]

    BulkAddToBlacklistArgs:
      description: |
        **bulk_add_to_blacklist** [mass_marketing] (mutation)
        Añade varios números de teléfono a la lista negra de marketing masivo de una vez
      type: object
      properties:
        action:
          type: string
        phones:
          type: array
          description: "Array de números de teléfono a añadir a la lista negra"
        reason:
          type: string
          description: "Motivo de la inclusión en la lista negra"
      required: ["action", "phones"]

    BulkDeleteWorkflowsArgs:
      description: |
        **bulk_delete_workflows** [automation] (mutation)
        Elimina multiples workflows de WhatsApp a la vez. OBLIGATORIO: Antes de llamar, usa list_whatsapp_workflows para obtener los workflows y confirma con el usuario la lista EXACTA de nombres e IDs a eliminar. NUNCA eliminar workflows sin confirmacion explicita del usuario sobre cuales borrar. Si el usuario dice 'limpieza maxima' o similar, listar primero los workflows y preguntar cuales quiere eliminar (todos, solo los desactivados, etc.). FLUJO DE CONFIRMACION OBLIGATORIO: Esta accion devolvera success=false con requires_confirmation=true — esto NO es un error, es el paso 1 del flujo normal. Cuando recibas esta respuesta: 1) Describe brevemente los workflows que se eliminaran, 2) PARA completamente, 3) NUNCA vuelvas a llamar a esta misma accion — hacerlo INVALIDA el token de confirmacion y rompe el flujo. Los botones aparecen automaticamente.
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
        workflow_ids:
          type: array
          description: "Array de IDs de workflows a eliminar"
      required: ["action", "workflow_ids"]

    BulkToggleWorkflowsArgs:
      description: |
        **bulk_toggle_workflows** [automation] (mutation)
        Activa o desactiva multiples workflows a la vez
      type: object
      properties:
        action:
          type: string
        workflow_ids:
          type: array
          description: "Array de IDs de workflows"
        enabled:
          type: boolean
          description: "true para activar, false para desactivar"
      required: ["action", "workflow_ids", "enabled"]

    CancelCampaignArgs:
      description: |
        **cancel_campaign** [mass_marketing] (mutation)
        Cancela definitivamente una campana de marketing masivo (en curso, pausada, borrador o programada). Los mensajes ya enviados no se deshacen.
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
          description: "Accion fija: cancel"
        campaign_id:
          type: integer
          description: "ID de la campana a cancelar"
      required: ["action", "campaign_id"]

    CancelCampaignScheduleArgs:
      description: |
        **cancel_campaign_schedule** [mass_marketing] (mutation)
        Cancela la programacion de una campana programada, cambiandola a estado borrador. No elimina la campana.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija: cancel_schedule"
        campaign_id:
          type: integer
          description: "ID de la campana programada"
      required: ["action", "campaign_id"]

    CancelScheduledEmailArgs:
      description: |
        **cancel_scheduled_email** [email] (mutation)
        Cancela un email que estaba programado para enviarse. El email se elimina.
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
          description: "Debe ser 'cancel_scheduled'"
        message_id:
          type: integer
          description: "ID del mensaje programado a cancelar"
        to:
          type: string
          description: "Destinatario del email"
        subject:
          type: string
          description: "Asunto del email"
        body_text:
          type: string
          description: "Cuerpo en texto plano"
        cc:
          type: array
          description: "Copia a (array de emails)"
        bcc:
          type: array
          description: "Copia oculta (array de emails)"
        account_id:
          type: integer
          description: "ID de la cuenta de email"
        attachment_ids:
          type: array
          description: "IDs de adjuntos"
        scheduled_at:
          type: string
          description: "Fecha programada"
      required: ["action", "message_id"]

    CancelScheduledMessageArgs:
      description: |
        **cancel_scheduled_message** [whatsapp_ops] (mutation)
        Cancela un mensaje de WhatsApp que esta programado para envio futuro
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        id:
          type: integer
          description: "ID del mensaje programado a cancelar"
        agent_id:
          type: integer
          description: "ID del agente que cancela el mensaje"
      required: ["action", "id"]

    CheckDocqaFileStatusArgs:
      description: |
        **check_docqa_file_status** [plugins] (query)
        Comprueba el estado de procesamiento de los archivos subidos a un asistente Doc-QA
      type: object
      properties:
        assistant_id:
          type: integer
          description: "ID del asistente Doc-QA"
      required: ["assistant_id"]

    CheckPluginConversationNoteArgs:
      description: |
        **check_plugin_conversation_note** [plugins] (query)
        Comprueba si ya existe una nota guardada para una sesion de chat del plugin y muestra los datos del cliente asociado.
      type: object
      properties:
        session_id:
          type: string
          description: "ID de la sesion de chat del plugin"
      required: ["session_id"]

    CheckWhatsappContactEligibilityArgs:
      description: |
        **check_whatsapp_contact_eligibility** [whatsapp_ops] (query)
        Comprueba sin enviar nada si el cliente ha escrito recientemente a la misma linea fisica que usaria el origen automatico. Devuelve tambien el estado del filtro y la ventana configurada.
      type: object
      properties:
        action:
          type: string
        phone:
          type: string
          description: "Telefono del cliente en formato E.164."
        billing_source:
          type: string
          description: "Origen automatico que intentaria enviar el mensaje."
          enum: ["order_automation", "shopify_order", "parts_progress", "recambios_envia_event", "campaign", "followup"]
        sender_role:
          type: string
          description: "Rol logico solicitado; WAzion resuelve despues la linea fisica."
          enum: ["general", "operations", "marketing"]
      required: ["action", "phone", "billing_source"]

    CheckWhatsappOptoutArgs:
      description: |
        **check_whatsapp_optout** [whatsapp_ops] (query)
        Comprueba si un numero de telefono esta en la lista de opt-out de automatizacion WhatsApp
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        phone:
          type: string
          description: "Numero de telefono a verificar (con prefijo internacional)"
      required: ["action", "phone"]

    CloseAiTicketArgs:
      description: |
        **close_ai_ticket** [tickets] (mutation)
        Cierra un ticket interno cuando el caso queda terminado. A diferencia de resolver, marca el ticket como cerrado definitivamente.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        ticket_id:
          type: integer
          description: "ID del ticket"
        reason:
          type: string
          description: "Motivo interno del cierre"
      required: ["action", "ticket_id"]

    ConfigureAiLearningArgs:
      description: |
        **configure_ai_learning** [prompt] (mutation)
        Configura el modo de despliegue del aprendizaje automatico para un canal concreto (off, sombra, suave, forzado), cuantas reglas se aplican como maximo y que categorias estan habilitadas o forzadas.
      type: object
      properties:
        action:
          type: string
        surface:
          type: string
          description: "Canal al que aplica la configuracion (all=todos, chatgpt, whatsapp_workflow, ticket, plugin_chat, email, voice, dashboard)"
          enum: ["all", "chatgpt", "whatsapp_workflow", "ticket", "plugin_chat", "email", "voice", "dashboard"]
        mode:
          type: string
          description: "Modo de despliegue: off=desactivado, shadow=solo observa, soft=sugiere, enforced=aplica las reglas"
          enum: ["off", "shadow", "soft", "enforced"]
          default: "shadow"
        max_rules:
          type: integer
          description: "Numero maximo de reglas que se aplican (entre 1 y 12)"
          default: 5
        enabled_categories:
          type: array
          description: "Lista de categorias de reglas habilitadas para este canal"
        enforced_categories:
          type: array
          description: "Lista de categorias de reglas que se aplican de forma forzada en este canal"
      required: ["action", "surface"]

    ConfigureEcommerceLocalesArgs:
      description: |
        **configure_ecommerce_locales** [integrations] (mutation)
        Configura como se manejan los idiomas y URLs de tu plataforma e-commerce
      type: object
      properties:
        shopify_locale_mode:
          type: string
          description: "Modo de URLs: auto detecta por mercado, fixed usa un idioma fijo"
          enum: ["auto", "fixed"]
          default: "auto"
        shopify_fixed_locale:
          type: string
          description: "Idioma fijo para URLs (solo si locale_mode es fixed)"
        shopify_content_locale_mode:
          type: string
          description: "Modo de contenido: auto o fijo"
          enum: ["auto", "fixed"]
          default: "auto"
        shopify_content_fixed_locale:
          type: string
          description: "Idioma fijo para contenido"
        shopify_fallback_locale:
          type: string
          description: "Idioma por defecto cuando no se puede detectar"

    ConfigurePluginChatArgs:
      description: |
        **configure_plugin_chat** [plugins] (mutation)
        Configura el widget de chat web. Soporta actualizacion parcial: solo envia los campos que quieras cambiar. Los campos JSON (config_design, config_texts, config_behavior) se mergean automaticamente con los valores existentes, puedes enviar solo los sub-campos que quieras modificar.
      type: object
      properties:
        plugin_type:
          type: string
          default: "chat"
        is_enabled:
          type: boolean
          description: "true para activar el plugin, false para desactivar"
        allowed_domains:
          type: array
          description: "Lista de dominios donde funcionara el chat (ej: ["tutienda.com", "www.tutienda.com"]). Vacio [] para permitir todos."
        config_design:
          type: object
          description: "Configuracion visual del widget. Se mergea con valores existentes: puedes enviar solo lo que quieras cambiar."
        config_texts:
          type: object
          description: "Textos del widget. Se mergea con valores existentes: puedes enviar solo lo que quieras cambiar."
        config_behavior:
          type: object
          description: "Comportamiento del widget. Se mergea con valores existentes: puedes enviar solo lo que quieras cambiar."
        avatar_url:
          type: string
          description: "URL de la imagen avatar del asistente en el chat"
        language_mode:
          type: string
          description: "'auto' detecta el idioma del visitante, 'fixed' responde siempre en el idioma configurado"
          enum: ["auto", "fixed"]
        language_fixed:
          type: string
          description: "Idioma fijo (solo aplica si language_mode es 'fixed')"
          enum: ["es", "en", "de", "fr", "pt", "it", "hu"]
        language_available:
          type: array
          description: "Lista de idiomas disponibles (ej: ["es", "en", "de"])"
        language_show_selector:
          type: boolean
          description: "Mostrar selector de idioma en el widget"
        rate_limit_per_session:
          type: integer
          description: "Maximo de mensajes por sesion (default: 30)"
        rate_limit_window_minutes:
          type: integer
          description: "Ventana de tiempo en minutos para el rate limit (default: 60)"
        require_verification:
          type: boolean
          description: "Requiere verificacion del visitante antes de chatear"
        custom_css:
          type: string
          description: "CSS personalizado para inyectar en el widget"
      required: ["plugin_type"]

    ConfigurePluginProductqaArgs:
      description: |
        **configure_plugin_productqa** [plugins] (mutation)
        Activa y configura el widget de preguntas sobre productos
      type: object
      properties:
        plugin_type:
          type: string
          default: "product-qa"
        is_enabled:
          type: boolean
          description: "true para activar el plugin"
        allowed_domains:
          type: string
          description: "Dominios donde funcionara el widget"
        faq_enabled:
          type: boolean
          description: "Publicar FAQs automaticamente en tu tienda online"
        faq_max_per_product:
          type: integer
          description: "Maximo de FAQs por producto"
          default: 5
      required: ["plugin_type", "is_enabled"]

    ConfigureWebhooksArgs:
      description: |
        **configure_webhooks** [advanced] (mutation)
        Modifica la configuracion de webhooks. ACTUALIZACION PARCIAL: solo se modifican los campos que envies; los que omitas (webhook_url, webhook_secret, webhook_events) conservan su valor actual en la base de datos. EXCEPCION CRITICA: webhook_events es REEMPLAZO COMPLETO, no merge incremental. Si el usuario pide AÑADIR o QUITAR eventos sin sustituir el resto, DEBES: (1) llamar get_webhook_config primero para obtener la lista actual, (2) calcular tu mismo la nueva lista (actual + nuevos, o actual - eliminados), (3) enviar webhook_events con la lista COMPLETA resultante. Si envias solo los nuevos eventos, perderas los anteriores. FLUJO DE CONFIRMACION: tras llamar esta accion el sistema mostrara botones de confirmacion al usuario - NO vuelvas a llamar la accion ni pidas confirmacion por texto; el sistema completa el flujo automaticamente cuando el usuario pulsa el boton. Antes de llamar, resume al usuario en lenguaje natural los cambios concretos que vas a aplicar.
        ⚠️ Requires confirmation
      type: object
      properties:
        webhook_enabled:
          type: boolean
          description: "true para activar webhooks, false para desactivarlos. Si solo cambias eventos/URL/secret y los webhooks ya estan activos, envia true para mantenerlos activos."
        webhook_url:
          type: string
          description: "URL HTTPS del endpoint que recibira los webhooks. Omite este campo si no quieres cambiar la URL actual."
        webhook_secret:
          type: string
          description: "Secret para firmar los webhooks con HMAC-SHA256. Omite este campo si no quieres cambiar el secret actual."
        webhook_events:
          type: array
          description: "Lista COMPLETA de eventos a suscribir. Reemplaza la lista existente, no hace merge. Para añadir/quitar eventos sin perder los demas: llama primero a get_webhook_config y envia la lista completa resultante (existentes + nuevos, o existentes - eliminados). Omite este campo si no quieres cambiar los eventos."
      required: ["webhook_enabled"]

    ConnectEcommerceArgs:
      description: |
        **connect_ecommerce** [integrations] (mutation)
        Conecta tu tienda online (Shopify, WooCommerce, PrestaShop o VTEX) para buscar productos, pedidos y clientes. Pregunta al usuario que plataforma usa.
        ⚠️ Requires confirmation
      type: object
      properties:
        platform_type:
          type: string
          description: "Plataforma e-commerce: shopify, woocommerce, prestashop o vtex"
          enum: ["shopify", "woocommerce", "prestashop", "vtex"]
        shopify_url:
          type: string
          description: "Shopify: URL de la tienda (ej: mitienda.myshopify.com)"
        shopify_token:
          type: string
          description: "Shopify: Token de acceso de la app personalizada"
        wc_store_url:
          type: string
          description: "Solo WooCommerce: URL de la tienda (ej: mitienda.com)"
        wc_consumer_key:
          type: string
          description: "Solo WooCommerce: Consumer Key de la API REST"
        wc_consumer_secret:
          type: string
          description: "Solo WooCommerce: Consumer Secret de la API REST"
        ps_store_url:
          type: string
          description: "Solo PrestaShop: URL de la tienda (ej: mitienda.com)"
        ps_api_key:
          type: string
          description: "Solo PrestaShop: API Key del Webservice"
        vtex_account_name:
          type: string
          description: "Solo VTEX: Nombre de la cuenta VTEX"
        vtex_app_key:
          type: string
          description: "Solo VTEX: App Key de la API"
        vtex_app_token:
          type: string
          description: "Solo VTEX: App Token de la API"
        vtex_store_url:
          type: string
          description: "Solo VTEX: URL de la tienda (opcional, se genera automaticamente si no se proporciona)"
        platform_enabled:
          type: string
          description: "Activar/desactivar plataforma"
        shopify_locale_mode:
          type: string
          description: "Modo de locale (auto/fixed)"
        shopify_fixed_locale:
          type: string
          description: "Locale fijo para Shopify"
        shopify_content_locale_mode:
          type: string
          description: "Modo de locale para contenido"
        shopify_content_fixed_locale:
          type: string
          description: "Locale fijo para contenido"
        shopify_fallback_locale:
          type: string
          description: "Locale de fallback"
      required: ["platform_type"]

    ConnectWhatsappArgs:
      description: |
        **connect_whatsapp** [whatsapp_ops] (mutation)
        Inicia la conexión de un nuevo número y asigna uno o varios roles lógicos. Una tienda con un solo número puede usarlo para General, Operaciones y Marketing; con varios números puede repartir o combinar roles.
      type: object
      properties:
        label:
          type: string
          description: "Etiqueta para identificar la sesión (máximo 50 caracteres)"
        force_new:
          type: boolean
          description: "Forzar creación de nueva sesión aunque haya sesiones desconectadas disponibles"
        routing_roles:
          type: array
          description: "Roles del número: general (conversaciones/destino público), operations (avisos y pedidos) y/o marketing (campañas). Si es el primer número y se omite, se asignan los tres; los siguientes nacen como Operaciones."

    CountFilteredContactsArgs:
      description: |
        **count_filtered_contacts** [mass_marketing] (query)
        Cuenta cuantos contactos de una lista cumplen con filtros de segmentacion (tags, actividad reciente, historial WhatsApp)
      type: object
      properties:
        action:
          type: string
          description: "Accion fija: count_filtered"
        list_id:
          type: integer
          description: "ID de la lista de contactos"
        segment_filters:
          type: string
          description: "Filtros en formato JSON. Claves: tags (array), last_contact_days (entero), has_whatsapp_history (boolean)"
      required: ["action", "list_id", "segment_filters"]

    CreateAgentArgs:
      description: |
        **create_agent** [agents] (mutation)
        Crea un nuevo agente de atencion. PREFLIGHT OBLIGATORIO: antes de llamar a esta accion, llama PRIMERO a list_agents para confirmar que hay cupo disponible (compara count con el limite del plan, que tambien viene en el campo buy_agents de get_shop_status). Si ya estan al limite, NO intentes crear: en su lugar, lista los agentes existentes al usuario y ofrece dos alternativas accionables — (a) eliminar un agente existente con delete_agent para liberar un slot, o (b) ampliar el plan desde https://www.wazion.com/dashboard/buy_agents. Si aun asi llamas a esta accion y recibes error_code=agent_limit_reached, la respuesta incluye current_count y max_allowed: muestra esos numeros al usuario y ofrece las mismas dos alternativas (eliminar o ampliar). NUNCA reintentes create_agent tras un agent_limit_reached sin que el usuario haya eliminado un agente primero.
      type: object
      properties:
        action:
          type: string
        nickname:
          type: string
          description: "Nombre corto del agente (lo veran los clientes)"
        full_name:
          type: string
          description: "Nombre completo del agente"
        email:
          type: string
          description: "Email del agente"
        color:
          type: string
          description: "Color en formato hexadecimal"
          default: "#2563eb"
        phone:
          type: string
          description: "Telefono del agente"
        pin:
          type: string
          description: "PIN numerico para que el agente se identifique en la extension de Chrome"
        permissions_json:
          type: string
          description: "Permisos iniciales del agente en formato JSON. Si no se proporciona, el agente tendra todos los permisos por defecto"
        permissions:
          type: object
          description: "Permisos del agente (objeto JSON con permisos por seccion)"
      required: ["action", "nickname", "full_name", "email"]

    CreateAiTicketArgs:
      description: |
        **create_ai_ticket** [tickets] (mutation)
        Crea o actualiza un ticket interno para un cliente. No envia nada al cliente. El contenido de message/internal_note queda como nota interna IA-agente.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        phone:
          type: string
          description: "Telefono del cliente"
        customer_email:
          type: string
          description: "Email del cliente si no hay telefono"
        title:
          type: string
          description: "Titulo breve del ticket"
        description:
          type: string
          description: "Descripcion interna del caso"
        priority:
          type: string
          description: "Prioridad interna"
          enum: ["P0", "P1", "P2", "P3"]
        category:
          type: string
          description: "Categoria interna"
        message:
          type: string
          description: "Nota interna inicial. No se envia al cliente"
        dedupe_customer:
          type: boolean
          description: "Si true, actualiza un ticket abierto del mismo cliente en vez de crear otro"
      required: ["action", "title"]

    CreateCalendarAvailabilityArgs:
      description: |
        **create_calendar_availability** [calendar] (mutation)
        Crea una regla de disponibilidad en un calendario (semanal, excepcion por fecha, bloqueo)
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        calendar_id:
          type: integer
          description: "ID del calendario"
        rule_type:
          type: string
          description: "Tipo: weekly, date_exception, blocked"
        day_of_week:
          type: integer
          description: "Dia de la semana (0-6, para weekly)"
        specific_date:
          type: string
          description: "Fecha especifica YYYY-MM-DD (para date_exception)"
        start_time:
          type: string
          description: "Hora inicio HH:MM"
        end_time:
          type: string
          description: "Hora fin HH:MM"
        label:
          type: string
          description: "Etiqueta descriptiva"
        is_available:
          type: boolean
          description: "Si esta disponible (true) o bloqueado (false)"
      required: ["action", "calendar_id", "rule_type", "start_time", "end_time"]

    CreateCalendarEventArgs:
      description: |
        **create_calendar_event** [calendar] (mutation)
        Agenda un nuevo evento o cita en el calendario
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        title:
          type: string
          description: "Titulo del evento"
        start_datetime:
          type: string
          description: "Fecha y hora de inicio (YYYY-MM-DD HH:MM:SS)"
        end_datetime:
          type: string
          description: "Fecha y hora de fin"
        description:
          type: string
        phone:
          type: string
          description: "Telefono del cliente relacionado"
        assigned_agent_id:
          type: integer
          description: "Agente asignado al evento"
        all_day:
          type: integer
          enum: [0, 1]
          default: 0
        date_from:
          type: string
          description: "Fecha inicio para filtrar"
        date_to:
          type: string
          description: "Fecha fin para filtrar"
        agent_id:
          type: integer
          description: "ID del agente"
        event_id:
          type: integer
          description: "ID del evento"
      required: ["action", "title", "start_datetime"]

    CreateCalendarNotificationArgs:
      description: |
        **create_calendar_notification** [calendar] (mutation)
        Crea una notificacion automatica para un calendario (confirmacion, recordatorio, cancelacion, seguimiento, no-show)
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        calendar_id:
          type: integer
          description: "ID del calendario"
        notification_type:
          type: string
          description: "Tipo: confirmation, reminder, cancellation, follow_up, no_show"
        channel:
          type: string
          description: "Canal: whatsapp, email, both"
        timing_minutes:
          type: integer
          description: "Minutos antes/despues del evento"
        template_text:
          type: string
          description: "Texto de la notificacion"
        is_enabled:
          type: boolean
          description: "Si esta habilitada"
      required: ["action", "calendar_id", "notification_type", "channel", "timing_minutes", "template_text"]

    CreateCalendarServiceArgs:
      description: |
        **create_calendar_service** [calendar] (mutation)
        Crea un tipo de cita/servicio para un calendario (ej: consulta 30min, reunion 60min)
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        calendar_id:
          type: integer
          description: "ID del calendario"
        name:
          type: string
          description: "Nombre del servicio"
        duration_minutes:
          type: integer
          description: "Duracion en minutos"
        description:
          type: string
          description: "Descripcion del servicio"
        buffer_before_minutes:
          type: integer
          description: "Minutos de buffer antes"
        buffer_after_minutes:
          type: integer
          description: "Minutos de buffer despues"
        max_concurrent:
          type: integer
          description: "Maximo de citas concurrentes"
        price:
          type: string
          description: "Precio del servicio"
        currency:
          type: string
          description: "Moneda (EUR, USD, etc.)"
        requires_confirmation:
          type: boolean
          description: "Si requiere confirmacion del negocio"
      required: ["action", "calendar_id", "name", "duration_minutes"]

    CreateCampaignArgs:
      description: |
        **create_campaign** [mass_marketing] (mutation)
        Crea una nueva campana de marketing masivo. Puede crearse como borrador o programarse para una fecha futura. Soporta variables de plantilla {nombre}, {telefono}, {tienda} en el mensaje.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija: create"
        name:
          type: string
          description: "Nombre de la campana"
        message_text:
          type: string
          description: "Texto del mensaje. Soporta variables: {nombre} (nombre del contacto), {telefono} (telefono del contacto), {tienda} (nombre de la tienda)"
        list_id:
          type: integer
          description: "ID de la lista de contactos a usar para esta campana"
        send_interval_seconds:
          type: integer
          description: "Segundos entre cada envio (minimo 10, por defecto 30)"
          default: 30
        translate_by_prefix:
          type: boolean
          description: "Si true, traduce el mensaje al idioma del destinatario segun prefijo telefonico"
          default: false
        include_unsubscribe_link:
          type: boolean
          description: "Si true, anade un enlace de baja al final del mensaje"
          default: true
        archive_after_send:
          type: boolean
          description: "Si true, archiva tras enviar solo chats que no estaban activos antes del envio; las conversaciones activas se mantienen visibles."
          default: false
        session_ids:
          type: array
          description: "Array de IDs de sesion de WhatsApp a usar para enviar. Si no se especifica, usa todas las sesiones habilitadas para marketing masivo. Usa get_whatsapp_status para ver los IDs."
        scheduled_at:
          type: string
          description: "Fecha y hora para programar el envio (formato: YYYY-MM-DD HH:MM:SS). Debe ser una fecha futura. Si se especifica, la campana se crea con estado 'scheduled' en vez de 'draft'."
        segment_filters:
          type: object
          description: "Filtros de segmentacion para enviar solo a contactos que cumplan criterios. Objeto con claves opcionales: tags (array de nombres de tags), last_contact_days (entero, enviar solo a contactos con actividad en los ultimos N dias), has_whatsapp_history (boolean, enviar solo a contactos con historial de WhatsApp)"
        media_url:
          type: string
          description: "URL del archivo multimedia a enviar con el mensaje (imagen, video, documento). Debe ser una URL publica accesible."
        media_type:
          type: string
          description: "Tipo de multimedia: 'image', 'video' o 'document'. Requerido si se especifica media_url."
        media_filename:
          type: string
          description: "Nombre del archivo multimedia. Requerido para tipo 'document'."
        is_recurring:
          type: boolean
          description: "Si true, la campana se ejecuta de forma recurrente segun recurring_cron"
        recurring_cron:
          type: string
          description: "Expresion cron para campanas recurrentes (ej: '0 10 * * 1' para cada lunes a las 10:00). Requerido si is_recurring es true."
      required: ["action", "name", "message_text", "list_id"]

    CreateContactListArgs:
      description: |
        **create_contact_list** [mass_marketing] (mutation)
        Crea una nueva lista de contactos para campanas de marketing masivo
      type: object
      properties:
        action:
          type: string
          description: "Accion fija: create"
        name:
          type: string
          description: "Nombre de la lista de contactos"
        description:
          type: string
          description: "Descripcion opcional de la lista"
      required: ["action", "name"]

    CreateCrmCustomerArgs:
      description: |
        **create_crm_customer** [crm] (mutation)
        Crea un nuevo contacto en el CRM interno de WAzion
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        whatsapp_number:
          type: string
          description: "Numero de WhatsApp del contacto (con prefijo +)"
      required: ["action", "whatsapp_number"]

    CreateDocqaAssistantArgs:
      description: |
        **create_docqa_assistant** [plugins] (mutation)
        Crea un nuevo asistente de documentacion. Despues de crearlo, podras subir archivos (PDF, Word, etc.) desde el dashboard.
      type: object
      properties:
        display_name:
          type: string
          description: "Nombre del asistente (ej: 'Manual de Usuario', 'FAQ Producto X')"
        prompt:
          type: string
          description: "Instrucciones adicionales para la IA (opcional)"
        is_enabled:
          type: boolean
          description: "true para activar inmediatamente"
          default: true
        language_mode:
          type: string
          description: "Modo de idioma: auto (detecta automaticamente), fixed (siempre responde en un idioma fijo), selector (el usuario elige el idioma)"
          enum: ["auto", "fixed", "selector"]
          default: "auto"
        language_fixed:
          type: string
          description: "REQUERIDO si language_mode=fixed. Codigo del idioma fijo (es=Espanol, en=Ingles, de=Aleman, fr=Frances, pt=Portugues, it=Italiano, hu=Hungaro). Si el usuario dice 'idioma fijo en espanol', usar language_mode='fixed' Y language_fixed='es'."
          enum: ["es", "en", "de", "fr", "pt", "it", "hu"]
        rate_limit_per_session:
          type: integer
          description: "Limite de preguntas por sesion"
          default: 50
        allowed_domains:
          type: array
          description: "Dominios donde funcionara el widget (vacio = todos)"
        language_available:
          type: array
          description: "Idiomas disponibles (array)"
        language_show_selector:
          type: boolean
          description: "Mostrar selector de idioma"
        rate_limit_window_minutes:
          type: integer
          description: "Ventana de rate limit en minutos"
        config_design:
          type: object
          description: "Configuracion de diseno (JSON)"
        config_texts:
          type: object
          description: "Textos personalizados (JSON)"
      required: ["display_name"]

    CreateEmailAccountArgs:
      description: |
        **create_email_account** [email] (mutation)
        Crea una nueva cuenta de correo electronico con configuracion IMAP/SMTP. Maximo 10 cuentas por tienda.
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        label:
          type: string
          description: "Nombre descriptivo de la cuenta (ej: 'Soporte', 'Ventas')"
        email_address:
          type: string
          description: "Direccion de email"
        auth_type:
          type: string
          description: "Tipo de autenticacion: 'basic' (IMAP/SMTP) o 'oauth2'. Default: 'basic'"
        imap_host:
          type: string
          description: "Servidor IMAP (ej: imap.gmail.com). Requerido para auth_type=basic"
        imap_port:
          type: integer
          description: "Puerto IMAP. Default: 993"
        imap_user:
          type: string
          description: "Usuario IMAP (normalmente el email)"
        imap_password:
          type: string
          description: "Contrasena IMAP (se cifra automaticamente)"
        smtp_host:
          type: string
          description: "Servidor SMTP (ej: smtp.gmail.com). Requerido para auth_type=basic"
        smtp_port:
          type: integer
          description: "Puerto SMTP. Default: 587"
        smtp_user:
          type: string
          description: "Usuario SMTP (normalmente el email)"
        smtp_password:
          type: string
          description: "Contrasena SMTP (se cifra automaticamente)"
        smtp_from_name:
          type: string
          description: "Nombre del remitente en los emails enviados"
        agent_hashes:
          type: array
          description: "Lista de phone_hash de agentes asignados a esta cuenta"
        signature_html:
          type: string
          description: "Firma HTML para los emails enviados desde esta cuenta"
        oauth_provider:
          type: string
          description: "Proveedor OAuth: 'gmail', 'microsoft' o 'none'. Requerido cuando auth_type=oauth2"
        is_active:
          type: integer
          description: "1 para activar, 0 para desactivar. Default: 1"
        ai_classification_enabled:
          type: integer
          description: "1 para activar clasificacion IA de emails, 0 para desactivar. Default: 1"
        ai_transcription_enabled:
          type: integer
          description: "1 para activar transcripcion IA de adjuntos, 0 para desactivar. Default: 1"
      required: ["action", "label", "email_address"]

    CreateEmailRuleArgs:
      description: |
        **create_email_rule** [email] (mutation)
        Crea una nueva regla automatica para procesar emails entrantes. Puede filtrar por remitente, asunto, etc. y ejecutar acciones como archivar, etiquetar o asignar agente.
      type: object
      properties:
        action:
          type: string
          description: "Debe ser 'create'"
        name:
          type: string
          description: "Nombre descriptivo de la regla"
        priority:
          type: integer
          description: "Prioridad (0-99, mayor = se evalua primero). Default 0"
        conditions:
          type: array
          description: "Array de condiciones. Cada condicion: {field: 'from'|'subject'|'body', operator: 'contains'|'equals'|'starts_with'|'ends_with', value: 'texto'}"
        actions:
          type: array
          description: "Array de acciones. Cada accion: {type: 'archive'|'delete'|'spam'|'set_tags'|'assign', value?: 'etiqueta o agent_hash'}"
      required: ["action", "name", "conditions", "actions"]

    CreateKnowledgeFileArgs:
      description: |
        **create_knowledge_file** [storage] (mutation)
        Crea un nuevo archivo en la base de conocimiento a partir de contenido de texto. Ideal para anadir informacion como promociones, politicas, instrucciones, FAQs, etc. sin necesidad de subir un archivo manualmente.
      type: object
      properties:
        title:
          type: string
          description: "Titulo descriptivo del archivo (max 255 caracteres)"
        content:
          type: string
          description: "Contenido de texto del archivo"
        description:
          type: string
          description: "Descripcion breve del contenido (para que la IA sepa cuando usar este archivo)"
        filename:
          type: string
          description: "Nombre del archivo con extension (ej: 'promociones.txt'). Si no se proporciona, se genera automaticamente desde el titulo. Extensiones validas: txt, md, csv, json, html"
      required: ["title", "content"]

    CreateListFromFollowupArgs:
      description: |
        **create_list_from_followup** [mass_marketing] (mutation)
        Crea una lista de contactos desde conversaciones detectadas por Smart Follow-up
      type: object
      properties:
        action:
          type: string
        name:
          type: string
          description: "Nombre de la nueva lista"
        period:
          type: string
          description: "Periodo de búsqueda"
          enum: ["last_7_days", "last_30_days", "last_60_days", "last_90_days"]
      required: ["action"]

    CreateListFromInactiveArgs:
      description: |
        **create_list_from_inactive** [mass_marketing] (mutation)
        Crea una nueva lista de contactos a partir de clientes que no han tenido conversación en un periodo determinado
      type: object
      properties:
        action:
          type: string
        days:
          type: integer
          description: "Días de inactividad mínima (default: 30)"
        name:
          type: string
          description: "Nombre de la nueva lista"
      required: ["action"]

    CreateScheduledMessageArgs:
      description: |
        **create_scheduled_message** [whatsapp_ops] (mutation)
        Programa un mensaje de WhatsApp para envio futuro usando un rol logico, nunca un ID de sesion. FLUJO DE CONFIRMACION: requires_confirmation=true con success=false es normal; describe lo que se programara y PARA.
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        sender_role:
          type: string
          description: "Rol logico del emisor. Por defecto Operaciones."
          enum: ["general", "operations", "marketing"]
          default: "operations"
        phone:
          type: string
          description: "Numero de telefono destino con prefijo internacional formato E.164 (ej: +34612345678). Si el usuario da un numero sin prefijo, preguntarle el pais"
        message_text:
          type: string
          description: "Texto del mensaje a enviar"
        scheduled_at:
          type: string
          description: "Fecha y hora de envio en formato YYYY-MM-DD HH:MM:SS. Debe ser una fecha futura. Si el usuario dice una fecha relativa como 'manana a las 10', convertirla al formato correcto"
        agent_id:
          type: integer
          description: "ID del agente que programa el mensaje"
      required: ["action", "phone", "message_text", "scheduled_at"]

    CreateTaskArgs:
      description: |
        **create_task** [tasks] (mutation)
        Crea una nueva tarea asociada opcionalmente a un cliente y agente
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        task_text:
          type: string
          description: "Descripcion de la tarea"
        phone:
          type: string
          description: "Telefono del cliente relacionado"
        due_date:
          type: string
          description: "Fecha limite (YYYY-MM-DD)"
        priority:
          type: string
          enum: ["low", "medium", "high"]
          default: "medium"
        assigned_agent_id:
          type: integer
          description: "ID del agente al que asignar la tarea"
        status:
          type: string
          description: "Estado de la tarea"
        agent_id:
          type: integer
          description: "ID del agente"
        limit:
          type: integer
          description: "Maximo de resultados"
        offset:
          type: integer
          description: "Posicion de inicio para paginacion"
        task_id:
          type: integer
          description: "ID de la tarea"
        include_completed:
          type: boolean
          description: "Incluir tareas completadas"
      required: ["action", "task_text"]

    CreateWhatsappTemplateFromWorkflowArgs:
      description: |
        **create_whatsapp_template_from_workflow** [whatsapp_ops] (mutation)
        Crea un nuevo workflow de WhatsApp a partir de una plantilla existente
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        template_id:
          type: integer
          description: "ID de la plantilla desde la que crear el workflow"
        session_id:
          type: integer
          description: "ID de la sesion WhatsApp para asociar al workflow"
        name:
          type: string
          description: "Nombre para el nuevo workflow"
      required: ["action", "template_id"]

    CreateWhatsappWorkflowArgs:
      description: |
        **create_whatsapp_workflow** [automation] (mutation)
        Crea un nuevo workflow de automatizacion para respuestas de WhatsApp. Campos requeridos: name y actions. Si el usuario no especifica nombre, genera uno descriptivo automaticamente (ej: 'Respuesta IA fuera horario'). Si el usuario pide crearlo desactivado o para revision, usa status='disabled'. Por defecto se crea activo. LIMITE: maximo 10 workflows por tienda. Si recibes error de limite alcanzado, NO reintentes crear — en su lugar: 1) Llama a list_whatsapp_workflows para mostrar los existentes, 2) Sugiere al usuario eliminar workflows que ya no necesite o reutilizar uno existente con update_whatsapp_workflow.
      type: object
      properties:
        name:
          type: string
          description: "Nombre descriptivo del workflow (max 100 caracteres). Si el usuario no especifica, genera un nombre descriptivo automaticamente basado en las acciones/condiciones."
        trigger_type:
          type: string
          description: "Evento que activa el workflow: 'message.received' (al recibir un mensaje, por defecto) o 'message.sent' (al enviar un mensaje)"
          enum: ["message.received", "message.sent"]
          default: "message.received"
        conditions:
          type: object
          description: "Condiciones para ejecutar el workflow. Formato: {logic: 'AND'|'OR', rules: [...]}. Si no se especifica, se ejecuta siempre."
        actions:
          type: array
          description: "Acciones a ejecutar. Tipos: {type:'reply_with_ai'} o {type:'reply', message:'texto'} o {type:'delay', seconds:N} o {type:'ai_filter'} o {type:'ai_filter', prompt:'instrucciones adicionales'} o {type:'ai_archive_decision', archive_policy:'always'|'preserve_if_previously_archived', prompt:'instrucciones opcionales'}. Para reply_with_ai se puede añadir pre_send_check:{enabled:true} para cancelar el envio si llega un mensaje nuevo durante la generacion IA. Para reply se puede añadir no_repeat:true y no_repeat_hours:N (1, 6, 24, 168 o 0=siempre) para no repetir al mismo contacto. ai_filter analiza si el mensaje necesita respuesta y detiene el workflow si no (previene bucles con mensajes tipo 'gracias' o 'vale', ideal como primera accion antes de reply_with_ai). ai_archive_decision decide ARCHIVAR/MANTENER y debe archivar cuando no queda tarea humana aunque el siguiente paso dependa del cliente. archive_policy define que hacer si la IA decide ARCHIVAR: 'always' archiva el chat; 'preserve_if_previously_archived' archiva solo si el chat no estaba activo antes del mensaje. Opcion prompt:'instrucciones adicionales' para personalizar criterios. Minimo una accion."
        status:
          type: string
          description: "Estado inicial del workflow. Usar 'disabled' si el usuario quiere crearlo desactivado para revision. Por defecto: 'active'."
          enum: ["active", "disabled"]
          default: "active"
        session_id:
          type: integer
          description: "ID de la sesion de WhatsApp a la que asignar este workflow. Si no se especifica (null), el workflow se ejecuta para todos los numeros conectados."
        id:
          type: integer
          description: "ID del workflow (si se especifica, actualiza en lugar de crear)"
      required: ["name", "actions"]

    DeleteAgentArgs:
      description: |
        **delete_agent** [agents] (mutation)
        Elimina un agente de atencion
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
        id:
          type: integer
          description: "ID del agente a eliminar"
      required: ["action", "id"]

    DeleteAiErrorArgs:
      description: |
        **delete_ai_error** [knowledge] (mutation)
        Remove an AI correction that is no longer valid.
      type: object
      properties:
        id:
          type: integer
          description: "ID of the correction to delete"
      required: ["id"]

    DeleteCalendarArgs:
      description: |
        **delete_calendar** [calendar] (mutation)
        Elimina un calendario y todos sus eventos, servicios y disponibilidad
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        calendar_id:
          type: integer
          description: "ID del calendario a eliminar"
      required: ["action", "calendar_id"]

    DeleteCalendarAvailabilityArgs:
      description: |
        **delete_calendar_availability** [calendar] (mutation)
        Elimina una regla de disponibilidad del calendario
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        rule_id:
          type: integer
          description: "ID de la regla a eliminar"
      required: ["action", "rule_id"]

    DeleteCalendarConnectionArgs:
      description: |
        **delete_calendar_connection** [calendar] (mutation)
        Elimina una conexion de proveedor de calendario (Google/Microsoft)
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        connection_id:
          type: integer
          description: "ID de la conexion a eliminar"
      required: ["action", "connection_id"]

    DeleteCalendarEventArgs:
      description: |
        **delete_calendar_event** [calendar] (mutation)
        Elimina un evento del calendario
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        event_id:
          type: integer
          description: "ID del evento a eliminar"
        date_from:
          type: string
          description: "Fecha inicio para filtrar"
        date_to:
          type: string
          description: "Fecha fin para filtrar"
        agent_id:
          type: integer
          description: "ID del agente"
        phone:
          type: string
          description: "Telefono del cliente"
        title:
          type: string
          description: "Titulo del evento"
        description:
          type: string
          description: "Descripcion del evento"
        start_datetime:
          type: string
          description: "Fecha/hora inicio YYYY-MM-DD HH:MM:SS"
        end_datetime:
          type: string
          description: "Fecha/hora fin YYYY-MM-DD HH:MM:SS"
        all_day:
          type: boolean
          description: "Evento de dia completo"
        assigned_agent_id:
          type: integer
          description: "ID del agente asignado"
      required: ["action", "event_id"]

    DeleteCalendarNotificationArgs:
      description: |
        **delete_calendar_notification** [calendar] (mutation)
        Elimina una notificacion automatica de calendario
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        notification_id:
          type: integer
          description: "ID de la notificacion a eliminar"
      required: ["action", "notification_id"]

    DeleteCalendarServiceArgs:
      description: |
        **delete_calendar_service** [calendar] (mutation)
        Elimina un servicio/tipo de cita del calendario
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        service_id:
          type: integer
          description: "ID del servicio a eliminar"
      required: ["action", "service_id"]

    DeleteCampaignArgs:
      description: |
        **delete_campaign** [mass_marketing] (mutation)
        Elimina permanentemente una campaña de marketing masivo
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
        campaign_id:
          type: integer
          description: "ID de la campaña a eliminar"
      required: ["action", "campaign_id"]

    DeleteContactListArgs:
      description: |
        **delete_contact_list** [mass_marketing] (mutation)
        Elimina una lista de contactos y todos sus contactos asociados. Esta accion no se puede deshacer.
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
          description: "Accion fija: delete"
        list_id:
          type: integer
          description: "ID de la lista a eliminar"
      required: ["action", "list_id"]

    DeleteConversationFileArgs:
      description: |
        **delete_conversation_file** [storage] (mutation)
        Elimina un archivo compartido en una conversacion
        ⚠️ Requires confirmation
      type: object
      properties:
        file_uuid:
          type: string
          description: "UUID del archivo a eliminar"
        agent_id:
          type: integer
          description: "ID del agente que realiza la accion"
      required: ["file_uuid"]

    DeleteConversationMessageArgs:
      description: |
        **delete_conversation_message** [conversations] (mutation)
        Elimina un mensaje especifico de una conversacion. Requiere el texto exacto del mensaje.
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        phone:
          type: string
          description: "Telefono del cliente"
        message:
          type: string
          description: "Texto exacto del mensaje a eliminar (string completo tal como aparece en el historial)"
        query:
          type: string
          description: "Texto de busqueda"
        date_from:
          type: string
          description: "Fecha inicio YYYY-MM-DD"
        date_to:
          type: string
          description: "Fecha fin YYYY-MM-DD"
        limit:
          type: integer
          description: "Maximo de resultados"
        offset:
          type: integer
          description: "Posicion de inicio para paginacion"
        hours:
          type: integer
          description: "Ultimas N horas"
        conversation_id:
          type: integer
          description: "ID de conversacion especifica"
        last_n:
          type: integer
          description: "Ultimos N mensajes"
        period:
          type: string
          description: "Periodo de tiempo"
          enum: ["today", "yesterday", "last_7_days"]
        agent_id:
          type: integer
          description: "ID del agente"
        format:
          type: string
          description: "Formato de respuesta"
      required: ["action", "phone", "message"]

    DeleteCustomerAiErrorArgs:
      description: |
        **delete_customer_ai_error** [knowledge] (mutation)
        Remove a correction from the customer-facing WhatsApp AI that is no longer valid.
      type: object
      properties:
        id:
          type: integer
          description: "ID of the correction to delete"
      required: ["id"]

    DeleteDocqaAssistantArgs:
      description: |
        **delete_docqa_assistant** [plugins] (mutation)
        Elimina un asistente Doc-QA y todos sus recursos asociados en OpenAI
        ⚠️ Requires confirmation
      type: object
      properties:
        assistant_id:
          type: integer
          description: "ID del asistente Doc-QA a eliminar"
      required: ["assistant_id"]

    DeleteDocqaFileArgs:
      description: |
        **delete_docqa_file** [plugins] (mutation)
        Elimina un archivo de un asistente Doc-QA
        ⚠️ Requires confirmation
      type: object
      properties:
        file_id:
          type: integer
          description: "ID del archivo a eliminar"
      required: ["file_id"]

    DeleteEmailAccountArgs:
      description: |
        **delete_email_account** [email] (mutation)
        Elimina una cuenta de correo y todos sus emails asociados. Esta accion no se puede deshacer.
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        id:
          type: integer
          description: "ID de la cuenta a eliminar"
      required: ["action", "id"]

    DeleteEmailNoteArgs:
      description: |
        **delete_email_note** [email] (mutation)
        Elimina una nota interna de un hilo de email.
      type: object
      properties:
        action:
          type: string
          description: "Debe ser 'delete'"
        thread_id:
          type: integer
          description: "ID del hilo"
        note_id:
          type: integer
          description: "ID de la nota a eliminar"
        note_text:
          type: string
          description: "Texto de la nota"
        agent_name:
          type: string
          description: "Nombre del agente"
        agent_color:
          type: string
          description: "Color del agente"
        avatar_url:
          type: string
          description: "URL del avatar"
      required: ["action", "thread_id", "note_id"]

    DeleteEmailRuleArgs:
      description: |
        **delete_email_rule** [email] (mutation)
        Elimina una regla de email. Esta accion no se puede deshacer.
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
          description: "Debe ser 'delete'"
        id:
          type: integer
          description: "ID de la regla a eliminar"
      required: ["action", "id"]

    DeleteFaqArgs:
      description: |
        **delete_faq** [plugins] (mutation)
        Elimina permanentemente una o varias FAQs del plugin Product Q&A
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        faq_ids:
          type: array
          description: "IDs de las FAQs a eliminar"
      required: ["action", "faq_ids"]

    DeleteKnowledgeFileArgs:
      description: |
        **delete_knowledge_file** [storage] (mutation)
        Elimina un archivo de la base de conocimiento (no permite eliminar archivos de sistema)
        ⚠️ Requires confirmation
      type: object
      properties:
        file_id:
          type: integer
          description: "ID del archivo a eliminar"
      required: ["file_id"]

    DeleteKnowledgeSnippetArgs:
      description: |
        **delete_knowledge_snippet** [knowledge] (mutation)
        Elimina permanentemente un snippet de conocimiento
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        id:
          type: integer
          description: "ID del snippet a eliminar"
      required: ["action", "id"]

    DeleteNotificationArgs:
      description: |
        **delete_notification** [notifications] (mutation)
        Elimina permanentemente una notificacion
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        notification_id:
          type: integer
          description: "ID de la notificacion a eliminar"
        limit:
          type: integer
          description: "Maximo de resultados"
        offset:
          type: integer
          description: "Posicion de inicio"
        filter:
          type: string
          description: "Filtro de notificaciones"
        type:
          type: string
          description: "Tipo de notificacion"
        agent_id:
          type: integer
          description: "ID del agente"
      required: ["action", "notification_id"]

    DeleteTaskArgs:
      description: |
        **delete_task** [tasks] (mutation)
        Elimina una tarea permanentemente
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        task_id:
          type: integer
          description: "ID de la tarea a eliminar"
        status:
          type: string
          description: "Estado de la tarea"
        agent_id:
          type: integer
          description: "ID del agente"
        phone:
          type: string
          description: "Telefono del cliente"
        limit:
          type: integer
          description: "Maximo de resultados"
        offset:
          type: integer
          description: "Posicion de inicio para paginacion"
        task_text:
          type: string
          description: "Texto de la tarea"
        due_date:
          type: string
          description: "Fecha limite YYYY-MM-DD"
        priority:
          type: string
          description: "Prioridad de la tarea"
          enum: ["low", "medium", "high"]
        assigned_agent_id:
          type: integer
          description: "ID del agente asignado"
        include_completed:
          type: boolean
          description: "Incluir tareas completadas"
      required: ["action", "task_id"]

    DeleteWhatsappSessionArgs:
      description: |
        **delete_whatsapp_session** [whatsapp_ops] (mutation)
        Elimina una sesion de WhatsApp desconectada. Solo funciona con sesiones en estado 'disconnected'.
        ⚠️ Requires confirmation
      type: object
      properties:
        session_id:
          type: integer
          description: "ID de la sesion a eliminar"
        migrate_to:
          type: integer
          description: "ID de otra sesión a la que reasignar workflows, campañas y seguimiento inteligente. Si no se proporciona, se usa 'todas las líneas'."
      required: ["session_id"]

    DeleteWhatsappTemplateArgs:
      description: |
        **delete_whatsapp_template** [whatsapp_ops] (mutation)
        Elimina una plantilla de mensaje de WhatsApp. FLUJO DE CONFIRMACION: Esta accion devolvera requires_confirmation=true con success=false - esto NO es un error, es el flujo normal. Cuando recibas esto, describe brevemente al usuario que la plantilla se eliminara y PARA. NO llames de nuevo a esta accion. El sistema mostrara botones de Confirmar/Cancelar automaticamente.
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        id:
          type: integer
          description: "ID de la plantilla a eliminar"
      required: ["action", "id"]

    DeleteWhatsappWorkflowArgs:
      description: |
        **delete_whatsapp_workflow** [automation] (mutation)
        SOLO para BORRAR/ELIMINAR un workflow de WhatsApp de forma permanente. NO usar para editar, modificar, añadir palabras, simular, probar, unir, combinar ni reorganizar workflows. Si el usuario quiere cambiar algo, usar update_whatsapp_workflow. Si dice 'unir' o 'combinar' workflows, NO borrar ninguno — usar update_whatsapp_workflow para fusionar condiciones/acciones en uno existente. Antes de eliminar, SIEMPRE llama a list_whatsapp_workflows para confirmar con el usuario EXACTAMENTE cual workflow quiere borrar por nombre e ID. FLUJO DE CONFIRMACION OBLIGATORIO: Esta accion devolvera success=false con requires_confirmation=true — esto NO es un error, es el paso 1 del flujo normal de confirmacion. Cuando recibas esta respuesta: 1) Describe brevemente al usuario que workflow se eliminara, 2) PARA completamente, 3) NUNCA vuelvas a llamar a esta misma accion — hacerlo INVALIDA el token de confirmacion y rompe el flujo. Los botones de Confirmar/Cancelar aparecen automaticamente en la interfaz del usuario.
        ⚠️ Requires confirmation
      type: object
      properties:
        id:
          type: integer
          description: "ID del workflow a eliminar"
      required: ["id"]

    DisconnectEcommerceArgs:
      description: |
        **disconnect_ecommerce** [integrations] (mutation)
        Desconecta la integracion con tu plataforma e-commerce (Shopify, WooCommerce, etc.)
        ⚠️ Requires confirmation
      type: object
      properties:
        platform_type:
          type: string
          description: "Plataforma a desconectar. Usa disconnect_ seguido del nombre de la plataforma activa"
          enum: ["disconnect_shopify", "disconnect_woocommerce", "disconnect_prestashop", "disconnect_vtex"]
      required: ["platform_type"]

    DisconnectWhatsappArgs:
      description: |
        **disconnect_whatsapp** [automation] (mutation)
        Desconecta una sesion de WhatsApp y elimina los datos de autenticacion. Si hay multiples numeros, requiere session_id.
        ⚠️ Requires confirmation
      type: object
      properties:
        session_id:
          type: integer
          description: "ID de la sesion a desconectar. Obligatorio si hay mas de un numero conectado. Usa get_whatsapp_status para obtener los IDs."

    DiscoverEmailFoldersArgs:
      description: |
        **discover_email_folders** [email] (query)
        Conecta al servidor IMAP de una cuenta de email y descubre las carpetas disponibles (Enviados, Papelera, Archivo, Spam). Detecta automaticamente las carpetas estandar.
      type: object
      properties:
        action:
          type: string
          description: "Debe ser 'discover_folders'"
        id:
          type: integer
          description: "ID de la cuenta de correo"
      required: ["action", "id"]

    DismissTrainingSuggestionArgs:
      description: |
        **dismiss_training_suggestion** [knowledge] (mutation)
        Descarta una sugerencia de entrenamiento de IA con motivo opcional.
      type: object
      properties:
        action:
          type: string
        suggestion_id:
          type: integer
          description: "ID de la sugerencia a descartar"
        reason:
          type: string
          description: "Motivo del descarte (opcional)"
      required: ["action", "suggestion_id"]

    DownloadConversationFileArgs:
      description: |
        **download_conversation_file** [storage] (query)
        Obtiene la URL de descarga de un archivo compartido en una conversacion
      type: object
      properties:
        file_uuid:
          type: string
          description: "UUID del archivo a descargar"
      required: ["file_uuid"]

    DownloadEmailAttachmentArgs:
      description: |
        **download_email_attachment** [email] (query)
        Obtiene la URL de descarga de un adjunto de email
      type: object
      properties:
        attachment_id:
          type: integer
          description: "ID del adjunto"
        json:
          type: boolean
          description: "Devolver URL como JSON en vez de redirigir"
      required: ["attachment_id"]

    DownloadKnowledgeFileArgs:
      description: |
        **download_knowledge_file** [knowledge] (query)
        Obtiene la URL de descarga de un archivo de la base de conocimiento
      type: object
      properties:
        id:
          type: integer
          description: "ID del archivo de conocimiento"
      required: ["id"]

    DraftAiTicketCustomerReplyArgs:
      description: |
        **draft_ai_ticket_customer_reply** [tickets] (mutation)
        Genera un borrador seguro para cliente a partir de instrucciones internas. No envia el mensaje; solo crea un customer_draft revisable.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        ticket_id:
          type: integer
          description: "ID del ticket"
        instruction:
          type: string
          description: "Instruccion interna del agente. La IA usa la intencion, no el texto literal"
        customer_safe_facts:
          type: array
          description: "Hechos seguros que se pueden mencionar al cliente"
      required: ["action", "ticket_id"]

    DryRunWorkflowArgs:
      description: |
        **dry_run_workflow** [automation] (query)
        Simula la ejecucion de un workflow con un mensaje de prueba sin enviar nada real. Usar cuando el usuario diga 'pruebalo', 'simulalo', 'testea', 'probemos', 'a ver si funciona' o cualquier variacion de probar/simular. Esta accion es SEGURA — no envia mensajes ni modifica nada. Para probar con multiples ejemplos, llamar esta accion varias veces con diferentes test_message. PREFERIR esta accion sobre save/update cuando el usuario quiere validar antes de activar.
      type: object
      properties:
        action:
          type: string
        workflow_id:
          type: integer
          description: "ID del workflow a probar"
        test_message:
          type: string
          description: "Texto de mensaje simulado. Para simular multiples escenarios, hacer varias llamadas con diferentes mensajes"
        test_phone:
          type: string
          description: "Telefono simulado del remitente (con prefijo +). Usar diferentes prefijos para probar condiciones de pais"
      required: ["action", "workflow_id", "test_message"]

    DuplicateCampaignArgs:
      description: |
        **duplicate_campaign** [mass_marketing] (mutation)
        Crea una copia de una campaña existente en estado borrador
      type: object
      properties:
        action:
          type: string
        campaign_id:
          type: integer
          description: "ID de la campaña a duplicar"
      required: ["action", "campaign_id"]

    EditKnowledgeSnippetArgs:
      description: |
        **edit_knowledge_snippet** [knowledge] (mutation)
        Edita el contenido o categoria de un snippet de conocimiento
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        id:
          type: integer
          description: "ID del snippet"
        content:
          type: string
          description: "Nuevo contenido del snippet"
        category:
          type: string
          description: "Nueva categoria"
      required: ["action", "id"]

    EmailThreadActionArgs:
      description: |
        **email_thread_action** [email] (mutation)
        Ejecuta una accion sobre un hilo de email: archivar, eliminar, spam, restaurar, marcar como no leido, posponer (snooze), quitar snooze, fusionar hilos, asignar etiquetas o asignar agente
      type: object
      properties:
        action:
          type: string
          description: "Accion a ejecutar: archive, delete, spam, restore, mark_unread, snooze, unsnooze, merge, set_tags, assign"
        thread_id:
          type: integer
          description: "ID del hilo de email"
        until:
          type: string
          description: "Fecha/hora hasta la que posponer (solo para action=snooze). Formato ISO 8601 o natural (ej: '2026-03-22 09:00:00', 'tomorrow 9am')"
        target_thread_id:
          type: integer
          description: "ID del hilo destino para fusionar (solo para action=merge)"
        tags:
          type: array
          description: "Array de etiquetas (solo para action=set_tags)"
        agent_hash:
          type: string
          description: "Hash del agente a asignar (solo para action=assign, null para desasignar)"
      required: ["action", "thread_id"]

    ExportCampaignCsvArgs:
      description: |
        **export_campaign_csv** [mass_marketing] (query)
        Descarga los logs de envio de una campana completada como archivo CSV. Solo funciona con campanas completadas, canceladas, pausadas o archivadas.
      type: object
      properties:
        campaign_id:
          type: integer
          description: "ID de la campana cuyos resultados se quieren exportar"
      required: ["campaign_id"]

    ExportConversationsArgs:
      description: |
        **export_conversations** [conversations] (query)
        Exporta conversaciones con todos los mensajes en formato estructurado
      type: object
      properties:
        action:
          type: string
        phone:
          type: string
          description: "Filtrar por telefono"
        date_from:
          type: string
          description: "Fecha inicio YYYY-MM-DD"
        date_to:
          type: string
          description: "Fecha fin YYYY-MM-DD"
        format:
          type: string
          description: "Formato: json (completo) o csv_summary (sin mensajes)"
          enum: ["json", "csv_summary"]
        limit:
          type: integer
          description: "Maximo conversaciones (default 50, max 200)"
        query:
          type: string
          description: "Texto de busqueda"
        offset:
          type: integer
          description: "Posicion de inicio para paginacion"
        hours:
          type: integer
          description: "Ultimas N horas"
        conversation_id:
          type: integer
          description: "ID de conversacion especifica"
        last_n:
          type: integer
          description: "Ultimos N mensajes"
        period:
          type: string
          description: "Periodo de tiempo"
          enum: ["today", "yesterday", "last_7_days"]
        agent_id:
          type: integer
          description: "ID del agente"
        message:
          type: string
          description: "Texto del mensaje a enviar o eliminar"
      required: ["action"]

    ExportCrmContactsArgs:
      description: |
        **export_crm_contacts** [crm] (query)
        Exporta los contactos del CRM interno como archivo CSV
      type: object
      properties:
        format:
          type: string
          description: "Formato de exportacion"
        tag:
          type: string
          description: "Filtrar por etiqueta de cliente"
        since:
          type: string
          description: "Fecha minima de actualizacion (formato ISO 8601, ej: 2026-01-01T00:00:00Z)"
      required: ["format"]

    ForceEmailSyncArgs:
      description: |
        **force_email_sync** [email] (mutation)
        Fuerza una sincronizacion inmediata de todas las cuentas de email via IMAP
      type: object

    GdprDeleteCustomerDataArgs:
      description: |
        **gdpr_delete_customer_data** [customers] (mutation)
        Elimina todos los datos personales de un cliente para cumplimiento GDPR (Art. 17 - Derecho al olvido). Los registros CRM se anonimizan en vez de eliminarse.
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
        phone:
          type: string
          description: "Telefono del cliente cuyos datos se eliminaran"
      required: ["action", "phone"]

    GdprExportCustomerDataArgs:
      description: |
        **gdpr_export_customer_data** [customers] (query)
        Exporta todos los datos almacenados de un cliente para cumplimiento GDPR (Art. 15 - Derecho de acceso)
      type: object
      properties:
        action:
          type: string
        phone:
          type: string
          description: "Telefono del cliente"
      required: ["action", "phone"]

    GenerateAiTicketBriefArgs:
      description: |
        **generate_ai_ticket_brief** [tickets] (mutation)
        Genera un resumen operativo interno, posible solucion, datos faltantes y hechos seguros para el cliente.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        ticket_id:
          type: integer
          description: "ID del ticket"
      required: ["action", "ticket_id"]

    GenerateEmailDraftArgs:
      description: |
        **generate_email_draft** [email] (mutation)
        Genera un borrador de respuesta usando IA para un hilo de email
      type: object
      properties:
        thread_id:
          type: integer
          description: "ID del hilo"
        action:
          type: string
          description: "Debe ser 'generate'"
        instructions:
          type: string
          description: "Instrucciones opcionales para la IA"
      required: ["thread_id", "action"]

    GenerateReferralCodeArgs:
      description: |
        **generate_referral_code** [referrals] (mutation)
        Genera el enlace único de referido del usuario para compartir. Si ya tiene uno, lo devuelve.
      type: object

    GetAgentActivityArgs:
      description: |
        **get_agent_activity** [agents] (query)
        Muestra la actividad y carga de trabajo de un agente especifico
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        agent_id:
          type: integer
          description: "ID del agente"
        period:
          type: string
          description: "Periodo de tiempo"
          enum: ["today", "yesterday", "last_7_days", "last_30_days"]
        days:
          type: integer
          description: "Numero de dias a consultar"
      required: ["action", "agent_id"]

    GetAgentAssignmentsArgs:
      description: |
        **get_agent_assignments** [agents] (query)
        Devuelve los agentes asignados a una lista de telefonos de clientes
      type: object
      properties:
        phones:
          type: array
          description: "Lista de numeros de telefono para consultar sus agentes asignados"
      required: ["phones"]

    GetAgentPerformanceArgs:
      description: |
        **get_agent_performance** [agents] (query)
        Metricas detalladas de rendimiento de un agente: clientes asignados, tareas, tasa de completado
      type: object
      properties:
        action:
          type: string
        agent_id:
          type: integer
          description: "ID del agente"
        days:
          type: integer
          description: "Dias a analizar (default 30)"
        period:
          type: string
          description: "Periodo de tiempo"
          enum: ["today", "yesterday", "last_7_days", "last_30_days"]
      required: ["action", "agent_id"]

    GetAgentPermissionsArgs:
      description: |
        **get_agent_permissions** [agents] (query)
        Obtiene los permisos configurados de un agente y el registro completo de permisos disponibles
      type: object
      properties:
        action:
          type: string
        id:
          type: integer
          description: "ID del agente"
      required: ["action", "id"]

    GetAgentStatsArgs:
      description: |
        **get_agent_stats** [agents] (query)
        Metricas de rendimiento del equipo: mensajes enviados, recibidos, tareas completadas
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        period:
          type: string
          enum: ["today", "yesterday", "last_7_days", "last_30_days"]
          default: "last_7_days"
        agent_id:
          type: integer
          description: "ID del agente para filtrar"
        days:
          type: integer
          description: "Numero de dias a consultar"
      required: ["action"]

    GetAgentTasksArgs:
      description: |
        **get_agent_tasks** [tasks] (query)
        Muestra las tareas asignadas a un agente especifico
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        agent_id:
          type: integer
          description: "ID del agente"
        include_completed:
          type: string
          description: "Incluir tareas completadas (default 0)"
          enum: ["0", "1"]
          default: "0"
        status:
          type: string
          description: "Estado de la tarea"
        phone:
          type: string
          description: "Telefono del cliente"
        limit:
          type: integer
          description: "Maximo de resultados"
        offset:
          type: integer
          description: "Posicion de inicio para paginacion"
        task_text:
          type: string
          description: "Texto de la tarea"
        due_date:
          type: string
          description: "Fecha limite YYYY-MM-DD"
        priority:
          type: string
          description: "Prioridad de la tarea"
          enum: ["low", "medium", "high"]
        assigned_agent_id:
          type: integer
          description: "ID del agente asignado"
        task_id:
          type: integer
          description: "ID de la tarea"
      required: ["action", "agent_id"]

    GetAiErrorsArgs:
      description: |
        **get_ai_errors** [knowledge] (query)
        List active AI corrections for this assistant. To list ALL corrections, pass no parameters. Only use category or query when filtering specific results.
      type: object
      properties:
        category:
          type: string
          description: "OPTIONAL filter. Omit to get ALL categories. Values: shipping, pricing, warranty, product, tone, policy, communication, general"
        query:
          type: string
          description: "OPTIONAL single keyword search. Omit to get ALL corrections. Use single words only, not sentences."

    GetAiLearningInsightsArgs:
      description: |
        **get_ai_learning_insights** [stats] (query)
        Muestra metricas del sistema de aprendizaje trazable: KPIs de uso de reglas, eventos de aprendizaje, distribucion por canal, reglas mas usadas y eventos recientes.
      type: object
      properties:
        days:
          type: integer
          description: "Ventana de dias a analizar (entre 1 y 90, por defecto 30)"
          default: 30

    GetAiSummaryArgs:
      description: |
        **get_ai_summary** [ai_analysis] (query)
        Genera un resumen de una conversacion usando IA. Tipos: quick (breve), detailed (completo), actionable (acciones pendientes). Consume creditos de IA.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        phone:
          type: string
          description: "Telefono del cliente (con o sin +)"
        summary_type:
          type: string
          description: "Tipo de resumen: quick (breve), detailed (completo, default), actionable (acciones pendientes)"
          enum: ["quick", "detailed", "actionable"]
          default: "detailed"
        days:
          type: integer
          description: "Numero de dias a analizar"
        tone:
          type: string
          description: "Tono para la respuesta"
        hours:
          type: integer
          description: "Ultimas N horas a analizar"
        limit:
          type: integer
          description: "Maximo de resultados"
        target_language:
          type: string
          description: "Idioma destino para traduccion"
        last_n:
          type: integer
          description: "Ultimos N mensajes a procesar"
      required: ["action", "phone"]

    GetAiTicketArgs:
      description: |
        **get_ai_ticket** [tickets] (query)
        Obtiene un ticket interno con mensajes, eventos, adjuntos y contexto de cliente/conversacion.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        ticket_id:
          type: integer
          description: "ID numerico del ticket"
        ticket_uid:
          type: string
          description: "UID publico interno del ticket, por ejemplo TKT-260609-ABC123"
      required: ["action"]

    GetAiTicketsSettingsArgs:
      description: |
        **get_ai_tickets_settings** [tickets] (query)
        Devuelve si Tickets IA esta activado para la tienda y el prompt de sistema en uso.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
      required: ["action"]

    GetAiTicketsStatsArgs:
      description: |
        **get_ai_tickets_stats** [tickets] (query)
        Obtiene metricas de tickets internos: abiertos, sin asignar, urgentes, vencidos, creados y resueltos en el periodo, tiempo medio de resolucion y series diarias.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        date_from:
          type: string
          description: "Fecha inicial del periodo (YYYY-MM-DD). Por defecto los ultimos 7 dias"
        date_to:
          type: string
          description: "Fecha final del periodo (YYYY-MM-DD). Por defecto hoy"
      required: ["action"]

    GetAnalyticsArgs:
      description: |
        **get_analytics** [stats] (query)
        Muestra metricas de rendimiento: conversaciones, mensajes, actividad diaria
      type: object
      properties:
        period:
          type: string
          description: "Periodo: 7d (semana), 14d (2 semanas), 30d (mes)"
          default: "7d"

    GetApiKeyArgs:
      description: |
        **get_api_key** [advanced] (query)
        Muestra la API key actual de la tienda (token_ext) y la URL del servidor MCP. Usa esta accion cuando el usuario pregunte por su API key, token, como conectar MCP, o como configurar Claude/Cursor/VS Code.
      type: object

    GetApiUsageStatsArgs:
      description: |
        **get_api_usage_stats** [activity] (query)
        Consumo de tokens y costes por modelo de IA
      type: object
      properties:
        action:
          type: string
        days:
          type: integer
          description: "Dias a analizar (default 30)"
        period:
          type: string
          description: "Periodo: last_7_days, last_30_days, this_month, last_month, last_90_days, all_time, custom"
          enum: ["last_7_days", "last_30_days", "this_month", "last_month", "last_90_days", "all_time", "custom"]
        date:
          type: string
          description: "Fecha de referencia YYYY-MM-DD"
        phone:
          type: string
          description: "Filtrar por telefono de cliente"
      required: ["action"]

    GetAutolearningMetricsArgs:
      description: |
        **get_autolearning_metrics** [stats] (query)
        Muestra las metricas del sistema de aprendizaje automatico incluyendo KPIs, distribucion por categoria y evolucion de similitud.
      type: object

    GetAutolearningStatsArgs:
      description: |
        **get_autolearning_stats** [stats] (query)
        Obtiene estadisticas detalladas del sistema de auto-learning: snippets activos, pendientes, rechazados, etc.
      type: object

    GetBusiestHoursArgs:
      description: |
        **get_busiest_hours** [activity] (query)
        Analiza a que horas del dia se reciben mas mensajes de clientes
      type: object
      properties:
        action:
          type: string
        days:
          type: integer
          description: "Dias a analizar (default 7)"
          default: 7
        period:
          type: string
          description: "Periodo: last_7_days, last_30_days, this_month, last_month, last_90_days, all_time, custom"
          enum: ["last_7_days", "last_30_days", "this_month", "last_month", "last_90_days", "all_time", "custom"]
        date:
          type: string
          description: "Fecha de referencia YYYY-MM-DD"
        phone:
          type: string
          description: "Filtrar por telefono de cliente"
      required: ["action"]

    GetCalendarSettingsArgs:
      description: |
        **get_calendar_settings** [calendar] (query)
        Get calendar integration settings (enabled, timezone, booking rules)
      type: object
      properties:
        action:
          type: string
      required: ["action"]

    GetCampaignArgs:
      description: |
        **get_campaign** [mass_marketing] (query)
        Obtiene los detalles completos de una campaña de marketing masivo
      type: object
      properties:
        action:
          type: string
        campaign_id:
          type: integer
          description: "ID de la campaña"
      required: ["action", "campaign_id"]

    GetCampaignLogsArgs:
      description: |
        **get_campaign_logs** [mass_marketing] (query)
        Obtiene el progreso y logs de envio de una campana especifica
      type: object
      properties:
        campaign_id:
          type: integer
          description: "ID de la campana"
        page:
          type: integer
          description: "Numero de pagina"
        limit:
          type: integer
          description: "Resultados por pagina"
      required: ["campaign_id"]

    GetChatPluginStatsArgs:
      description: |
        **get_chat_plugin_stats** [stats] (query)
        Muestra estadisticas de uso del plugin de chat web: conversaciones, mensajes, sesiones activas, referrers y paises
      type: object

    GetChatSessionsArgs:
      description: |
        **get_chat_sessions** [plugins] (query)
        Lista las sesiones recientes del widget de chat web
      type: object
      properties:
        action:
          type: string
        hours:
          type: integer
          description: "Horas a consultar (default 24)"
        limit:
          type: integer
          description: "Maximo resultados (default 20)"
        plugin_type:
          type: string
          description: "Filtrar por tipo de plugin"
        period:
          type: string
          description: "Periodo"
          enum: ["today", "yesterday", "last_7_days", "last_30_days"]
      required: ["action"]

    GetContactListDetailArgs:
      description: |
        **get_contact_list_detail** [mass_marketing] (query)
        Obtiene los contactos de una lista específica con paginación y búsqueda
      type: object
      properties:
        action:
          type: string
        list_id:
          type: integer
          description: "ID de la lista"
        page:
          type: integer
          description: "Número de página"
        search:
          type: string
          description: "Buscar contactos por teléfono o nombre"
      required: ["action", "list_id"]

    GetConversationAnalyticsArgs:
      description: |
        **get_conversation_analytics** [activity] (query)
        Distribucion de satisfaccion, urgencia e intenciones en conversaciones analizadas
      type: object
      properties:
        action:
          type: string
        days:
          type: integer
          description: "Dias a analizar (default 30)"
        date:
          type: string
          description: "Fecha especifica YYYY-MM-DD"
        period:
          type: string
          description: "Periodo de tiempo"
          enum: ["last_7_days", "last_30_days", "this_month", "last_month", "last_90_days", "all_time", "custom"]
        phone:
          type: string
          description: "Filtrar por telefono del cliente"
      required: ["action"]

    GetConversationCountArgs:
      description: |
        **get_conversation_count** [conversations] (query)
        Cuenta conversaciones que coinciden con criterios de busqueda, fecha o periodo
      type: object
      properties:
        action:
          type: string
        query:
          type: string
          description: "Texto a buscar"
        period:
          type: string
          description: "Periodo predefinido"
          enum: ["today", "yesterday", "last_7_days", "last_30_days"]
        date_from:
          type: string
          description: "Fecha inicio YYYY-MM-DD"
        date_to:
          type: string
          description: "Fecha fin YYYY-MM-DD"
        phone:
          type: string
          description: "Filtrar por telefono del cliente"
        limit:
          type: integer
          description: "Maximo de resultados"
        offset:
          type: integer
          description: "Posicion de inicio para paginacion"
        hours:
          type: integer
          description: "Ultimas N horas"
        conversation_id:
          type: integer
          description: "ID de conversacion especifica"
        last_n:
          type: integer
          description: "Ultimos N mensajes"
        agent_id:
          type: integer
          description: "ID del agente"
        message:
          type: string
          description: "Texto del mensaje a enviar o eliminar"
        format:
          type: string
          description: "Formato de respuesta"
      required: ["action"]

    GetConversationDetailArgs:
      description: |
        **get_conversation_detail** [conversations] (query)
        Muestra los mensajes completos de una conversacion especifica, incluyendo datos del cliente
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        phone:
          type: string
          description: "Numero de telefono del cliente"
        conversation_id:
          type: integer
          description: "ID de la conversacion (alternativa a phone)"
        last_n:
          type: integer
          description: "Cantidad de ultimos mensajes a mostrar (default 50, max 200)"
          default: 50
        query:
          type: string
          description: "Texto de busqueda"
        date_from:
          type: string
          description: "Fecha inicio YYYY-MM-DD"
        date_to:
          type: string
          description: "Fecha fin YYYY-MM-DD"
        limit:
          type: integer
          description: "Maximo de resultados"
        offset:
          type: integer
          description: "Posicion de inicio para paginacion"
        hours:
          type: integer
          description: "Ultimas N horas"
        period:
          type: string
          description: "Periodo de tiempo"
          enum: ["today", "yesterday", "last_7_days"]
        agent_id:
          type: integer
          description: "ID del agente"
        message:
          type: string
          description: "Texto del mensaje a enviar o eliminar"
        format:
          type: string
          description: "Formato de respuesta"
      required: ["action"]

    GetConversationsByAgentArgs:
      description: |
        **get_conversations_by_agent** [conversations] (query)
        Muestra las conversaciones asignadas a un agente especifico
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        agent_id:
          type: integer
          description: "ID del agente"
        limit:
          type: integer
          description: "Maximo de resultados (default 20)"
          default: 20
        query:
          type: string
          description: "Texto de busqueda"
        phone:
          type: string
          description: "Filtrar por telefono del cliente"
        date_from:
          type: string
          description: "Fecha inicio YYYY-MM-DD"
        date_to:
          type: string
          description: "Fecha fin YYYY-MM-DD"
        offset:
          type: integer
          description: "Posicion de inicio para paginacion"
        hours:
          type: integer
          description: "Ultimas N horas"
        conversation_id:
          type: integer
          description: "ID de conversacion especifica"
        last_n:
          type: integer
          description: "Ultimos N mensajes"
        period:
          type: string
          description: "Periodo de tiempo"
          enum: ["today", "yesterday", "last_7_days"]
        message:
          type: string
          description: "Texto del mensaje a enviar o eliminar"
        format:
          type: string
          description: "Formato de respuesta"
      required: ["action", "agent_id"]

    GetConversationsSummaryArgs:
      description: |
        **get_conversations_summary** [conversations] (query)
        Resumen estadistico de las conversaciones de un periodo: total, satisfaccion media, urgencia, etc.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        period:
          type: string
          description: "Periodo (default today)"
          enum: ["today", "yesterday", "last_7_days"]
          default: "today"
        query:
          type: string
          description: "Texto de busqueda"
        phone:
          type: string
          description: "Filtrar por telefono del cliente"
        date_from:
          type: string
          description: "Fecha inicio YYYY-MM-DD"
        date_to:
          type: string
          description: "Fecha fin YYYY-MM-DD"
        limit:
          type: integer
          description: "Maximo de resultados"
        offset:
          type: integer
          description: "Posicion de inicio para paginacion"
        hours:
          type: integer
          description: "Ultimas N horas"
        conversation_id:
          type: integer
          description: "ID de conversacion especifica"
        last_n:
          type: integer
          description: "Ultimos N mensajes"
        agent_id:
          type: integer
          description: "ID del agente"
        message:
          type: string
          description: "Texto del mensaje a enviar o eliminar"
        format:
          type: string
          description: "Formato de respuesta"
      required: ["action"]

    GetCreditHistoryArgs:
      description: |
        **get_credit_history** [activity] (query)
        Muestra el consumo de creditos OpenAI por dia y por endpoint
      type: object
      properties:
        action:
          type: string
        days:
          type: integer
          description: "Dias a analizar (default 30)"
        date:
          type: string
          description: "Fecha especifica YYYY-MM-DD"
        period:
          type: string
          description: "Periodo de tiempo"
          enum: ["last_7_days", "last_30_days", "this_month", "last_month", "last_90_days", "all_time", "custom"]
        phone:
          type: string
          description: "Filtrar por telefono del cliente"
      required: ["action"]

    GetCreditsInfoArgs:
      description: |
        **get_credits_info** [stats] (query)
        Muestra informacion detallada sobre los creditos disponibles: gratuitos, comprados, porcentaje usado y fecha de renovacion. Usa esta accion cuando el usuario pregunte especificamente por creditos.
      type: object

    GetCrmCustomerArgs:
      description: |
        **get_crm_customer** [crm] (query)
        Obtiene los datos de un contacto del CRM interno por su numero de WhatsApp
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        whatsapp_number:
          type: string
          description: "Numero de WhatsApp del contacto a consultar"
      required: ["action", "whatsapp_number"]

    GetCrmHealthStatusArgs:
      description: |
        **get_crm_health_status** [advanced] (query)
        Muestra el estado actual de los endpoints CRM configurados: si estan activos o deshabilitados por errores consecutivos, contador de errores y lista de endpoints
      type: object

    GetCustomerAiErrorsArgs:
      description: |
        **get_customer_ai_errors** [knowledge] (query)
        List corrections for the CUSTOMER-FACING WhatsApp AI. To list ALL corrections, pass no parameters. Only use category or query when filtering specific results.
      type: object
      properties:
        category:
          type: string
          description: "OPTIONAL filter. Omit to get ALL categories. Values: shipping, pricing, warranty, product, tone, policy, communication, general"
        query:
          type: string
          description: "OPTIONAL single keyword search. Omit to get ALL corrections. Use single words only, not sentences."

    GetCustomerCommentsArgs:
      description: |
        **get_customer_comments** [customers] (query)
        Obtiene los comentarios y tags asociados a un cliente
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        phone:
          type: string
          description: "Numero de telefono del cliente"
        comment:
          type: string
          description: "Texto del comentario"
        agent_name:
          type: string
          description: "Nombre del agente"
        query:
          type: string
          description: "Texto de busqueda"
        limit:
          type: integer
          description: "Maximo de resultados"
        tag_name:
          type: string
          description: "Nombre del tag"
        tag_color:
          type: string
          description: "Color del tag en formato hexadecimal"
        primary_phone:
          type: string
          description: "Telefono principal para merge"
        secondary_phone:
          type: string
          description: "Telefono secundario para merge"
      required: ["action", "phone"]

    GetCustomerInfoArgs:
      description: |
        **get_customer_info** [customers] (query)
        Obtiene perfil completo de un cliente: datos CRM, comentarios, tags, conversacion, archivos y tareas
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        phone:
          type: string
          description: "Numero de telefono del cliente"
        query:
          type: string
          description: "Buscar cliente por nombre o teléfono"
        comment:
          type: string
          description: "Texto del comentario"
        agent_name:
          type: string
          description: "Nombre del agente"
        limit:
          type: integer
          description: "Maximo de resultados"
        tag_name:
          type: string
          description: "Nombre del tag"
        tag_color:
          type: string
          description: "Color del tag en formato hexadecimal"
        primary_phone:
          type: string
          description: "Telefono principal para merge"
        secondary_phone:
          type: string
          description: "Telefono secundario para merge"
      required: ["action", "phone"]

    GetCustomerJourneyArgs:
      description: |
        **get_customer_journey** [customers] (query)
        Timeline completo de un cliente: mensajes, comentarios, archivos, tareas, pedidos, follow-ups
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        phone:
          type: string
          description: "Numero de telefono del cliente"
        date:
          type: string
          description: "Fecha especifica YYYY-MM-DD"
        period:
          type: string
          description: "Periodo de tiempo"
          enum: ["last_7_days", "last_30_days", "this_month", "last_month", "last_90_days", "all_time", "custom"]
        days:
          type: integer
          description: "Numero de dias a consultar"
      required: ["action", "phone"]

    GetCustomerLifetimeValueArgs:
      description: |
        **get_customer_lifetime_value** [customers] (query)
        Calcula metricas de valor del cliente: pedidos, gasto, antiguedad, interacciones
      type: object
      properties:
        action:
          type: string
        phone:
          type: string
          description: "Telefono del cliente"
      required: ["action", "phone"]

    GetDailySummaryArgs:
      description: |
        **get_daily_summary** [activity] (query)
        Resumen completo de actividad de un dia: conversaciones, mensajes, plugins, workflows, follow-ups, tareas
      type: object
      properties:
        action:
          type: string
        date:
          type: string
          description: "Fecha (YYYY-MM-DD, default hoy)"
        period:
          type: string
          description: "Periodo: last_7_days, last_30_days, this_month, last_month, last_90_days, all_time, custom"
          enum: ["last_7_days", "last_30_days", "this_month", "last_month", "last_90_days", "all_time", "custom"]
        days:
          type: integer
          description: "Numero de dias a incluir"
        phone:
          type: string
          description: "Filtrar por telefono de cliente"
      required: ["action"]

    GetDocqaDetailArgs:
      description: |
        **get_docqa_detail** [plugins] (query)
        Obtiene los detalles completos de un asistente Doc-QA incluyendo estadisticas
      type: object
      properties:
        assistant_id:
          type: integer
          description: "ID del asistente Doc-QA"
      required: ["assistant_id"]

    GetDocqaLogsArgs:
      description: |
        **get_docqa_logs** [plugins] (query)
        Obtiene el historial de preguntas realizadas a un asistente Doc-QA
      type: object
      properties:
        assistant_id:
          type: integer
          description: "ID del asistente Doc-QA"
        page:
          type: integer
          description: "Numero de pagina (default: 1)"
        per_page:
          type: integer
          description: "Resultados por pagina (10-100, default: 20)"
        date_from:
          type: string
          description: "Fecha inicio del filtro (YYYY-MM-DD)"
        date_to:
          type: string
          description: "Fecha fin del filtro (YYYY-MM-DD)"
        days:
          type: integer
          description: "Ultimos N dias"
        search:
          type: string
          description: "Texto de busqueda en preguntas y respuestas"
      required: ["assistant_id"]

    GetDocqaStatsArgs:
      description: |
        **get_docqa_stats** [stats] (query)
        Muestra estadisticas detalladas de un asistente de documentacion. Requiere assistant_id: usa list_docqa_assistants primero para obtener los IDs disponibles.
      type: object
      properties:
        assistant_id:
          type: integer
          description: "ID del asistente (obtenlo llamando a list_docqa_assistants)"
        days:
          type: integer
          description: "Periodo en dias (1-365)"
          default: 30
      required: ["assistant_id"]

    GetEcommerceSyncStatusArgs:
      description: |
        **get_ecommerce_sync_status** [activity] (query)
        Estado de conexion con la plataforma e-commerce y estadisticas de clientes CRM sincronizados
      type: object
      properties:
        action:
          type: string
        period:
          type: string
          description: "Periodo: last_7_days, last_30_days, this_month, last_month, last_90_days, all_time, custom"
          enum: ["last_7_days", "last_30_days", "this_month", "last_month", "last_90_days", "all_time", "custom"]
        days:
          type: integer
          description: "Numero de dias de lookback"
        date:
          type: string
          description: "Fecha de referencia"
        phone:
          type: string
          description: "Filtrar por telefono de cliente"
      required: ["action"]

    GetEmailAccountArgs:
      description: |
        **get_email_account** [email] (query)
        Devuelve los datos completos de una cuenta de correo especifica, incluyendo agentes asignados.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        id:
          type: integer
          description: "ID de la cuenta de email"
      required: ["action", "id"]

    GetEmailAccountsArgs:
      description: |
        **get_email_accounts** [email] (query)
        Lista las cuentas de email accesibles con su estado y configuracion basica
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
      required: ["action"]

    GetEmailFilterCountsArgs:
      description: |
        **get_email_filter_counts** [email] (query)
        Devuelve la cantidad de hilos por cada filtro (no leidos, leidos, enviados, archivados, etc.)
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        account_id:
          type: integer
          description: "ID de cuenta de email para filtrar (omitir para todas)"
      required: ["action"]

    GetEmailRetentionArgs:
      description: |
        **get_email_retention** [email] (query)
        Devuelve el periodo de retencion configurado para los emails de la tienda.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        id:
          type: integer
          description: "ID de la cuenta de correo"
      required: ["action", "id"]

    GetEmailStatsArgs:
      description: |
        **get_email_stats** [email] (query)
        Obtiene estadisticas de correo electronico: volumenes, tiempos de respuesta, desglose por agente y clasificacion IA
      type: object
      properties:
        period:
          type: string
          description: "Periodo: last_7_days, last_30_days, this_month, last_month, last_90_days, all_time, custom"
          enum: ["last_7_days", "last_30_days", "this_month", "last_month", "last_90_days", "all_time", "custom"]
        date_from:
          type: string
          description: "Fecha inicio YYYY-MM-DD (solo para period=custom)"
        date_to:
          type: string
          description: "Fecha fin YYYY-MM-DD (solo para period=custom)"

    GetEmailThreadDetailArgs:
      description: |
        **get_email_thread_detail** [email] (query)
        Obtiene todos los mensajes de un hilo de email especifico
      type: object
      properties:
        thread_id:
          type: integer
          description: "ID del hilo"
        page:
          type: integer
          description: "Numero de pagina para paginacion de mensajes"
      required: ["thread_id"]

    GetEmailUnreadCountArgs:
      description: |
        **get_email_unread_count** [email] (query)
        Devuelve el total de emails no leidos en todas las cuentas
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
      required: ["action"]

    GetKnowledgeProcessingStatusArgs:
      description: |
        **get_knowledge_processing_status** [knowledge] (query)
        Obtiene el estado de procesamiento de todos los archivos de conocimiento (polling endpoint)
      type: object

    GetMarketingSessionsArgs:
      description: |
        **get_marketing_sessions** [mass_marketing] (query)
        Obtiene las sesiones de WhatsApp disponibles para envío de campañas
      type: object
      properties:
        action:
          type: string
      required: ["action"]

    GetMassMarketingConfigArgs:
      description: |
        **get_mass_marketing_config** [mass_marketing] (query)
        Obtiene la configuracion actual de marketing masivo (auto-respuesta, texto de baja, aprobacion)
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
      required: ["action"]

    GetMassMarketingStatsArgs:
      description: |
        **get_mass_marketing_stats** [stats] (query)
        Estadisticas de campanas masivas: rendimiento por campana, desglose de fallos, distribucion horaria de envios, calidad de listas y balance de creditos disponibles
      type: object
      properties:
        date_from:
          type: string
          description: "Fecha inicio (YYYY-MM-DD). Default: hace 30 dias"
        date_to:
          type: string
          description: "Fecha fin (YYYY-MM-DD). Default: hoy"

    GetOnboardingStatusArgs:
      description: |
        **get_onboarding_status** [general] (query)
        Muestra el progreso de configuracion inicial del usuario (setup guide)
      type: object

    GetOverdueTasksArgs:
      description: |
        **get_overdue_tasks** [tasks] (query)
        Muestra todas las tareas pendientes cuya fecha limite ya paso
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        status:
          type: string
          description: "Estado de la tarea"
        agent_id:
          type: integer
          description: "ID del agente"
        phone:
          type: string
          description: "Telefono del cliente"
        limit:
          type: integer
          description: "Maximo de resultados"
        offset:
          type: integer
          description: "Posicion de inicio para paginacion"
        task_text:
          type: string
          description: "Texto de la tarea"
        due_date:
          type: string
          description: "Fecha limite YYYY-MM-DD"
        priority:
          type: string
          description: "Prioridad de la tarea"
          enum: ["low", "medium", "high"]
        assigned_agent_id:
          type: integer
          description: "ID del agente asignado"
        task_id:
          type: integer
          description: "ID de la tarea"
        include_completed:
          type: boolean
          description: "Incluir tareas completadas"
      required: ["action"]

    GetPeriodStatsArgs:
      description: |
        **get_period_stats** [activity] (query)
        Evolucion diaria de conversaciones y mensajes en un periodo
      type: object
      properties:
        action:
          type: string
        period:
          type: string
          enum: ["last_7_days", "last_30_days", "this_month", "last_month", "last_90_days", "all_time", "custom"]
          default: "last_7_days"
        date:
          type: string
          description: "Fecha de referencia YYYY-MM-DD"
        days:
          type: integer
          description: "Numero de dias del periodo"
        phone:
          type: string
          description: "Filtrar por telefono de cliente"
      required: ["action"]

    GetPluginChatSessionsArgs:
      description: |
        **get_plugin_chat_sessions** [plugins] (query)
        Obtiene las conversaciones cerradas del plugin de chat web para un teléfono específico. Útil cuando un agente quiere ver qué ha preguntado un cliente por el chat de la web.
      type: object
      properties:
        phone:
          type: string
          description: "Teléfono del cliente con prefijo + (ej: +34616083226)"
        page:
          type: integer
          description: "Número de página (default 1, 10 resultados por página)"
      required: ["phone"]

    GetPluginConversationDetailArgs:
      description: |
        **get_plugin_conversation_detail** [plugins] (query)
        Muestra los mensajes completos de una conversacion del plugin de chat web
      type: object
      properties:
        session_id:
          type: string
          description: "ID de la sesion de chat del plugin"
      required: ["session_id"]

    GetPluginConversationsArgs:
      description: |
        **get_plugin_conversations** [stats] (query)
        Muestra las conversaciones del plugin de chat web. Soporta filtros por periodo de tiempo.
      type: object
      properties:
        limit:
          type: integer
          description: "Numero maximo de conversaciones"
          default: 20
        period:
          type: string
          description: "Periodo: 1 (ultimo dia/hoy), 7 (ultima semana), 30 (ultimo mes), 90 (ultimos 3 meses), all (todas)"
          enum: ["1", "7", "30", "90", "all"]
          default: "30"
        date_from:
          type: string
          description: "Fecha inicio en formato YYYY-MM-DD"
        date_to:
          type: string
          description: "Fecha fin en formato YYYY-MM-DD"
        page:
          type: integer
          description: "Numero de pagina"

    GetPluginEmbedCodeArgs:
      description: |
        **get_plugin_embed_code** [plugins] (query)
        Genera el codigo de instalacion (embed code) para un plugin. Usalo cuando el usuario necesite el codigo para instalar Chat Web, Product Q&A o Doc Q&A en su web.
      type: object
      properties:
        plugin_type:
          type: string
          description: "Tipo de plugin: chat (Chat Web), product-qa (Product Q&A), doc-qa (Doc Q&A)"
          enum: ["chat", "product-qa", "doc-qa"]
      required: ["plugin_type"]

    GetPluginStatsArgs:
      description: |
        **get_plugin_stats** [plugins] (query)
        Metricas del plugin Product Q&A: preguntas, visitantes, productos mas consultados
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        period:
          type: string
          enum: ["today", "yesterday", "last_7_days", "last_30_days"]
          default: "last_7_days"
        plugin_type:
          type: string
          description: "Filtrar por tipo de plugin"
        limit:
          type: integer
          description: "Máximo de resultados"
        hours:
          type: integer
          description: "Ultimas N horas a analizar"
      required: ["action"]

    GetProductQaFaqsArgs:
      description: |
        **get_product_qa_faqs** [plugins] (query)
        Lista las FAQs publicadas del plugin Product Q&A, agrupadas por producto. Requiere que el plugin Product Q&A este configurado/activado.
      type: object
      properties:
        status:
          type: string
          description: "Filtrar por estado de la FAQ"
          enum: ["published", "unpublished", "all"]
          default: "published"
        product_id:
          type: string
          description: "Filtrar por ID de producto especifico"
        page:
          type: integer
          description: "Numero de pagina"
          default: 1
        limit:
          type: integer
          description: "FAQs por pagina (max 50)"
          default: 20

    GetProductQaQuestionsArgs:
      description: |
        **get_product_qa_questions** [stats] (query)
        Muestra las preguntas sobre productos. Soporta filtros por periodo de tiempo.
      type: object
      properties:
        limit:
          type: integer
          description: "Numero maximo de preguntas"
          default: 20
        period:
          type: string
          description: "Periodo de tiempo: today (solo hoy), 7 (ultimos 7 dias), 30 (ultimos 30 dias), 90 (ultimos 90 dias), all (todas)"
          enum: ["today", "7", "30", "90", "all"]
          default: "30"
        date_from:
          type: string
          description: "Fecha inicio en formato YYYY-MM-DD (tiene prioridad sobre period)"
        date_to:
          type: string
          description: "Fecha fin en formato YYYY-MM-DD (tiene prioridad sobre period)"
        page:
          type: integer
          description: "Numero de pagina"

    GetProductQaStatsArgs:
      description: |
        **get_product_qa_stats** [stats] (query)
        Muestra estadisticas del plugin de preguntas sobre productos
      type: object

    GetPromptArgs:
      description: |
        **get_prompt** [prompt] (query)
        Muestra el prompt actual de la IA
      type: object

    GetPromptHistoryArgs:
      description: |
        **get_prompt_history** [prompt] (query)
        Muestra las versiones anteriores del prompt
      type: object

    GetPurchaseHistoryArgs:
      description: |
        **get_purchase_history** [account] (query)
        Muestra el historial de compras de creditos
      type: object
      properties:
        page:
          type: integer
          description: "Pagina a mostrar (default: 1)"
        limit:
          type: integer
          description: "Registros por pagina (default: 20, max: 50)"

    GetRecentConversationsArgs:
      description: |
        **get_recent_conversations** [conversations] (query)
        Obtiene las conversaciones mas recientes ordenadas por ultima actividad
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        limit:
          type: integer
          description: "Cantidad de conversaciones (default 10, max 50)"
          default: 10
        hours:
          type: integer
          description: "Ventana de tiempo en horas (default 48)"
          default: 48
        query:
          type: string
          description: "Texto de busqueda"
        phone:
          type: string
          description: "Filtrar por telefono del cliente"
        date_from:
          type: string
          description: "Fecha inicio YYYY-MM-DD"
        date_to:
          type: string
          description: "Fecha fin YYYY-MM-DD"
        offset:
          type: integer
          description: "Posicion de inicio para paginacion"
        conversation_id:
          type: integer
          description: "ID de conversacion especifica"
        last_n:
          type: integer
          description: "Ultimos N mensajes"
        period:
          type: string
          description: "Periodo de tiempo"
          enum: ["today", "yesterday", "last_7_days"]
        agent_id:
          type: integer
          description: "ID del agente"
        message:
          type: string
          description: "Texto del mensaje a enviar o eliminar"
        format:
          type: string
          description: "Formato de respuesta"
      required: ["action"]

    GetRecentPluginQuestionsArgs:
      description: |
        **get_recent_plugin_questions** [plugins] (query)
        Muestra las ultimas preguntas que los clientes hicieron al plugin de Product Q&A
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        hours:
          type: integer
          default: 48
        limit:
          type: integer
          default: 20
        plugin_type:
          type: string
          description: "Filtrar por tipo de plugin"
        period:
          type: string
          description: "Periodo"
          enum: ["today", "yesterday", "last_7_days", "last_30_days"]
      required: ["action"]

    GetReferralDataArgs:
      description: |
        **get_referral_data** [referrals] (query)
        Muestra los referidos del usuario, comisiones pendientes y pagadas, y estado de solicitudes de pago
      type: object

    GetSentimentAnalysisArgs:
      description: |
        **get_sentiment_analysis** [ai_analysis] (query)
        Analiza el sentimiento e intencion del cliente en una conversacion usando IA. Devuelve score (0-10), categoria, intencion, consejo y urgencia. Consume creditos de IA.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        phone:
          type: string
          description: "Telefono del cliente (con o sin +)"
        summary_type:
          type: string
          description: "Tipo de resumen: quick (rapido), actionable (con acciones), detailed (detallado)"
          enum: ["quick", "actionable", "detailed"]
        days:
          type: integer
          description: "Numero de dias a analizar"
        tone:
          type: string
          description: "Tono para la respuesta"
        hours:
          type: integer
          description: "Ultimas N horas a analizar"
        limit:
          type: integer
          description: "Maximo de resultados"
        target_language:
          type: string
          description: "Idioma destino para traduccion"
        last_n:
          type: integer
          description: "Ultimos N mensajes a procesar"
      required: ["action", "phone"]

    GetSentimentTrendArgs:
      description: |
        **get_sentiment_trend** [ai_analysis] (query)
        Muestra la evolucion del sentimiento a lo largo del tiempo. Sin phone muestra tendencia global de todas las conversaciones.
      type: object
      properties:
        action:
          type: string
        phone:
          type: string
          description: "Telefono del cliente. Omitir para tendencia global."
        days:
          type: integer
          description: "Dias a analizar (default 30)"
        summary_type:
          type: string
          description: "Tipo de resumen: quick (rapido), actionable (con acciones), detailed (detallado)"
          enum: ["quick", "actionable", "detailed"]
        tone:
          type: string
          description: "Tono para la respuesta"
        hours:
          type: integer
          description: "Ultimas N horas a analizar"
        limit:
          type: integer
          description: "Maximo de resultados"
        target_language:
          type: string
          description: "Idioma destino para traduccion"
        last_n:
          type: integer
          description: "Ultimos N mensajes a procesar"
      required: ["action"]

    GetShopStatusArgs:
      description: |
        **get_shop_status** [general] (query)
        Obtiene el estado actual de la tienda: idioma, creditos, configuracion basica
      type: object

    GetSmartFollowupConfigArgs:
      description: |
        **get_smart_followup_config** [smart_followup] (query)
        Obtiene la configuracion actual del sistema de seguimiento inteligente (Smart Follow-up)
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        exclude_phones:
          type: array
          description: "Lista de telefonos excluidos del seguimiento"
        sending_window_start:
          type: string
          description: "Hora de inicio de ventana de envio (HH:MM)"
        sending_window_end:
          type: string
          description: "Hora de fin de ventana de envio (HH:MM)"
      required: ["action"]

    GetSmartFollowupLogsArgs:
      description: |
        **get_smart_followup_logs** [smart_followup] (query)
        Lista las acciones recientes de seguimiento inteligente: que clientes se contactaron, nivel de intencion, producto mencionado, resultado y mensaje enviado
      type: object
      properties:
        action:
          type: string
        page:
          type: integer
          description: "Numero de pagina (20 resultados por pagina, default 1)"
        intent_level:
          type: string
          description: "Filtrar por nivel de intencion: 'low', 'medium' o 'high'"
        action_taken:
          type: string
          description: "Filtrar por accion: 'message_sent', 'webhook_fired', 'logged_only' o 'skipped'"
        outcome:
          type: string
          description: "Filtrar por resultado: 'abandoned', 'unclear', 'converted' o 'support_only'"
        search:
          type: string
          description: "Buscar por telefono o producto mencionado"
        period:
          type: string
          description: "Periodo: 'today', 'yesterday', 'last_7_days', 'last_30_days', 'this_month', 'last_month', 'last_90_days', 'all_time' o 'custom'"
          enum: ["today", "yesterday", "last_7_days", "last_30_days", "this_month", "last_month", "last_90_days", "last_365_days", "all_time", "custom"]
        date_from:
          type: string
          description: "Fecha inicio (YYYY-MM-DD). Solo con period='custom'"
        date_to:
          type: string
          description: "Fecha fin (YYYY-MM-DD). Solo con period='custom'"
      required: ["action"]

    GetSmartFollowupStatsArgs:
      description: |
        **get_smart_followup_stats** [smart_followup] (query)
        Estadisticas de recuperacion de ventas: embudo de conversion, tasa de respuesta, productos mas mencionados, rendimiento por intento y desglose de motivos de omision
      type: object
      properties:
        action:
          type: string
        period:
          type: string
          description: "Periodo: 'today', 'yesterday', 'last_7_days', 'last_30_days', 'this_month', 'last_month', 'last_90_days', 'last_365_days', 'all_time' o 'custom'. Default: 'last_30_days'"
          enum: ["today", "yesterday", "last_7_days", "last_30_days", "this_month", "last_month", "last_90_days", "last_365_days", "all_time", "custom"]
        date_from:
          type: string
          description: "Fecha inicio (YYYY-MM-DD). Solo con period='custom'"
        date_to:
          type: string
          description: "Fecha fin (YYYY-MM-DD). Solo con period='custom'"
        page:
          type: integer
          description: "Numero de pagina"
        intent_level:
          type: string
          description: "Filtrar por nivel de intencion"
          enum: ["low", "medium", "high"]
        outcome:
          type: string
          description: "Filtrar por resultado"
        action_taken:
          type: string
          description: "Filtrar por accion tomada"
        search:
          type: string
          description: "Buscar en los registros"
      required: ["action"]

    GetSmartReplySuggestionsArgs:
      description: |
        **get_smart_reply_suggestions** [ai_analysis] (query)
        Genera 3 sugerencias de respuesta basadas en la conversacion actual
      type: object
      properties:
        action:
          type: string
        phone:
          type: string
          description: "Telefono del cliente"
        tone:
          type: string
          description: "Tono de las respuestas (default professional)"
          enum: ["professional", "friendly", "empathetic", "direct"]
        summary_type:
          type: string
          description: "Tipo de resumen: quick (rapido), actionable (con acciones), detailed (detallado)"
          enum: ["quick", "actionable", "detailed"]
        days:
          type: integer
          description: "Numero de dias a analizar"
        hours:
          type: integer
          description: "Ultimas N horas a analizar"
        limit:
          type: integer
          description: "Maximo de resultados"
        target_language:
          type: string
          description: "Idioma destino para traduccion"
        last_n:
          type: integer
          description: "Ultimos N mensajes a procesar"
      required: ["action", "phone"]

    GetStorageStatusArgs:
      description: |
        **get_storage_status** [storage] (query)
        Muestra el uso actual de almacenamiento y el plan activo
      type: object

    GetStructuredAnalyticsArgs:
      description: |
        **get_structured_analytics** [stats] (query)
        Obtiene analytics detallados de conversaciones usando structured outputs: KPIs, distribucion por intencion, sentimiento, urgencia, tendencia de satisfaccion y conversaciones recientes. Requiere que structured outputs este activado.
      type: object
      properties:
        date_from:
          type: string
          description: "Fecha inicio YYYY-MM-DD (default: hace 30 dias)"
        date_to:
          type: string
          description: "Fecha fin YYYY-MM-DD (default: hoy)"
        limit:
          type: integer
          description: "Cantidad de conversaciones recientes a incluir (default 50)"
          default: 50

    GetTasksSettingsArgs:
      description: |
        **get_tasks_settings** [tasks] (query)
        Consulta si el modulo de tareas esta activado para la tienda
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
      required: ["action"]

    GetTeamSummaryArgs:
      description: |
        **get_team_summary** [agents] (query)
        Vista general de todos los agentes con su carga de trabajo actual
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        agent_id:
          type: integer
          description: "ID del agente para filtrar"
        period:
          type: string
          description: "Periodo de tiempo"
          enum: ["today", "yesterday", "last_7_days", "last_30_days"]
        days:
          type: integer
          description: "Numero de dias a consultar"
      required: ["action"]

    GetTopAskedProductsArgs:
      description: |
        **get_top_asked_products** [products] (query)
        Muestra los productos sobre los que mas preguntan los clientes en el plugin Q&A
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        days:
          type: integer
          description: "Periodo en dias (default 30)"
          default: 30
        limit:
          type: integer
          default: 10
        query:
          type: string
          description: "Buscar por nombre de producto"
      required: ["action"]

    GetTopTopicsArgs:
      description: |
        **get_top_topics** [activity] (query)
        Muestra los temas/intenciones mas comunes en las conversaciones
      type: object
      properties:
        action:
          type: string
        days:
          type: integer
          description: "Dias a analizar (default 30)"
          default: 30
        period:
          type: string
          description: "Periodo: last_7_days, last_30_days, this_month, last_month, last_90_days, all_time, custom"
          enum: ["last_7_days", "last_30_days", "this_month", "last_month", "last_90_days", "all_time", "custom"]
        date:
          type: string
          description: "Fecha de referencia YYYY-MM-DD"
        phone:
          type: string
          description: "Filtrar por telefono de cliente"
      required: ["action"]

    GetTrainingSuggestionsArgs:
      description: |
        **get_training_suggestions** [knowledge] (query)
        List pending AI improvement suggestions generated by the automatic error detection system. These are proposed changes to workflows or the shop prompt that need owner review.
      type: object
      properties:
        status:
          type: string
          description: "Filter by status: pending, applied, dismissed. Default: pending"

    GetUnansweredConversationsArgs:
      description: |
        **get_unanswered_conversations** [conversations] (query)
        Muestra conversaciones donde el ultimo mensaje es del cliente (sin respuesta del agente/IA)
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        hours:
          type: integer
          description: "Buscar en las ultimas N horas (default 24)"
          default: 24
        limit:
          type: integer
          description: "Maximo de resultados (default 20)"
          default: 20
        query:
          type: string
          description: "Texto de busqueda"
        phone:
          type: string
          description: "Filtrar por telefono del cliente"
        date_from:
          type: string
          description: "Fecha inicio YYYY-MM-DD"
        date_to:
          type: string
          description: "Fecha fin YYYY-MM-DD"
        offset:
          type: integer
          description: "Posicion de inicio para paginacion"
        conversation_id:
          type: integer
          description: "ID de conversacion especifica"
        last_n:
          type: integer
          description: "Ultimos N mensajes"
        period:
          type: string
          description: "Periodo de tiempo"
          enum: ["today", "yesterday", "last_7_days"]
        agent_id:
          type: integer
          description: "ID del agente"
        message:
          type: string
          description: "Texto del mensaje a enviar o eliminar"
        format:
          type: string
          description: "Formato de respuesta"
      required: ["action"]

    GetUnansweredPluginQuestionsArgs:
      description: |
        **get_unanswered_plugin_questions** [plugins] (query)
        Identifica preguntas donde el bot no pudo dar una respuesta satisfactoria
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        limit:
          type: integer
          default: 20
        plugin_type:
          type: string
          description: "Filtrar por tipo de plugin"
        period:
          type: string
          description: "Periodo"
          enum: ["today", "yesterday", "last_7_days", "last_30_days"]
        hours:
          type: integer
          description: "Horas a analizar"
      required: ["action"]

    GetUnreadNotificationCountArgs:
      description: |
        **get_unread_notification_count** [notifications] (query)
        Obtiene el numero de notificaciones pendientes de leer
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        limit:
          type: integer
          description: "Maximo de resultados"
        offset:
          type: integer
          description: "Posicion de inicio"
        filter:
          type: string
          description: "Filtro de notificaciones"
        type:
          type: string
          description: "Tipo de notificacion"
        notification_id:
          type: integer
          description: "ID de la notificacion"
        agent_id:
          type: integer
          description: "ID del agente"
      required: ["action"]

    GetUnsubscribedListArgs:
      description: |
        **get_unsubscribed_list** [mass_marketing] (query)
        Obtiene la lista de contactos que se han dado de baja de los envios masivos de la tienda
      type: object
      properties:
        action:
          type: string
          description: "Accion fija: get_unsubscribed"
        page:
          type: integer
          description: "Numero de pagina para paginacion (default: 1)"
        search:
          type: string
          description: "Filtrar por numero de telefono"
        date_from:
          type: string
          description: "Fecha inicio filtro (formato YYYY-MM-DD)"
        date_to:
          type: string
          description: "Fecha fin filtro (formato YYYY-MM-DD)"
      required: ["action"]

    GetUsageStatsArgs:
      description: |
        **get_usage_stats** [stats] (query)
        Muestra el uso de creditos, tokens y costes de los ultimos dias
      type: object
      properties:
        action:
          type: string
          description: "summary para resumen diario, detail para detalle individual"
          default: "summary"
        from:
          type: string
          description: "Fecha inicio YYYY-MM-DD (default: hace 7 dias)"
        to:
          type: string
          description: "Fecha fin YYYY-MM-DD (default: hoy)"
        page:
          type: integer
          description: "Numero de pagina"
        limit:
          type: integer
          description: "Resultados por pagina"

    GetUsageStatsDetailArgs:
      description: |
        **get_usage_stats_detail** [stats] (query)
        Muestra el detalle individual de cada consulta de IA con tokens y costes
      type: object
      properties:
        action:
          type: string
        from:
          type: string
          description: "Fecha inicio YYYY-MM-DD"
        to:
          type: string
          description: "Fecha fin YYYY-MM-DD"
        page:
          type: integer
          description: "Número de página"
        limit:
          type: integer
          description: "Resultados por página"
      required: ["action"]

    GetVoiceAssistantConfigArgs:
      description: |
        **get_voice_assistant_config** [voice] (query)
        Devuelve el payload sanitizado del assistant de Vapi de la tienda (modelo, voz, transcriptor, herramientas y mensajes), tal y como WAzion lo provisiona. Opcionalmente lo entrega como archivo descargable.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        download:
          type: boolean
          description: "Si es true, marca la respuesta para descarga como archivo JSON."
      required: ["action"]

    GetVoiceCallArgs:
      description: |
        **get_voice_call** [voice] (query)
        Devuelve una llamada de voz concreta con su transcripcion completa y el registro de tools que ejecuto el asistente durante la llamada.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        call_id:
          type: string
          description: "Identificador de la llamada a consultar"
      required: ["action", "call_id"]

    GetVoiceConfigArgs:
      description: |
        **get_voice_config** [voice] (query)
        Devuelve la configuracion actual del asistente de voz (Vapi BYOK): activo, assistant_id, public_key, idiomas, voces, reglas, herramientas habilitadas, transferencia humana, plantilla follow-up, URL webhook y estadisticas.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
      required: ["action"]

    GetVoiceLibraryArgs:
      description: |
        **get_voice_library** [voice] (query)
        Devuelve el catalogo curado de voces compatibles con Vapi por idioma, los transcriptores disponibles y los textos de previsualizacion. Util para elegir voz y transcriptor al configurar el asistente de voz.
      type: object

    GetWebhookConfigArgs:
      description: |
        **get_webhook_config** [advanced] (query)
        Lee la configuracion actual de webhooks de la tienda: si estan activados, URL configurada, eventos suscritos y si tiene secret. Usa esta accion SIEMPRE antes de configurar o modificar webhooks, y cuando el usuario pregunte sobre su configuracion de webhooks.
      type: object

    GetWhatsappActiveChatsArgs:
      description: |
        **get_whatsapp_active_chats** [whatsapp_ops] (query)
        Devuelve los chats activos de WhatsApp, entendidos como chats no archivados en la bandeja real de WhatsApp. Ideal para que un MCP o LLM priorice urgencias sin mezclar chats viejos con chats realmente activos.
      type: object
      properties:
        action:
          type: string
        session_id:
          type: integer
          description: "ID de sesion especifica (opcional). Si se omite, consulta todos los chats activos de la tienda usando una sesion conectada valida."
        limit:
          type: integer
          description: "Numero maximo de chats a devolver (1-200)"
          default: 25
        offset:
          type: integer
          description: "Desplazamiento para paginacion"
          default: 0
        include_recent_messages:
          type: boolean
          description: "Si true, incluye unos pocos mensajes recientes por chat para poder priorizar urgencia sin hacer una llamada extra por cada numero."
        messages_per_chat:
          type: integer
          description: "Cuantos mensajes recientes incluir por chat cuando include_recent_messages=true (1-10)"
          default: 3
      required: ["action"]

    GetWhatsappChatArchiveStatusArgs:
      description: |
        **get_whatsapp_chat_archive_status** [whatsapp_ops] (query)
        Consulta si el chat de WhatsApp de un telefono esta archivado actualmente. La API resuelve automaticamente la sesion conectada y devuelve true, false o null si WhatsApp no tiene estado local suficiente.
      type: object
      properties:
        action:
          type: string
        phone:
          type: string
          description: "Telefono del chat a consultar en formato E.164 o con prefijo internacional (ej: +34612345678). OBLIGATORIO"
        session_id:
          type: integer
          description: "ID de sesion especifica (opcional). Si se omite, la API usa la sesion conectada mas reciente para ese telefono o la primera conectada"
      required: ["action", "phone"]

    GetWhatsappConnectionStatusArgs:
      description: |
        **get_whatsapp_connection_status** [whatsapp_ops] (query)
        Muestra todas las sesiones de WhatsApp de la tienda con su estado actual (conectado, desconectado, pendiente QR)
      type: object

    GetWhatsappConversationHistoryArgs:
      description: |
        **get_whatsapp_conversation_history** [automation] (query)
        Muestra el historial de mensajes de WhatsApp con un telefono especifico
      type: object
      properties:
        phone:
          type: string
          description: "Numero de telefono (con codigo de pais, ej: +34600123456)"
        limit:
          type: integer
          description: "Cantidad maxima de mensajes a mostrar (1-100)"
          default: 50
      required: ["phone"]

    GetWhatsappHealthArgs:
      description: |
        **get_whatsapp_health** [whatsapp_ops] (query)
        Estado combinado de sesiones, actividad de mensajes 24h y workflows activos
      type: object
      properties:
        action:
          type: string
        session_id:
          type: integer
          description: "ID de sesion de WhatsApp"
        direction:
          type: string
          description: "Filtrar por direccion"
        phone:
          type: string
          description: "Filtrar por telefono"
      required: ["action"]

    GetWhatsappLiveChatMessagesArgs:
      description: |
        **get_whatsapp_live_chat_messages** [whatsapp_ops] (query)
        Obtiene los mensajes recientes de un chat directamente desde el VPS de WhatsApp, combinando memoria viva y logs recientes. Sirve para analizar urgencia o contexto actual sin depender solo del historial persistido.
      type: object
      properties:
        action:
          type: string
        phone:
          type: string
          description: "Telefono del chat en formato E.164 o con prefijo internacional (ej: +34612345678). OBLIGATORIO"
        limit:
          type: integer
          description: "Numero maximo de mensajes a devolver (1-200)"
          default: 50
        session_id:
          type: integer
          description: "ID de sesion especifica (opcional). Si se omite, la API resuelve automaticamente la sesion conectada mas adecuada para ese telefono."
      required: ["action", "phone"]

    GetWhatsappMessageLogsArgs:
      description: |
        **get_whatsapp_message_logs** [whatsapp_ops] (query)
        Muestra los ultimos mensajes enviados y recibidos por WhatsApp
      type: object
      properties:
        action:
          type: string
        direction:
          type: string
          description: "Filtrar por direccion del mensaje"
          enum: ["incoming", "outgoing"]
        phone:
          type: string
          description: "Filtrar por numero de telefono"
        hours:
          type: integer
          description: "Ultimas N horas (default 24)"
          default: 24
        limit:
          type: integer
          default: 50
        session_id:
          type: integer
          description: "ID de la sesión WhatsApp"
        days:
          type: integer
          description: "Numero de dias de lookback"
        message:
          type: string
          description: "Buscar en contenido del mensaje"
      required: ["action"]

    GetWhatsappOutboundDeliveryStatusArgs:
      description: |
        **get_whatsapp_outbound_delivery_status** [whatsapp_ops] (query)
        Consulta y reconcilia el ledger durable de un envio WhatsApp mediante idempotency_key, siempre limitado a la tienda autenticada. Es el metodo preferido cuando el envio queda queued, retry_sending o sent_unconfirmed, incluso si el VPS no devolvio queue_id. Solo sent con message_id confirma envio fisico.
      type: object
      properties:
        action:
          type: string
        idempotency_key:
          type: string
          description: "Clave estable usada al enviar. Para Vicshop: vicshop-wa-queue-{IdQueue}."
      required: ["action", "idempotency_key"]

    GetWhatsappOutboundDeliveryStatusShortArgs:
      description: |
        **get_whatsapp_outbound_delivery_status_short** [whatsapp_ops] (query)
        Alias de get_whatsapp_outbound_delivery_status: consulta y reconcilia el ledger durable de un envio WhatsApp mediante idempotency_key, siempre limitado a la tienda autenticada. Mismo comportamiento que la version larga.
      type: object
      properties:
        action:
          type: string
        idempotency_key:
          type: string
          description: "Clave estable usada al enviar. Para Vicshop: vicshop-wa-queue-{IdQueue}."
      required: ["action", "idempotency_key"]

    GetWhatsappOutboundPolicyArgs:
      description: |
        **get_whatsapp_outbound_policy** [whatsapp_ops] (query)
        Muestra la política de envío saliente: modo, número con rol General, orígenes, pie de no respuesta y disponibilidad por rol lógico.
      type: object

    GetWhatsappOutboundQueueStatusArgs:
      description: |
        **get_whatsapp_outbound_queue_status** [whatsapp_ops] (query)
        Consulta el estado real de un mensaje de WhatsApp aceptado en cola por el guardrail anti-bloqueo. Usalo cuando send_whatsapp_message devuelva queued:true o status:'queued'. Solo debe considerarse enviado real cuando status sea 'sent' y message_id tenga valor.
      type: object
      properties:
        action:
          type: string
        queue_id:
          type: integer
          description: "queue_id devuelto por send_whatsapp_message cuando queued=true"
      required: ["action", "queue_id"]

    GetWhatsappProfileArgs:
      description: |
        **get_whatsapp_profile** [whatsapp_ops] (query)
        Obtiene el perfil de WhatsApp de una sesion conectada: nombre, foto, estado/info, y datos de empresa si es WhatsApp Business (descripcion, direccion, email, web, horario)
      type: object
      properties:
        session_id:
          type: integer
          description: "ID de la sesion WhatsApp conectada"
      required: ["session_id"]

    GetWhatsappQrArgs:
      description: |
        **get_whatsapp_qr** [automation] (query)
        Obtiene el codigo QR de WhatsApp para que el usuario lo escanee. IMPORTANTE: Requiere que exista una sesion previa (estado qr_pending). Si no hay sesion, usa connect_whatsapp primero para crear una. Si ya esta conectado, informa del estado. Devuelve una URL de imagen que puedes mostrar inline con ![QR WhatsApp](url).
      type: object

    GetWhatsappResponseTimeStatsArgs:
      description: |
        **get_whatsapp_response_time_stats** [whatsapp_ops] (query)
        Muestra la distribucion horaria de mensajes entrantes y salientes de WhatsApp
      type: object
      properties:
        action:
          type: string
        days:
          type: integer
          description: "Dias a analizar (default 7)"
        session_id:
          type: integer
          description: "ID de la sesión WhatsApp"
        direction:
          type: string
          description: "Filtrar por direccion"
        phone:
          type: string
          description: "Filtrar por telefono"
      required: ["action"]

    GetWhatsappStatusArgs:
      description: |
        **get_whatsapp_status** [whatsapp_ops] (query)
        Muestra el estado de todas las sesiones de WhatsApp conectadas
      type: object
      properties:
        action:
          type: string
        session_id:
          type: integer
          description: "ID de sesion WhatsApp especifica"
        direction:
          type: string
          description: "Filtrar por direccion (incoming/outgoing)"
        phone:
          type: string
          description: "Filtrar por telefono"
      required: ["action"]

    GetWhatsappTemplateArgs:
      description: |
        **get_whatsapp_template** [whatsapp_ops] (query)
        Obtiene el detalle de una plantilla de mensaje especifica
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        id:
          type: integer
          description: "ID de la plantilla"
      required: ["action", "id"]

    GetWhatsappWorkflowActivityArgs:
      description: |
        **get_whatsapp_workflow_activity** [whatsapp_ops] (query)
        Muestra estadísticas de ejecución de los workflows de WhatsApp en un periodo
      type: object
      properties:
        action:
          type: string
        days:
          type: integer
          description: "Días a analizar (default: 7)"
        session_id:
          type: integer
          description: "ID de la sesion WhatsApp"
        direction:
          type: string
          description: "Filtrar por direccion"
        phone:
          type: string
          description: "Filtrar por telefono"
      required: ["action"]

    GetWhatsappWorkflowLogsArgs:
      description: |
        **get_whatsapp_workflow_logs** [automation] (query)
        Obtiene el historial de ejecuciones de workflows de WhatsApp Auto con filtros de fecha
      type: object
      properties:
        limit:
          type: integer
          description: "Numero maximo de logs a devolver (1-100)"
          default: 20
        offset:
          type: integer
          description: "Desplazamiento para paginacion"
          default: 0
        period:
          type: string
          description: "Periodo: 'today' o numero de dias (ej: '7' para ultimos 7 dias)"
        from:
          type: string
          description: "Fecha desde (formato: YYYY-MM-DD)"
        to:
          type: string
          description: "Fecha hasta (formato: YYYY-MM-DD)"

    GetWhatsappWorkflowStatsArgs:
      description: |
        **get_whatsapp_workflow_stats** [stats] (query)
        Get WhatsApp message volume, workflow execution stats, peak hours, and performance metrics
      type: object
      properties:
        action:
          type: string
        period:
          type: integer
          description: "Number of days: 7, 30, or 90. Default: 7"
        limit:
          type: integer
          description: "Numero maximo de resultados"
        offset:
          type: integer
          description: "Desplazamiento para paginacion"
        from:
          type: string
          description: "Fecha inicio (YYYY-MM-DD)"
        to:
          type: string
          description: "Fecha fin (YYYY-MM-DD)"
      required: ["action"]

    GetWorkflowLogsArgs:
      description: |
        **get_workflow_logs** [whatsapp_ops] (query)
        Muestra las ejecuciones recientes de workflows automaticos de WhatsApp
      type: object
      properties:
        action:
          type: string
        hours:
          type: integer
          description: "Ultimas N horas (default 24)"
          default: 24
        limit:
          type: integer
          default: 50
        session_id:
          type: integer
          description: "ID de la sesión WhatsApp"
        days:
          type: integer
          description: "Numero de dias de lookback"
        direction:
          type: string
          description: "Filtrar por direccion"
        phone:
          type: string
          description: "Filtrar por telefono"
      required: ["action"]

    GetWorkflowSessionStatsArgs:
      description: |
        **get_workflow_session_stats** [automation] (query)
        Obtiene estadísticas de workflows para una sesión específica de WhatsApp: mensajes de hoy, ejecuciones, volumen de 7 días
      type: object
      properties:
        action:
          type: string
        session_id:
          type: integer
          description: "ID de la sesión WhatsApp"
      required: ["action", "session_id"]

    GlobalSearchArgs:
      description: |
        **global_search** [customers] (query)
        Busca en todas las fuentes de datos de clientes: CRM, contactos, conversaciones. Devuelve resultados unificados sin duplicados.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        query:
          type: string
          description: "Texto de busqueda (minimo 2 caracteres). Busca en nombre, email, telefono y comentarios."
        phone:
          type: string
          description: "Telefono del cliente"
        comment:
          type: string
          description: "Texto del comentario"
        agent_name:
          type: string
          description: "Nombre del agente"
        limit:
          type: integer
          description: "Maximo de resultados"
        tag_name:
          type: string
          description: "Nombre del tag"
        tag_color:
          type: string
          description: "Color del tag en formato hexadecimal"
        primary_phone:
          type: string
          description: "Telefono principal para merge"
        secondary_phone:
          type: string
          description: "Telefono secundario para merge"
      required: ["action", "query"]

    ImportContactsCsvArgs:
      description: |
        **import_contacts_csv** [mass_marketing] (mutation)
        Importa contactos a una lista de marketing desde un archivo CSV
      type: object
      properties:
        source:
          type: string
          description: "Fuente de importacion"
        list_id:
          type: integer
          description: "ID de la lista de contactos destino"
        file:
          type: string
          description: "Archivo CSV a importar (multipart/form-data)"
      required: ["source", "list_id", "file"]

    ImportContactsFromAllConversationsArgs:
      description: |
        **import_contacts_from_all_conversations** [mass_marketing] (mutation)
        Importa todos los contactos de conversaciones de WhatsApp a una lista de marketing
      type: object
      properties:
        source:
          type: string
          description: "Fuente fija"
        list_id:
          type: integer
          description: "ID de la lista destino"
      required: ["source", "list_id"]

    ImportContactsFromConversationsArgs:
      description: |
        **import_contacts_from_conversations** [mass_marketing] (mutation)
        Importa contactos seleccionados desde conversaciones de WhatsApp a una lista de marketing
      type: object
      properties:
        source:
          type: string
          description: "Fuente fija"
        list_id:
          type: integer
          description: "ID de la lista destino"
      required: ["source", "list_id"]

    ImportContactsFromCrmArgs:
      description: |
        **import_contacts_from_crm** [mass_marketing] (mutation)
        Importa contactos del CRM interno de WAzion a una lista de marketing masivo
      type: object
      properties:
        source:
          type: string
          description: "Fuente fija"
        list_id:
          type: integer
          description: "ID de la lista destino"
      required: ["source", "list_id"]

    ImportContactsFromPlatformArgs:
      description: |
        **import_contacts_from_platform** [mass_marketing] (mutation)
        Importa contactos de clientes desde la plataforma ecommerce conectada (Shopify, WooCommerce, etc.)
      type: object
      properties:
        source:
          type: string
          description: "Fuente fija"
        list_id:
          type: integer
          description: "ID de la lista destino"
      required: ["source", "list_id"]

    ImportContactsManualArgs:
      description: |
        **import_contacts_manual** [mass_marketing] (mutation)
        Importa contactos a una lista de marketing masivo escribiendo los telefonos manualmente
      type: object
      properties:
        source:
          type: string
          description: "Fuente fija"
        list_id:
          type: integer
          description: "ID de la lista destino"
        phones:
          type: string
          description: "Telefonos a importar, uno por linea o separados por comas. Incluir prefijo internacional (ej: +34600000000)"
      required: ["source", "list_id", "phones"]

    ImportContactsTxtArgs:
      description: |
        **import_contacts_txt** [mass_marketing] (mutation)
        Importa contactos a una lista de marketing desde un archivo de texto (un telefono por linea)
      type: object
      properties:
        source:
          type: string
          description: "Fuente de importacion"
        list_id:
          type: integer
          description: "ID de la lista de contactos destino"
        file:
          type: string
          description: "Archivo TXT a importar (multipart/form-data)"
      required: ["source", "list_id", "file"]

    ImportCrmContactsArgs:
      description: |
        **import_crm_contacts** [crm] (mutation)
        Importa contactos al CRM interno desde un archivo CSV
      type: object
      properties:
        file:
          type: string
          description: "Archivo CSV a importar (multipart/form-data)"
        skip_header:
          type: boolean
          description: "Omitir la primera fila como encabezado (default: true)"
        update_existing:
          type: boolean
          description: "Actualizar contactos existentes si ya existen (default: false)"
      required: ["file"]

    ImportMappedContactsArgs:
      description: |
        **import_mapped_contacts** [mass_marketing] (mutation)
        Importa contactos desde un archivo CSV previamente previsualizado, especificando que columna contiene el telefono y el nombre
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        list_id:
          type: integer
          description: "ID de la lista de contactos destino"
        tmp_id:
          type: string
          description: "ID temporal del archivo obtenido en la previsualizacion"
        phone_column:
          type: integer
          description: "Indice de la columna que contiene los telefonos"
        name_column:
          type: integer
          description: "Indice de la columna que contiene los nombres"
      required: ["action", "list_id", "tmp_id", "phone_column"]

    ImportMarketingContactsArgs:
      description: |
        **import_marketing_contacts** [mass_marketing] (mutation)
        Importa contactos a una lista de marketing masivo. Soporta entrada manual de telefonos o importacion desde conversaciones.
      type: object
      properties:
        source:
          type: string
          description: "Origen de importacion: manual (texto libre), conversations (desde historial WhatsApp), csv (archivo CSV), txt (archivo de texto)"
          enum: ["manual", "conversations", "csv", "txt"]
        list_id:
          type: integer
          description: "ID de la lista destino"
        phones_text:
          type: string
          description: "Para source=manual: telefonos separados por saltos de linea, uno por linea"
        phones:
          type: array
          description: "Array de teléfonos a importar (para source=manual)"
        tmp_id:
          type: string
          description: "ID temporal del archivo previamente subido (para importación con mapeo)"
        phone_column:
          type: string
          description: "Nombre de la columna de teléfono en el CSV"
        name_column:
          type: string
          description: "Nombre de la columna de nombre en el CSV"
      required: ["source", "list_id"]

    ImportVapiVoiceConfigArgs:
      description: |
        **import_vapi_voice_config** [voice] (mutation)
        Lee el assistant actual en Vapi con la API key guardada y sincroniza hacia WAzion solo los campos seguros soportados: modelo, voz, transcriptor, keyterms, ruido, tiempos y limites.
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        voice_assistant_id:
          type: string
          description: "Assistant ID de Vapi a importar. Si se omite, usa el assistant guardado en la tienda."
      required: ["action"]

    ImprovePromptArgs:
      description: |
        **improve_prompt** [prompt] (query)
        Analiza el prompt actual con IA y devuelve puntuaciones por categoria, sugerencias de mejora y una version mejorada del prompt. Util cuando el usuario quiere saber si su prompt es bueno o como mejorarlo.
      type: object
      properties:
        prompt:
          type: string
          description: "El prompt a analizar. Si no lo proporciona el usuario, usar el prompt actual (obtener con get_prompt primero)"
      required: ["prompt"]

    KeepBothKnowledgeSnippetsArgs:
      description: |
        **keep_both_knowledge_snippets** [knowledge] (mutation)
        Mantiene ambos snippets en conflicto activando los dos
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        id:
          type: integer
          description: "ID del snippet en conflicto"
      required: ["action", "id"]

    LinkAiTicketFileArgs:
      description: |
        **link_ai_ticket_file** [tickets] (mutation)
        Adjunta un archivo de la conversacion al ticket interno. La visibilidad controla si el archivo es solo interno o candidato a enviarse al cliente.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        ticket_id:
          type: integer
          description: "ID del ticket"
        conversation_file_id:
          type: integer
          description: "ID del archivo de conversacion a vincular"
        visibility:
          type: string
          description: "Visibilidad del adjunto"
          enum: ["internal", "customer_candidate"]
          default: "internal"
      required: ["action", "ticket_id", "conversation_file_id"]

    LinkEmailContactArgs:
      description: |
        **link_email_contact** [email] (mutation)
        Vincula un contacto de WhatsApp a un hilo de email para asociar conversaciones
      type: object
      properties:
        thread_id:
          type: integer
          description: "ID del hilo de email"
        phone:
          type: string
          description: "Telefono del contacto a vincular (con prefijo +)"
      required: ["thread_id", "phone"]

    LinkOauthCalendarArgs:
      description: |
        **link_oauth_calendar** [calendar] (mutation)
        Vincula un calendario externo (Google/Microsoft) a la tienda
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        connection_id:
          type: integer
          description: "ID de la conexion OAuth"
        external_calendar_id:
          type: string
          description: "ID del calendario externo a vincular"
        name:
          type: string
          description: "Nombre personalizado para el calendario"
      required: ["action", "connection_id", "external_calendar_id"]

    ListAgentsArgs:
      description: |
        **list_agents** [agents] (query)
        Lista todos los agentes del comercio con detalles de perfil y permisos
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
      required: ["action"]

    ListAgentsJsonArgs:
      description: |
        **list_agents_json** [agents] (query)
        Devuelve todos los agentes configurados en formato JSON con sus datos completos: nombre, email, teléfono, color, permisos y si tienen PIN.
      type: object
      properties:
        action:
          type: string
          description: "Acción fija"
      required: ["action"]

    ListAiTicketsArgs:
      description: |
        **list_ai_tickets** [tickets] (query)
        Lista tickets internos IA-agente. Usa phone para filtrar por cliente actual o queue para bandejas open, mine, unassigned, urgent, overdue o closed.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        queue:
          type: string
          description: "Bandeja a listar"
          enum: ["open", "mine", "unassigned", "urgent", "overdue", "closed"]
        phone:
          type: string
          description: "Telefono del cliente para filtrar"
        search:
          type: string
          description: "Busqueda por UID, titulo, descripcion, telefono o email"
        limit:
          type: integer
          description: "Limite de resultados, maximo 100"
      required: ["action"]

    ListBlacklistArgs:
      description: |
        **list_blacklist** [mass_marketing] (query)
        Obtiene los numeros bloqueados manualmente que no recibiran campanas masivas, distinta de las bajas voluntarias
      type: object
      properties:
        action:
          type: string
          description: "Accion fija: list"
        search:
          type: string
          description: "Filtrar por numero de telefono"
        page:
          type: integer
          description: "Pagina de resultados"
          default: 1
      required: ["action"]

    ListCalendarAgentsArgs:
      description: |
        **list_calendar_agents** [calendar] (query)
        Lista agentes asignados a un calendario especifico con sus roles
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        calendar_id:
          type: integer
          description: "ID del calendario"
      required: ["action", "calendar_id"]

    ListCalendarAvailabilityArgs:
      description: |
        **list_calendar_availability** [calendar] (query)
        Lista todas las reglas de disponibilidad de un calendario (horarios, excepciones, bloqueos)
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        calendar_id:
          type: integer
          description: "ID del calendario"
      required: ["action", "calendar_id"]

    ListCalendarConnectionsArgs:
      description: |
        **list_calendar_connections** [calendar] (query)
        List all connected calendar providers (Google, Microsoft) for this shop
      type: object
      properties:
        action:
          type: string
      required: ["action"]

    ListCalendarEventsArgs:
      description: |
        **list_calendar_events** [calendar] (query)
        List upcoming appointments/events in a date range
      type: object
      properties:
        action:
          type: string
        from:
          type: string
          description: "Start date YYYY-MM-DD"
        to:
          type: string
          description: "End date YYYY-MM-DD"
        status:
          type: string
          description: "Filtrar por estado: pending, confirmed, cancelled, completed, no_show"
      required: ["action"]

    ListCalendarEventsOpsArgs:
      description: |
        **list_calendar_events_ops** [calendar] (query)
        Lista eventos del calendario para un rango de fechas, con filtrado por agente o telefono
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        date_from:
          type: string
          description: "Fecha inicio YYYY-MM-DD"
        date_to:
          type: string
          description: "Fecha fin YYYY-MM-DD"
        agent_id:
          type: integer
          description: "Filtrar por ID de agente"
        phone:
          type: string
          description: "Filtrar por telefono del cliente"
        title:
          type: string
          description: "Titulo del evento"
        description:
          type: string
          description: "Descripcion del evento"
        start_datetime:
          type: string
          description: "Fecha/hora inicio"
        end_datetime:
          type: string
          description: "Fecha/hora fin"
        all_day:
          type: boolean
          description: "Si es evento de dia completo"
        assigned_agent_id:
          type: integer
          description: "ID del agente asignado"
        event_id:
          type: integer
          description: "ID del evento"
      required: ["action"]

    ListCalendarNotificationsArgs:
      description: |
        **list_calendar_notifications** [calendar] (query)
        Lista las notificaciones configuradas para un calendario (confirmaciones, recordatorios, etc.)
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        calendar_id:
          type: integer
          description: "ID del calendario"
      required: ["action", "calendar_id"]

    ListCalendarServicesArgs:
      description: |
        **list_calendar_services** [calendar] (query)
        List all appointment types/services configured for a calendar
      type: object
      properties:
        action:
          type: string
        calendar_id:
          type: integer
          description: "Calendar ID"
      required: ["action", "calendar_id"]

    ListCalendarsArgs:
      description: |
        **list_calendars** [calendar] (query)
        Lista todos los calendarios disponibles con conteo de servicios y eventos proximos
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
      required: ["action"]

    ListCampaignsArgs:
      description: |
        **list_campaigns** [mass_marketing] (query)
        Obtiene todas las campanas de marketing masivo de la tienda
      type: object
      properties:
        action:
          type: string
          description: "Accion fija: list"
      required: ["action"]

    ListContactListsArgs:
      description: |
        **list_contact_lists** [mass_marketing] (query)
        Obtiene todas las listas de contactos de marketing masivo de la tienda
      type: object
      properties:
        action:
          type: string
          description: "Accion fija: list"
        page:
          type: integer
          description: "Numero de pagina"
        search:
          type: string
          description: "Texto de busqueda"
      required: ["action"]

    ListConversationFilesArgs:
      description: |
        **list_conversation_files** [storage] (query)
        Lista los archivos compartidos en una conversacion con un cliente
      type: object
      properties:
        phone:
          type: string
          description: "Telefono del cliente para filtrar archivos"
        limit:
          type: integer
          default: 50
        offset:
          type: integer
          description: "Posicion de inicio para paginacion"
          default: 0

    ListDocqaAssistantsArgs:
      description: |
        **list_docqa_assistants** [plugins] (query)
        Muestra todos los asistentes de documentacion creados con el plugin Doc Q&A
      type: object

    ListDocqaFilesArgs:
      description: |
        **list_docqa_files** [plugins] (query)
        Lista los archivos subidos a un asistente Doc-QA
      type: object
      properties:
        assistant_id:
          type: integer
          description: "ID del asistente Doc-QA"
      required: ["assistant_id"]

    ListEmailAccountsArgs:
      description: |
        **list_email_accounts** [email] (query)
        Devuelve todas las cuentas de correo electronico configuradas en la tienda, con sus agentes asignados.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
      required: ["action"]

    ListEmailDraftsArgs:
      description: |
        **list_email_drafts** [email] (query)
        Muestra los borradores de email pendientes de envio.
      type: object
      properties:
        filter:
          type: string
          description: "Debe ser 'drafts'"
        account_id:
          type: integer
          description: "Filtrar por cuenta de email"
        page:
          type: integer
          description: "Pagina para paginacion"
        limit:
          type: integer
          description: "Limite de resultados por pagina"
        search:
          type: string
          description: "Buscar en asunto y contenido"
        from_filter:
          type: string
          description: "Filtrar por remitente"
        has_attachments:
          type: string
          description: "Filtrar por borradores con adjuntos"
        tag:
          type: string
          description: "Filtrar por etiqueta"
        assigned:
          type: string
          description: "Filtrar por agente asignado"
        date_from:
          type: string
          description: "Fecha inicio del filtro"
        date_to:
          type: string
          description: "Fecha fin del filtro"
      required: ["filter"]

    ListEmailNotesArgs:
      description: |
        **list_email_notes** [email] (query)
        Obtiene las notas internas de un hilo de email. Las notas son visibles solo para agentes, no para el cliente.
      type: object
      properties:
        thread_id:
          type: integer
          description: "ID del hilo"
        note_text:
          type: string
          description: "Texto de la nota"
        agent_name:
          type: string
          description: "Nombre del agente"
        agent_color:
          type: string
          description: "Color del agente"
        avatar_url:
          type: string
          description: "URL del avatar"
      required: ["thread_id"]

    ListEmailRulesArgs:
      description: |
        **list_email_rules** [email] (query)
        Lista todas las reglas automaticas de email configuradas para la tienda. Las reglas se aplican a los emails entrantes en orden de prioridad.
      type: object

    ListEmailThreadsArgs:
      description: |
        **list_email_threads** [email] (query)
        Lista los hilos de email de la tienda, con filtros por estado y cuenta
      type: object
      properties:
        filter:
          type: string
          description: "Filtro: unread, read, all (default: all)"
        account_id:
          type: integer
          description: "ID de cuenta para filtrar"
        search:
          type: string
          description: "Buscar por asunto o remitente"
        page:
          type: integer
          description: "Pagina (default: 1)"
        limit:
          type: integer
          description: "Resultados por pagina (default: 20)"
        from_filter:
          type: string
          description: "Filtrar por remitente"
        has_attachments:
          type: string
          description: "Filtrar por hilos con adjuntos"
        tag:
          type: string
          description: "Filtrar por etiqueta"
        assigned:
          type: string
          description: "Filtrar por agente asignado"
        date_from:
          type: string
          description: "Fecha inicio del filtro"
        date_to:
          type: string
          description: "Fecha fin del filtro"

    ListKnowledgeFilesArgs:
      description: |
        **list_knowledge_files** [storage] (query)
        Muestra todos los archivos subidos a la base de conocimiento (PDFs, documentos, etc.)
      type: object

    ListKnowledgeSnippetsArgs:
      description: |
        **list_knowledge_snippets** [prompt] (query)
        Lista snippets de conocimiento filtrados por estado (pendiente, activo, en conflicto, obsoleto, rechazado)
      type: object
      properties:
        filter:
          type: string
          description: "Filtro por estado: pending, active, conflicts, stale, rejected"
          enum: ["pending", "active", "conflicts", "stale", "rejected", "all"]
          default: "all"
        category:
          type: string
          description: "Filtrar por categoria"
        search:
          type: string
          description: "Buscar en contenido de snippets"
        source_type:
          type: string
          description: "Filtrar por tipo de fuente"
        offset:
          type: integer
          description: "Offset para paginacion"
          default: 0
        limit:
          type: integer
          description: "Limite de resultados"
          default: 50
        risk_level:
          type: string
          description: "Filtrar por nivel de riesgo"
          enum: ["low", "medium", "high"]

    ListNotificationsArgs:
      description: |
        **list_notifications** [notifications] (query)
        Obtiene las notificaciones del sistema con filtros opcionales
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        filter:
          type: string
          description: "Filtro: all (default), unread, read"
        type:
          type: string
          description: "Filtrar por tipo de notificacion"
        limit:
          type: integer
          description: "Maximo de resultados (default 20, max 100)"
        offset:
          type: integer
          description: "Paginacion"
        notification_id:
          type: integer
          description: "ID de la notificacion"
        agent_id:
          type: integer
          description: "ID del agente"
      required: ["action"]

    ListOauthCalendarsArgs:
      description: |
        **list_oauth_calendars** [calendar] (query)
        Lista los calendarios disponibles de una conexion OAuth (Google/Microsoft) para vincular
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        connection_id:
          type: integer
          description: "ID de la conexion OAuth"
      required: ["action", "connection_id"]

    ListPluginConfigsArgs:
      description: |
        **list_plugin_configs** [plugins] (query)
        Lista todos los plugins instalados con su configuracion y estado
      type: object
      properties:
        action:
          type: string
        plugin_type:
          type: string
          description: "Filtrar por tipo de plugin"
        hours:
          type: integer
          description: "Ultimas N horas a analizar"
        limit:
          type: integer
          description: "Maximo de resultados"
        period:
          type: string
          description: "Periodo de tiempo para las estadisticas"
          enum: ["today", "yesterday", "last_7_days", "last_30_days"]
      required: ["action"]

    ListScheduledEmailsArgs:
      description: |
        **list_scheduled_emails** [email] (query)
        Muestra los emails que estan programados para enviarse en el futuro.
      type: object
      properties:
        filter:
          type: string
          description: "Debe ser 'scheduled'"
        from_filter:
          type: string
          description: "Filtrar por remitente"
        has_attachments:
          type: string
          description: "Filtrar por emails con adjuntos"
        tag:
          type: string
          description: "Filtrar por etiqueta"
        assigned:
          type: string
          description: "Filtrar por agente asignado"
        date_from:
          type: string
          description: "Fecha inicio del filtro"
        date_to:
          type: string
          description: "Fecha fin del filtro"
      required: ["filter"]

    ListScheduledMessagesArgs:
      description: |
        **list_scheduled_messages** [whatsapp_ops] (query)
        Lists scheduled WhatsApp messages with optional status filter. Returns id, session info, phone, message text, scheduled time, status, agent name, and sent/error info.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        status:
          type: string
          description: "Filtrar por estado (default: pending, all para ver todos)"
          enum: ["pending", "sent", "cancelled", "failed", "all"]
          default: "pending"
        page:
          type: integer
          description: "Pagina de resultados"
        period:
          type: string
          description: "Periodo de tiempo para filtrar: today (hoy), 7/30/90 (ultimos N dias), custom (requiere date_from y date_to)"
          enum: ["today", "7", "30", "90", "custom"]
        date_from:
          type: string
          description: "Fecha inicio YYYY-MM-DD"
        date_to:
          type: string
          description: "Fecha fin YYYY-MM-DD"
        phone:
          type: string
          description: "Filtrar por número de teléfono del destinatario"
      required: ["action"]

    ListStorageFilesArgs:
      description: |
        **list_storage_files** [storage] (query)
        Muestra la lista de archivos subidos a la base de conocimiento con su tamano y fecha
      type: object
      properties:
        limit:
          type: integer
          description: "Numero maximo de archivos a mostrar (1-50)"
          default: 20

    ListTasksArgs:
      description: |
        **list_tasks** [tasks] (query)
        Lista las tareas de la tienda con filtros opcionales por estado, agente o telefono
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        status:
          type: string
          description: "Filtrar por estado"
          enum: ["pending", "in_progress", "completed", "cancelled"]
        agent_id:
          type: integer
          description: "Filtrar por agente asignado"
        phone:
          type: string
          description: "Filtrar por telefono del cliente"
        limit:
          type: integer
          default: 20
        offset:
          type: integer
          description: "Posicion de inicio para paginacion"
        task_text:
          type: string
          description: "Texto de la tarea"
        due_date:
          type: string
          description: "Fecha limite YYYY-MM-DD"
        priority:
          type: string
          description: "Prioridad de la tarea"
          enum: ["low", "medium", "high"]
        assigned_agent_id:
          type: integer
          description: "ID del agente asignado"
        task_id:
          type: integer
          description: "ID de la tarea"
        include_completed:
          type: boolean
          description: "Incluir tareas completadas"
      required: ["action"]

    ListVoiceCallsArgs:
      description: |
        **list_voice_calls** [voice] (query)
        Devuelve el registro paginado de llamadas del asistente de voz (Vapi) de la tienda: telefono, cliente, duracion, estado, resultado, idioma detectado y coste. Permite filtrar por resultado, origen, fecha y busqueda de texto.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija (list es el valor por defecto)"
        limit:
          type: integer
          description: "Numero de llamadas a devolver (1-200, default 50)"
        offset:
          type: integer
          description: "Desplazamiento para paginacion (default 0)"
        outcome:
          type: string
          description: "Filtrar por resultado de la llamada"
        source:
          type: string
          description: "Filtrar por origen de la llamada (ej: web, telefono)"
        since:
          type: string
          description: "Fecha minima de inicio en formato YYYY-MM-DD"
        q:
          type: string
          description: "Texto de busqueda en telefono, nombre, email o resumen del cliente"

    ListWhatsappAgentsArgs:
      description: |
        **list_whatsapp_agents** [agents] (query)
        Muestra todos los agentes disponibles para asignar en workflows de WhatsApp
      type: object

    ListWhatsappOptoutArgs:
      description: |
        **list_whatsapp_optout** [whatsapp_ops] (query)
        Muestra los contactos que han solicitado no recibir mensajes automaticos de WhatsApp
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        page:
          type: integer
          description: "Pagina de resultados (default 1)"
        search:
          type: string
          description: "Filtrar por numero de telefono"
      required: ["action"]

    ListWhatsappScheduledSessionsArgs:
      description: |
        **list_whatsapp_scheduled_sessions** [whatsapp_ops] (query)
        Devuelve las sesiones de WhatsApp conectadas disponibles para enviar mensajes programados.
      type: object
      properties:
        action:
          type: string
          description: "Acción fija"
      required: ["action"]

    ListWhatsappTemplatesArgs:
      description: |
        **list_whatsapp_templates** [whatsapp_ops] (query)
        Muestra las plantillas de mensajes guardadas para WhatsApp
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        category:
          type: string
          description: "Filtrar por categoria de plantilla"
      required: ["action"]

    ListWhatsappWorkflowsArgs:
      description: |
        **list_whatsapp_workflows** [automation] (query)
        Obtiene la lista de todos los workflows de automatizacion de WhatsApp. OBLIGATORIO llamar esta accion ANTES de cualquier operacion de eliminacion (delete_whatsapp_workflow, bulk_delete_workflows) para identificar workflows por nombre e ID y confirmar con el usuario cuales quiere eliminar. Tambien usar antes de 'unir' o 'combinar' workflows para entender la configuracion actual.
      type: object

    ManageFaqArgs:
      description: |
        **manage_faq** [plugins] (mutation)
        Permite despublicar, republicar o eliminar FAQs del plugin Product Q&A. Util para gestionar contenido que ya no es relevante.
        ⚠️ Requires confirmation
      type: object
      properties:
        faq_ids:
          type: array
          description: "Array de IDs de FAQs a gestionar (obtener de get_product_qa_faqs)"
        action:
          type: string
          description: "Accion a realizar: unpublish, republish, delete"
          enum: ["unpublish", "republish", "delete"]
      required: ["faq_ids", "action"]

    MarkAllNotificationsReadArgs:
      description: |
        **mark_all_notifications_read** [notifications] (mutation)
        Marca todas las notificaciones no leidas como leidas
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        agent_id:
          type: integer
          description: "ID del agente (opcional)"
        limit:
          type: integer
          description: "Maximo de resultados"
        offset:
          type: integer
          description: "Posicion de inicio"
        filter:
          type: string
          description: "Filtro de notificaciones"
        type:
          type: string
          description: "Tipo de notificacion"
        notification_id:
          type: integer
          description: "ID de la notificacion"
      required: ["action"]

    MarkEmailReadArgs:
      description: |
        **mark_email_read** [email] (mutation)
        Marca un hilo o mensaje de email como leido. Se requiere al menos thread_id o message_id.
      type: object
      properties:
        thread_id:
          type: integer
          description: "ID del hilo (marca todo el hilo como leido)"
        message_id:
          type: integer
          description: "ID del mensaje individual a marcar como leido"

    MarkEmailThreadSpamArgs:
      description: |
        **mark_email_thread_spam** [email] (mutation)
        Marca un hilo de email como spam y lo mueve a la carpeta de spam via IMAP. Anade el remitente a la lista de bloqueados de la tienda.
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
          description: "Debe ser 'spam'"
        thread_id:
          type: integer
          description: "ID del hilo a marcar como spam"
        message_ids:
          type: array
          description: "IDs de mensajes especificos a marcar como spam. Si se omite, se aplica a todo el hilo."
      required: ["action", "thread_id"]

    MarkEmailThreadUnreadArgs:
      description: |
        **mark_email_thread_unread** [email] (mutation)
        Marca como no leidos todos los mensajes de un hilo de email (o solo los message_ids especificados). Sincroniza el estado con IMAP cuando es posible.
      type: object
      properties:
        action:
          type: string
          description: "Debe ser 'mark_unread'"
        thread_id:
          type: integer
          description: "ID del hilo"
        message_ids:
          type: array
          description: "IDs de mensajes especificos a marcar como no leidos. Si se omite, se aplica a todo el hilo."
      required: ["action", "thread_id"]

    MarkNotificationReadArgs:
      description: |
        **mark_notification_read** [notifications] (mutation)
        Marca una notificacion especifica como leida
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        notification_id:
          type: integer
          description: "ID de la notificacion"
        agent_id:
          type: integer
          description: "ID del agente que lee (opcional)"
        limit:
          type: integer
          description: "Maximo de resultados"
        offset:
          type: integer
          description: "Posicion de inicio"
        filter:
          type: string
          description: "Filtro de notificaciones"
        type:
          type: string
          description: "Tipo de notificacion"
      required: ["action", "notification_id"]

    MergeCustomersArgs:
      description: |
        **merge_customers** [customers] (mutation)
        Fusiona dos registros de cliente en uno, combinando comentarios, tags y datos CRM
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
        primary_phone:
          type: string
          description: "Telefono del cliente principal (se mantiene)"
        secondary_phone:
          type: string
          description: "Telefono del cliente secundario (se fusiona y elimina)"
      required: ["action", "primary_phone", "secondary_phone"]

    MergeEmailThreadsArgs:
      description: |
        **merge_email_threads** [email] (mutation)
        Fusiona un hilo de email en otro. Los mensajes y notas del hilo origen se mueven al destino. Solo se pueden fusionar hilos de la misma cuenta de email.
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
          description: "Debe ser 'merge'"
        thread_id:
          type: integer
          description: "ID del hilo origen (se eliminara)"
        target_thread_id:
          type: integer
          description: "ID del hilo destino (recibira los mensajes)"
      required: ["action", "thread_id", "target_thread_id"]

    PauseCampaignArgs:
      description: |
        **pause_campaign** [mass_marketing] (mutation)
        Pausa temporalmente una campana de marketing masivo en curso
      type: object
      properties:
        action:
          type: string
          description: "Accion fija: pause"
        campaign_id:
          type: integer
          description: "ID de la campana a pausar"
      required: ["action", "campaign_id"]

    PrecheckDeleteWhatsappSessionArgs:
      description: |
        **precheck_delete_whatsapp_session** [whatsapp_ops] (query)
        Muestra qué configuraciones se verían afectadas al eliminar una sesión de WhatsApp (workflows, campañas, seguimiento inteligente) y lista las sesiones alternativas disponibles para migración. IMPORTANTE: Solo se pueden eliminar sesiones en estado 'disconnected'. Si la sesion esta conectada, informa al usuario que primero debe desconectarla desde el panel de WhatsApp antes de poder eliminarla.
      type: object
      properties:
        session_id:
          type: integer
          description: "ID de la sesión a verificar"
      required: ["session_id"]

    PreviewImportFileArgs:
      description: |
        **preview_import_file** [mass_marketing] (query)
        Previsualiza las columnas y primeras filas de un archivo CSV antes de importar contactos
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        file:
          type: string
          description: "Archivo CSV a previsualizar (multipart/form-data)"
      required: ["action", "file"]

    PreviewSmartFollowupArgs:
      description: |
        **preview_smart_followup** [smart_followup] (query)
        Genera una vista previa del mensaje de seguimiento que se enviaria a un cliente sin enviarlo realmente
      type: object
      properties:
        conversation_hash:
          type: string
          description: "Hash de la conversacion a analizar"
      required: ["conversation_hash"]

    PublishQuestionAsFaqArgs:
      description: |
        **publish_question_as_faq** [plugins] (mutation)
        Publica manualmente una pregunta del historial como FAQ en tu tienda online. Util para promover preguntas importantes que no fueron detectadas automaticamente.
      type: object
      properties:
        question_id:
          type: integer
          description: "ID de la pregunta a publicar (obtener de get_product_qa_questions)"
      required: ["question_id"]

    ReconnectWhatsappArgs:
      description: |
        **reconnect_whatsapp** [automation] (mutation)
        Intenta reconectar una sesion de WhatsApp existente (puede requerir escanear QR manualmente). Si hay multiples numeros, requiere session_id.
      type: object
      properties:
        session_id:
          type: integer
          description: "ID de la sesion a reconectar. Obligatorio si hay mas de un numero. Usa get_whatsapp_status para obtener los IDs."

    RegenerateApiKeyArgs:
      description: |
        **regenerate_api_key** [advanced] (mutation)
        Genera una nueva API key (token_ext) para la tienda. Esto invalida la key actual e impide el acceso de cualquier conexion MCP o aplicacion que la use. Usar solo si el usuario lo pide explicitamente.
        ⚠️ Requires confirmation
      type: object
      properties:
        confirmation:
          type: boolean
          description: "Debe ser true para confirmar la regeneracion"
        confirm:
          type: boolean
          description: "Confirmar la regeneracion del token"
      required: ["confirmation"]

    RegenerateDocqaTokenArgs:
      description: |
        **regenerate_docqa_token** [plugins] (mutation)
        Genera un nuevo token de acceso para un asistente Doc-QA
        ⚠️ Requires confirmation
      type: object
      properties:
        assistant_id:
          type: integer
          description: "ID del asistente Doc-QA"
      required: ["assistant_id"]

    RegeneratePluginTokenArgs:
      description: |
        **regenerate_plugin_token** [plugins] (mutation)
        Genera un nuevo token para los plugins (invalida el anterior)
        ⚠️ Requires confirmation
      type: object
      properties:
        plugin_type:
          type: string
          description: "Tipo de plugin cuyo token regenerar"
          enum: ["chat", "product-qa"]
          default: "chat"

    RejectAndProposeKnowledgeSnippetArgs:
      description: |
        **reject_and_propose_knowledge_snippet** [knowledge] (mutation)
        Rechaza ambos snippets en conflicto y crea uno nuevo con el contenido propuesto por el usuario
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        id:
          type: integer
          description: "ID del snippet en conflicto"
        proposed_content:
          type: string
          description: "Contenido correcto propuesto por el usuario"
        conflict_with_id:
          type: integer
          description: "ID del snippet en conflicto a rechazar tambien (si no se toma del campo conflict_with_id del snippet)"
      required: ["action", "id", "proposed_content"]

    RejectKnowledgeSnippetArgs:
      description: |
        **reject_knowledge_snippet** [knowledge] (mutation)
        Rechaza un snippet de conocimiento pendiente
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        id:
          type: integer
          description: "ID del snippet a rechazar"
      required: ["action", "id"]

    RemoveContactFromListArgs:
      description: |
        **remove_contact_from_list** [mass_marketing] (mutation)
        Elimina un contacto individual de una lista de marketing
      type: object
      properties:
        action:
          type: string
        contact_id:
          type: integer
          description: "ID del contacto a eliminar"
      required: ["action", "contact_id"]

    RemoveContactsBulkArgs:
      description: |
        **remove_contacts_bulk** [mass_marketing] (mutation)
        Elimina múltiples contactos de una lista de marketing
      type: object
      properties:
        action:
          type: string
        list_id:
          type: integer
          description: "ID de la lista"
        contact_ids:
          type: array
          description: "Array de IDs de contactos a eliminar"
        select_all:
          type: boolean
          description: "Seleccionar todos los contactos"
        exclude_ids:
          type: array
          description: "IDs a excluir cuando select_all=true"
        search:
          type: string
          description: "Filtro de búsqueda aplicado"
      required: ["action", "list_id"]

    RemoveCustomerTagArgs:
      description: |
        **remove_customer_tag** [customers] (mutation)
        Elimina una etiqueta (tag) de un cliente
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        phone:
          type: string
          description: "Numero de telefono del cliente"
        tag_name:
          type: string
          description: "Nombre del tag a eliminar"
        comment:
          type: string
          description: "Texto del comentario"
        agent_name:
          type: string
          description: "Nombre del agente"
        query:
          type: string
          description: "Texto de busqueda"
        limit:
          type: integer
          description: "Maximo de resultados"
        tag_color:
          type: string
          description: "Color del tag en formato hexadecimal"
        primary_phone:
          type: string
          description: "Telefono principal para merge"
        secondary_phone:
          type: string
          description: "Telefono secundario para merge"
      required: ["action", "phone", "tag_name"]

    RemoveFromBlacklistArgs:
      description: |
        **remove_from_blacklist** [mass_marketing] (mutation)
        Desbloquea un numero de telefono de la lista negra de marketing masivo
      type: object
      properties:
        action:
          type: string
          description: "Accion fija: remove"
        phone:
          type: string
          description: "Numero de telefono a desbloquear"
      required: ["action", "phone"]

    RemoveUnsubscribedBulkArgs:
      description: |
        **remove_unsubscribed_bulk** [mass_marketing] (mutation)
        Elimina registros de bajas de marketing masivo
      type: object
      properties:
        action:
          type: string
        ids:
          type: array
          description: "Array de IDs de registros de baja a eliminar"
        select_all:
          type: boolean
          description: "Seleccionar todos los registros (usa filtros search/date_from/date_to para limitar)"
        search:
          type: string
          description: "Filtro por telefono (usado con select_all=true para limitar el alcance)"
        date_from:
          type: string
          description: "Fecha inicio filtro (formato YYYY-MM-DD, usado con select_all=true)"
        date_to:
          type: string
          description: "Fecha fin filtro (formato YYYY-MM-DD, usado con select_all=true)"
        exclude_ids:
          type: array
          description: "IDs a excluir de la eliminacion masiva (usado con select_all=true)"
      required: ["action"]

    RemoveWhatsappOptoutArgs:
      description: |
        **remove_whatsapp_optout** [whatsapp_ops] (mutation)
        Elimina un numero de la lista de opt-out para que pueda recibir mensajes automaticos de nuevo
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        phone:
          type: string
          description: "Numero de telefono a quitar de opt-out"
      required: ["action", "phone"]

    RemoveWhatsappProfilePictureArgs:
      description: |
        **remove_whatsapp_profile_picture** [automation] (mutation)
        Elimina la foto de perfil de una sesion de WhatsApp
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        session_id:
          type: integer
          description: "ID de la sesion de WhatsApp"
      required: ["action", "session_id"]

    ReopenAiTicketArgs:
      description: |
        **reopen_ai_ticket** [tickets] (mutation)
        Reabre un ticket resuelto/cerrado cuando el cliente insiste o aparece informacion nueva.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        ticket_id:
          type: integer
          description: "ID del ticket"
        reason:
          type: string
          description: "Motivo interno de reapertura"
      required: ["action", "ticket_id"]

    ReorderWhatsappWorkflowsArgs:
      description: |
        **reorder_whatsapp_workflows** [automation] (mutation)
        Cambia el orden de ejecucion de los workflows de WhatsApp
      type: object
      properties:
        action:
          type: string
        order:
          type: array
          description: "Array de objetos {id, priority} con el nuevo orden de los workflows"
      required: ["action", "order"]

    RepublishFaqArgs:
      description: |
        **republish_faq** [plugins] (mutation)
        Republica una o varias FAQs previamente despublicadas
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        faq_ids:
          type: array
          description: "IDs de las FAQs a republicar"
      required: ["action", "faq_ids"]

    RequestReferralPayoutArgs:
      description: |
        **request_referral_payout** [referrals] (mutation)
        Solicita el pago de las comisiones pendientes (mínimo 50€). Solo disponible si no hay otra solicitud abierta.
        ⚠️ Requires confirmation
      type: object

    ResetCrmErrorsArgs:
      description: |
        **reset_crm_errors** [advanced] (mutation)
        Resetea el contador de errores CRM y reactiva los endpoints si estaban deshabilitados por errores consecutivos
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
      required: ["action"]

    ResolveAiTicketArgs:
      description: |
        **resolve_ai_ticket** [tickets] (mutation)
        Marca un ticket interno como resuelto.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        ticket_id:
          type: integer
          description: "ID del ticket"
        reason:
          type: string
          description: "Motivo interno del cierre"
      required: ["action", "ticket_id"]

    ResolveEmailContactArgs:
      description: |
        **resolve_email_contact** [email] (query)
        Busca la direccion de email asociada a un contacto de WhatsApp usando CRM y plataforma e-commerce
      type: object
      properties:
        phone_hash:
          type: string
          description: "Hash del telefono del contacto"
      required: ["phone_hash"]

    ResolveKnowledgeConflictArgs:
      description: |
        **resolve_knowledge_conflict** [knowledge] (mutation)
        Resuelve un conflicto entre snippets de conocimiento eligiendo cual mantener
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        id:
          type: integer
          description: "ID del snippet en conflicto"
        keep_id:
          type: integer
          description: "ID del snippet a mantener"
      required: ["action", "id", "keep_id"]

    RestoreDefaultPromptArgs:
      description: |
        **restore_default_prompt** [prompt] (query)
        Obtiene el prompt por defecto segun el idioma
      type: object

    RestoreEmailThreadArgs:
      description: |
        **restore_email_thread** [email] (mutation)
        Restaura un hilo de email previamente eliminado, archivado o marcado como spam, devolviendolo a la bandeja de entrada. Si estaba en spam, tambien elimina el remitente de la lista de bloqueados.
      type: object
      properties:
        action:
          type: string
          description: "Debe ser 'restore'"
        thread_id:
          type: integer
          description: "ID del hilo a restaurar"
        message_ids:
          type: array
          description: "IDs de mensajes especificos a restaurar. Si se omite, se aplica a todo el hilo."
      required: ["action", "thread_id"]

    ResumeCampaignArgs:
      description: |
        **resume_campaign** [mass_marketing] (mutation)
        Reanuda una campana de marketing masivo que fue pausada
      type: object
      properties:
        action:
          type: string
          description: "Accion fija: resume"
        campaign_id:
          type: integer
          description: "ID de la campana a reanudar"
      required: ["action", "campaign_id"]

    RetryEmailAccountArgs:
      description: |
        **retry_email_account** [email] (mutation)
        Resetea el estado de error de una cuenta de email y reintenta la conexion. Util cuando una cuenta esta en estado de error tras fallos de IMAP/SMTP.
      type: object
      properties:
        action:
          type: string
        id:
          type: integer
          description: "ID de la cuenta de email a reintentar"
      required: ["action", "id"]

    RollbackPromptArgs:
      description: |
        **rollback_prompt** [prompt] (mutation)
        Revierte la parte autogenerada del prompt a una version anterior del historial. La parte personalizada del usuario se mantiene. FLUJO DE CONFIRMACION: Esta accion devolvera requires_confirmation=true con success=false - esto NO es un error, es el flujo normal. Cuando recibas esto, describe brevemente al usuario que version se va a restaurar y PARA. NO llames de nuevo a esta accion. El sistema mostrara botones automaticamente.
        ⚠️ Requires confirmation
      type: object
      properties:
        version_id:
          type: integer
          description: "ID de la version a restaurar. Obtenerlo llamando a get_prompt_history primero"
      required: ["version_id"]

    SaveAgentPermissionsArgs:
      description: |
        **save_agent_permissions** [agents] (mutation)
        Actualiza los permisos de un agente. Enviar null para dar todos los permisos, o un objeto con los permisos especificos en true/false
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
        id:
          type: integer
          description: "ID del agente"
        permissions:
          type: object_or_null
          description: "Objeto con permisos (ej: {"ai_generate": true, "notes_view": true, "crm_edit": false}). null = todos los permisos"
      required: ["action", "id", "permissions"]

    SaveAsWhatsappTemplateArgs:
      description: |
        **save_as_whatsapp_template** [whatsapp_ops] (mutation)
        Guarda un mensaje como plantilla reutilizable de WhatsApp
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        name:
          type: string
          description: "Nombre de la plantilla"
        category:
          type: string
          description: "Categoria de la plantilla"
        workflow_id:
          type: integer
          description: "ID del workflow del que extraer el mensaje para guardar como plantilla"
      required: ["action", "name"]

    SaveCalendarSettingsArgs:
      description: |
        **save_calendar_settings** [calendar] (mutation)
        Guarda la configuracion global del modulo de calendario
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        settings:
          type: object
          description: "Objeto con la configuracion del calendario"
        enabled:
          type: boolean
          description: "Si el modulo de calendario esta habilitado"
      required: ["action"]

    SaveMassMarketingConfigArgs:
      description: |
        **save_mass_marketing_config** [mass_marketing] (mutation)
        Guarda la configuracion de marketing masivo: auto-respuesta, traduccion y opciones de envio
      type: object
      properties:
        auto_reply_enabled:
          type: boolean
          description: "true para activar la auto-respuesta, false para desactivarla"
        auto_reply_text:
          type: string
          description: "Texto de auto-respuesta cuando un destinatario responde a un mensaje masivo"
        auto_reply_translate:
          type: boolean
          description: "Si true, la auto-respuesta se traduce al idioma del destinatario segun su prefijo telefonico"
        auto_reply_unsubscribe:
          type: boolean
          description: "Si true, incluye un enlace de baja en la auto-respuesta"
        custom_unsubscribe_text:
          type: string
          description: "Texto personalizado para el enlace de baja en campanas. Maximo 500 caracteres. Enviar vacio o null para usar el texto predeterminado."
        require_approval:
          type: boolean
          description: "Si true, las campanas creadas por agentes requieren aprobacion del administrador antes de enviarse"

    SavePluginConversationNoteArgs:
      description: |
        **save_plugin_conversation_note** [plugins] (mutation)
        Genera un resumen IA de una conversacion del plugin de chat web y lo guarda como nota en el perfil del cliente. Requiere que el visitante se haya identificado con telefono o email para poder asociarlo a un cliente existente.
      type: object
      properties:
        session_id:
          type: string
          description: "ID de la sesion de chat del plugin"
      required: ["session_id"]

    SavePromptArgs:
      description: |
        **save_prompt** [prompt] (mutation)
        Guarda un nuevo prompt para la IA. IMPORTANTE: el endpoint REEMPLAZA el prompt completo (no soporta merge/append/secciones ni parametros incrementales add_*/remove_*). Si el usuario quiere AÑADIR, MODIFICAR o QUITAR algo del prompt existente (ej: 'add a rule', 'anade horario', 'quita la parte de...', 'add a shop-level rule'), usa apply_prompt_instruction PRIMERO — esa accion lee el prompt actual, lo modifica segun la instruccion y devuelve el prompt completo modificado; despues llama a save_prompt con ese resultado para persistir. Solo usa save_prompt directamente si el usuario proporciona un prompt COMPLETO de reemplazo. FLUJO DE CONFIRMACION: 1) Llama a esta accion con el prompt completo. 2) Recibiras requires_confirmation=true con success=false — esto NO es un error, es el flujo normal. 3) Describe brevemente al usuario que cambios se van a guardar y PARA. NO llames de nuevo a esta accion. El sistema mostrara botones de Confirmar/Cancelar automaticamente. NUNCA vuelvas a llamar save_prompt tras recibir requires_confirmation=true, ni siquiera si el usuario escribe 'si', 'yes', 'hazlo', 'confirma', 'dale', 'do it' o cualquier variante afirmativa en texto, NI cuando dice 'I did not receive the confirm button', 'no veo el boton', 'send again' o 'envialo otra vez'. Reenviar invalida el token anterior y el boton sigue sin renderizarse. La confirmacion SOLO se completa con los botones del sistema. Respuestas correctas segun lo que diga el usuario: si insiste por texto ('si'/'yes'/'do it'), respondele: 'Please use the Confirm button that appeared above to complete the save.' (en el idioma de la conversacion); si dice que no ve el boton, indicale que los botones azules de Confirmar/Cancelar aparecen JUSTO ENCIMA de tu mensaje anterior y, si aun asi no los ve, sugiere refrescar la pagina (F5) o ir a [Configuracion del Prompt](https://www.wazion.com/dashboard/prompt) para guardar manualmente.
        ⚠️ Requires confirmation
      type: object
      properties:
        prompt:
          type: string
          description: "El nuevo prompt para la IA. Si el usuario quiere modificar el prompt existente (ej: 'anade horario de 9 a 18h'), usa apply_prompt_instruction en su lugar - esa accion genera el prompt modificado y luego tu llamas a save_prompt con el resultado"
        enable_web_search:
          type: boolean
          description: "Opcionalmente, activar o desactivar la busqueda web al guardar el prompt"
      required: ["prompt"]

    SaveSmartFollowupConfigArgs:
      description: |
        **save_smart_followup_config** [smart_followup] (mutation)
        Actualiza la configuracion de seguimiento inteligente. Solo envia los campos que quieras cambiar. El sistema verifica automaticamente que el contacto no este dado de baja (mass marketing) y no tenga sentimiento negativo antes de enviar.
        ⚠️ Requires confirmation
      type: object
      properties:
        enabled:
          type: boolean
          description: "Enable or disable smart follow-up"
        run_hour:
          type: integer
          description: "Hour to run (0-23) in shop's timezone"
        lookback_hours:
          type: integer
          description: "How many hours back to look for conversations (default 24)"
        min_intent_level:
          type: string
          description: "Minimum intent level to follow up: 'low', 'medium', or 'high'"
        max_attempts:
          type: integer
          description: "Maximum follow-up attempts per conversation (1-5)"
        retry_interval_hours:
          type: integer
          description: "Hours to wait between retry attempts for the same conversation"
        max_conversations:
          type: integer
          description: "Maximum conversations to process per cron run"
        auto_send_enabled:
          type: boolean
          description: "Whether to automatically send WhatsApp follow-up messages"
        archive_after_send:
          type: boolean
          description: "Whether to archive the chat after sending an automatic smart follow-up. If the customer replies later, WhatsApp reopens it as active."
        delay_days:
          type: integer
          description: "Days to wait before sending follow-up (0-7)"
        run_days:
          type: array
          description: "Days of the week to run (0=Sunday, 1=Monday, ..., 6=Saturday). JSON array of integers."
        tracking_days:
          type: integer
          description: "Days to track conversions after follow-up is sent"
        reset_attempts_days:
          type: integer
          description: "Days after which attempt count resets for a conversation"
        custom_instructions:
          type: string
          description: "Instrucciones personalizadas para la IA al generar mensajes de seguimiento"
        followup_tone:
          type: string
          description: "Tono de los mensajes de seguimiento: 'friendly' (amigable), 'professional' (profesional) o 'casual'"
        whatsapp_session_id:
          type: integer
          description: "ID de la sesion de WhatsApp a usar para enviar los mensajes de seguimiento"
        exclude_phones:
          type: array
          description: "Lista de telefonos a excluir del seguimiento (maximo 200). Formato: array de strings con prefijo +"
        sending_window_start:
          type: integer
          description: "Hora de inicio de la ventana de envio (0-23). null para desactivar ventana"
        sending_window_end:
          type: integer
          description: "Hora de fin de la ventana de envio (0-23). null para desactivar ventana"

    SaveVoiceConfigArgs:
      description: |
        **save_voice_config** [voice] (mutation)
        Actualiza la configuracion del asistente de voz desde WAzion. El cliente solo pega su API key Vapi y WAzion crea/actualiza el assistant; no se debe mandar al cliente a dashboard.vapi.ai. La transferencia humana esta desactivada hasta que exista transferencia real en Vapi/telefonia.
        ⚠️ Requires confirmation
      type: object
      properties:
        voice_enabled:
          type: boolean
          description: "Master toggle on/off del asistente de voz"
        voice_assistant_id:
          type: string
          description: "Vapi assistant id gestionado por WAzion. Normalmente se rellena automaticamente al conectar la API key Vapi."
        voice_public_key:
          type: string
          description: "Vapi public key (browser-safe, usada por el boton 'Llamar' de la web)"
        voice_api_key:
          type: string
          description: "Vapi private/server key. Se almacena cifrada y permite que WAzion cree o actualice el assistant programaticamente."
        voice_phone_number:
          type: string
          description: "Numero publico desde el que se reciben llamadas (informativo, no se usa por backend)"
        voice_transfer_number:
          type: string
          description: "Reservado para transferencia humana futura. No activar mientras transfer_enabled este bloqueado."
        languages:
          type: array
          description: "Lista de codigos ISO 639-1 (es, en, de, fr, it, pt) que el asistente debe atender"
        primary_language:
          type: string
          description: "Idioma principal del asistente (codigo ISO 639-1). Define el system prompt base y la voz por defecto."
        voice_by_lang:
          type: object
          description: "Mapa { lang: { provider, voiceId, model? } } para preparar voces por idioma. En el assistant Vapi actual se aplica la voz del idioma principal."
        web_plugin_enabled:
          type: boolean
          description: "Activa o desactiva el boton web flotante. Si false, /api/plugins/voice/init.js devuelve no-op aunque el snippet siga instalado."
        conversation_model:
          type: string
          description: "Modelo LLM de la capa conversacional de Vapi. Opciones soportadas: gpt-4o-mini (recomendado por latencia) o gpt-4o (mas calidad, mas latencia/coste). Cambiarlo reprovisiona el assistant Vapi."
        assistant_preset:
          type: string
          description: "Preset guiado de calidad del assistant: balanced, fast, quality, noisy o low_cost. Ajusta valores seguros de modelo, ruido, tiempos y voz."
        voice_speed:
          type: number
          description: "Velocidad de voz Vapi/TTS entre 0.75 y 1.25. Default 1.0."
        voice_caching_enabled:
          type: boolean
          description: "Activa cache de audio repetido para reducir coste/latencia en saludos y mensajes frecuentes."
        background_sound:
          type: string
          description: "Sonido de fondo del assistant. Opciones seguras: office u off."
        noise_reduction:
          type: string
          description: "Reduccion de ruido/voz de fondo. Opciones: off, smart o smart_fourier."
        silence_timeout_seconds:
          type: integer
          description: "Segundos de silencio antes de cerrar o considerar la llamada inactiva. Rango seguro 10-60."
        max_duration_seconds:
          type: integer
          description: "Duracion maxima de llamada. Rango seguro 60-1800 segundos."
        idle_timeout_seconds:
          type: integer
          description: "Segundos antes de que Vapi reproduzca un mensaje de espera por silencio. Rango seguro 10-120."
        tool_timeout_seconds:
          type: integer
          description: "Timeout de la consulta ask_wazion desde Vapi. Rango seguro 20-120 segundos."
        first_message_interruptions_enabled:
          type: boolean
          description: "Permite que el cliente interrumpa el saludo inicial del assistant."
        auto_followup_enabled:
          type: boolean
          description: "Si true, envia un resumen automatico por WhatsApp al colgar cuando el numero esta confirmado. Default seguro: false."
        transcriber_id:
          type: string
          description: "ID del transcriptor del catalogo de voz. Valores validos: deepgram-nova-3-multi, assembly-ai-universal, gladia-solaria, speechmatics. Cambiarlo actualiza el assistant Vapi."
        keyterms:
          type: array
          description: "Lista de palabras clave del negocio para mejorar la transcripcion de marcas, modelos y referencias. Maximo recomendado: 50 strings cortos."
        followup_templates:
          type: object
          description: "Mapa { lang: 'plantilla' } para el WhatsApp post-llamada. Variables disponibles: {customer_name}, {business_name}, {summary}, {summary_bullets}"
        voice_rules:
          type: string
          description: "Reglas especificas en lenguaje natural que se anaden al prompt del asistente (ej: 'no consultes compatibilidad de piezas por telefono')"
        tools_enabled:
          type: array
          description: "Subconjunto de capacidades de voz. Valores activos actuales: consultar_pedido, consultar_envio, buscar_kb, derivar_whatsapp. No usar transferir_humano hasta que la transferencia real este implementada."
        transfer_enabled:
          type: boolean
          description: "Reservado. Debe permanecer false hasta que la transferencia real este conectada en Vapi y telefonia."
        button_color:
          type: string
          description: "Color principal del boton web de voz, en hexadecimal CSS."
        button_color_gradient_from:
          type: string
          description: "Color inicial del degradado del boton web de voz, en hexadecimal CSS."
        button_offset_bottom:
          type: integer
          description: "Separacion inferior del boton web en desktop, en pixeles."
        button_offset_bottom_mobile:
          type: integer
          description: "Separacion inferior del boton web en movil, en pixeles."
        button_offset_side:
          type: integer
          description: "Separacion lateral del boton web, en pixeles."

    SearchConversationsArgs:
      description: |
        **search_conversations** [conversations] (query)
        Busca conversaciones por texto, telefono o rango de fechas. Ejemplo: 'busca conversaciones que mencionen devolucion'
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        query:
          type: string
          description: "Texto a buscar en los mensajes de las conversaciones"
        phone:
          type: string
          description: "Numero de telefono del cliente (con o sin +)"
        date_from:
          type: string
          description: "Fecha inicio (YYYY-MM-DD)"
        date_to:
          type: string
          description: "Fecha fin (YYYY-MM-DD)"
        limit:
          type: integer
          description: "Maximo de resultados (default 20, max 50)"
          default: 20
        offset:
          type: integer
          description: "Posicion de inicio para paginacion"
        hours:
          type: integer
          description: "Ultimas N horas"
        conversation_id:
          type: integer
          description: "ID de conversacion especifica"
        last_n:
          type: integer
          description: "Ultimos N mensajes"
        period:
          type: string
          description: "Periodo de tiempo"
          enum: ["today", "yesterday", "last_7_days"]
        agent_id:
          type: integer
          description: "ID del agente"
        message:
          type: string
          description: "Texto del mensaje a enviar o eliminar"
        format:
          type: string
          description: "Formato de respuesta"
      required: ["action"]

    SearchCustomerCommentsArgs:
      description: |
        **search_customer_comments** [customers] (query)
        Busca texto en los comentarios de todos los clientes
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        query:
          type: string
          description: "Texto a buscar en los comentarios"
        limit:
          type: integer
          default: 20
        phone:
          type: string
          description: "Telefono del cliente"
        comment:
          type: string
          description: "Texto del comentario"
        agent_name:
          type: string
          description: "Nombre del agente"
        tag_name:
          type: string
          description: "Nombre del tag"
        tag_color:
          type: string
          description: "Color del tag en formato hexadecimal"
        primary_phone:
          type: string
          description: "Telefono principal para merge"
        secondary_phone:
          type: string
          description: "Telefono secundario para merge"
      required: ["action", "query"]

    SearchCustomersArgs:
      description: |
        **search_customers** [customers] (query)
        Busca clientes por nombre, telefono o email en el CRM y en los contactos
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        query:
          type: string
          description: "Texto a buscar (nombre, telefono o email)"
        limit:
          type: integer
          default: 20
        phone:
          type: string
          description: "Telefono del cliente"
        comment:
          type: string
          description: "Texto del comentario"
        agent_name:
          type: string
          description: "Nombre del agente"
        tag_name:
          type: string
          description: "Nombre del tag"
        tag_color:
          type: string
          description: "Color del tag en formato hexadecimal"
        primary_phone:
          type: string
          description: "Telefono principal para merge"
        secondary_phone:
          type: string
          description: "Telefono secundario para merge"
      required: ["action", "query"]

    SearchEmailContactsArgs:
      description: |
        **search_email_contacts** [email] (query)
        Busca clientes por nombre o telefono para vincularlos a hilos de email
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        query:
          type: string
          description: "Texto de busqueda (nombre o telefono)"
      required: ["action", "query"]

    SearchProductsArgs:
      description: |
        **search_products** [products] (query)
        Busca productos en tu tienda online o en el CRM configurado
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        query:
          type: string
          description: "Texto a buscar en el nombre del producto"
        limit:
          type: integer
          default: 10
        days:
          type: integer
          description: "Dias de historial a buscar"
      required: ["action", "query"]

    SendAiTicketCustomerReplyArgs:
      description: |
        **send_ai_ticket_customer_reply** [tickets] (mutation)
        Envia al cliente un borrador seguro. El endpoint aplica control anti-filtracion contra notas internas antes de enviar.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        ticket_id:
          type: integer
          description: "ID del ticket"
        draft_id:
          type: integer
          description: "ID del mensaje customer_draft"
        message:
          type: string
          description: "Mensaje seguro final para el cliente si se quiere sobreescribir el borrador"
      required: ["action", "ticket_id"]

    SendEmailReplyArgs:
      description: |
        **send_email_reply** [email] (mutation)
        Envia una respuesta a un hilo de email existente o compone un nuevo email
        ⚠️ Requires confirmation
      type: object
      properties:
        thread_id:
          type: integer
          description: "ID del hilo para responder (0 para email nuevo)"
        to:
          type: string
          description: "Destinatario (obligatorio para email nuevo)"
        subject:
          type: string
          description: "Asunto (obligatorio para email nuevo)"
        body_html:
          type: string
          description: "Contenido HTML del email"
        body_text:
          type: string
          description: "Version en texto plano del email (opcional, alternativa a body_html para clientes sin soporte HTML)"
        scheduled_at:
          type: string
          description: "Fecha y hora para programar el envio (ISO 8601)"
        attachment_ids:
          type: array
          description: "IDs de adjuntos previamente subidos"
        cc:
          type: array
          description: "Direcciones CC"
        bcc:
          type: array
          description: "Direcciones BCC"
        account_id:
          type: integer
          description: "ID de la cuenta de correo"
      required: ["body_html"]

    SendSupportTicketArgs:
      description: |
        **send_support_ticket** [support] (mutation)
        Envia un mensaje al equipo de soporte de WAzion. Usa esta accion cuando el usuario tenga un problema que no puedas resolver, quiera reportar un bug, o necesite ayuda del equipo tecnico.
      type: object
      properties:
        type:
          type: string
          description: "Tipo de solicitud: bug (problema tecnico), question (consulta general), feature (sugerencia de mejora), billing (facturacion), other (otro)"
          enum: ["bug", "question", "feature", "billing", "other"]
        subject:
          type: string
          description: "Asunto breve del mensaje (max 100 caracteres)"
        message:
          type: string
          description: "Descripcion detallada del problema o consulta (max 2000 caracteres)"
      required: ["type", "subject", "message"]

    SendWhatsappMessageArgs:
      description: |
        **send_whatsapp_message** [whatsapp_ops] (mutation)
        Envia o acepta en cola texto o multimedia por WhatsApp usando un rol logico (General, Operaciones o Marketing), nunca un ID de sesion. El telefono debe incluir prefijo internacional E.164. IMPORTANTE: requiere confirmacion; requires_confirmation=true es normal. Tras confirmar, queued significa aceptado pero aun no enviado.
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
        phone:
          type: string
          description: "Telefono destino en formato E.164 con prefijo internacional (ej: +34612345678). Si el usuario no incluye prefijo, preguntarle el pais. OBLIGATORIO"
        message:
          type: string
          description: "Texto a enviar. Obligatorio si no se indica media_url; puede usarse como caption si hay multimedia."
        sender_role:
          type: string
          description: "Rol logico del emisor. General para conversacion, Operations para avisos y Marketing para campanas."
          enum: ["general", "operations", "marketing"]
          default: "general"
        media_url:
          type: string
          description: "URL publica http(s) de imagen, video, audio o documento."
        media_type:
          type: string
          description: "Tipo del archivo de media_url."
          enum: ["image", "video", "audio", "document"]
          default: "image"
        caption:
          type: string
          description: "Pie o texto que acompana al archivo."
        archive_after_send:
          type: boolean
          description: "Archivar chat tras enviar. Si se usa archive_policy, esta bandera queda como compatibilidad legacy."
        archive_policy:
          type: string
          description: "Politica de archivado tras enviar: never no archiva; always archiva siempre; preserve_if_previously_archived conserva sin archivar solo los chats que ya estaban activos antes de enviar; si estaban archivados o no existian/no estaban en activos, los archiva tras enviar."
          enum: ["never", "always", "preserve_if_previously_archived"]
        idempotency_key:
          type: string
          description: "Clave estable del envio para deduplicar y consultar su entrega aunque no haya queue_id. Reutiliza exactamente la misma clave al reintentar la misma accion."
        customer_locale:
          type: string
          description: "Idioma ISO del destinatario (por ejemplo es, en, de o fr) para plantillas, traducciones y mensajes auxiliares."
      required: ["action", "phone"]

    SetAiErrorArgs:
      description: |
        **set_ai_error** [knowledge] (mutation)
        Record a mistake in YOUR OWN responses or behavior (this dashboard chat). Call this when the user corrects you, AND when you proactively detect you did something wrong. This includes: wrong answers and behavioral rules about HOW you should act. IMPORTANT: This is for YOUR errors. For errors in the CONTENT of responses sent to customers by the WhatsApp AI, use set_customer_ai_error instead.
      type: object
      properties:
        fact_content:
          type: string
          description: "The correct information or rule to remember"
        category:
          type: string
          description: "Category: shipping, pricing, warranty, product, tone, policy, communication, general"
        original_text:
          type: string
          description: "What the AI originally said wrong"
      required: ["fact_content", "category"]

    SetCustomerAiErrorArgs:
      description: |
        **set_customer_ai_error** [knowledge] (mutation)
        Record a correction for the CUSTOMER-FACING WhatsApp AI (auto-pilot, workflows, suggestions, chat web plugin). Use ONLY when the CONTENT of a response sent to a customer was wrong (wrong info, wrong tone, unnecessary questions to the customer). Do NOT use this for behavioral rules about when/whether to respond — those belong in set_ai_error. IMPORTANT: If the user says the AI should not have replied or should have handled the situation differently, that is a behavioral rule for set_ai_error, not a content correction.
      type: object
      properties:
        fact_content:
          type: string
          description: "The correct information that the AI should use instead"
        category:
          type: string
          description: "Category: shipping, pricing, warranty, product, tone, policy, communication, general"
        original_text:
          type: string
          description: "The wrong text that the AI generated"
      required: ["fact_content", "category"]

    SetEmailPriorityArgs:
      description: |
        **set_email_priority** [email] (mutation)
        Cambia la prioridad de un hilo de email.
      type: object
      properties:
        action:
          type: string
          description: "Debe ser 'set_priority'"
        thread_id:
          type: integer
          description: "ID del hilo"
        priority:
          type: string
          description: "Prioridad del hilo"
          enum: ["high", "medium", "low"]
      required: ["action", "thread_id", "priority"]

    SetEmailTagsArgs:
      description: |
        **set_email_tags** [email] (mutation)
        Establece las etiquetas de un hilo de email. Las etiquetas son strings libres.
      type: object
      properties:
        action:
          type: string
          description: "Debe ser 'set_tags'"
        thread_id:
          type: integer
          description: "ID del hilo"
        tags:
          type: array
          description: "Array de etiquetas (strings). Enviar array vacio para quitar todas."
      required: ["action", "thread_id", "tags"]

    SetWhatsappOutboundPolicyArgs:
      description: |
        **set_whatsapp_outbound_policy** [whatsapp_ops] (mutation)
        Configura el modo, los orígenes y el pie de no respuesta. El número físico se elige siempre por sus roles lógicos configurados con update_whatsapp_session; no guardes ni envíes un ID de sesión en esta política.
      type: object
      properties:
        mode:
          type: string
          description: "Modo de la política: desactivada, auditoría (solo registra) o forzada (enruta los envíos)"
          enum: ["disabled", "audit", "enforced"]
        apply_sources:
          type: array
          description: "Lista de orígenes de envío a los que aplica la política (usar ['*'] para todos)"
        no_reply_footer_enabled:
          type: boolean
          description: "Añadir un pie de no respuesta a los mensajes salientes"
        no_reply_footer_text:
          type: string
          description: "Texto del pie de no respuesta (usa {url} para insertar el enlace de contacto; máximo 1000 caracteres)"
        no_reply_footer_texts:
          type: object
          description: "Textos del pie de no respuesta por idioma"
        inbound_redirect_enabled:
          type: boolean
          description: "Responder automáticamente cuando un cliente escribe a un número secundario y dirigirlo al número con rol General mediante un enlace de WhatsApp con su mensaje ya rellenado"
        inbound_redirect_cooldown_seconds:
          type: integer
          description: "Tiempo mínimo entre respuestas de redirección al mismo cliente y número secundario (0-3600 segundos)"
        inbound_redirect_texts:
          type: object
          description: "Texto de redirección por idioma; usa {url} para el enlace directo al número General con el mensaje original prerrellenado"
        sticky_enabled:
          type: boolean
          description: "Mantener al cliente en el mismo número una vez asignado"
        failover_enabled:
          type: boolean
          description: "Reenviar por otro número disponible si el asignado no está conectado"
        audit_enabled:
          type: boolean
          description: "Registrar en auditoría las decisiones de enrutamiento de envío"
      required: ["mode"]

    SmartKnowledgeUpdateArgs:
      description: |
        **smart_knowledge_update** [prompt] (mutation)
        Busca y actualiza datos aprendidos que contradigan o estén desactualizados según la instrucción del usuario. Usa esto cuando el usuario dice cosas como 'ahora aceptamos PayPal', 'hemos cambiado el horario', 'ya no hacemos envíos a X', etc. Primero llama SIN confirm para ver preview, luego con confirm=true y selected_ids para ejecutar.
        ⚠️ Requires confirmation
      type: object
      properties:
        instruction:
          type: string
          description: "Instrucción en lenguaje natural describiendo el cambio en el negocio"
        confirm:
          type: boolean
          description: "true para ejecutar los cambios (segunda llamada)"
        selected_ids:
          type: array
          description: "IDs de snippets a modificar (solo con confirm=true). Si no se pasa, se aplican todos los cambios propuestos"
        changes:
          type: array
          description: "Lista de cambios propuestos del preview (para Phase 2 con confirm=true). Cada elemento: {id, action, proposed}"
      required: ["instruction"]

    SnoozeEmailThreadArgs:
      description: |
        **snooze_email_thread** [email] (mutation)
        Pospone un hilo de email hasta una fecha y hora especifica. El hilo se reabrira automaticamente cuando llegue el momento.
      type: object
      properties:
        action:
          type: string
          description: "Debe ser 'snooze'"
        thread_id:
          type: integer
          description: "ID del hilo"
        until:
          type: string
          description: "Fecha y hora hasta cuando posponer (formato ISO 8601, ej: 2026-03-25T09:00:00)"
      required: ["action", "thread_id", "until"]

    StartCampaignArgs:
      description: |
        **start_campaign** [mass_marketing] (mutation)
        Inicia el envio de una campana de marketing masivo. Funciona con campanas en estado borrador o programadas.
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
          description: "Accion fija: start"
        campaign_id:
          type: integer
          description: "ID de la campana a iniciar"
      required: ["action", "campaign_id"]

    SummarizeAiTicketArgs:
      description: |
        **summarize_ai_ticket** [tickets] (mutation)
        Genera (o devuelve cacheado) un resumen del hilo del ticket con la situacion, contexto del cliente y proximos pasos. Usa force para regenerarlo.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        ticket_id:
          type: integer
          description: "ID del ticket"
        force:
          type: boolean
          description: "Si true, regenera el resumen aunque exista uno cacheado"
      required: ["action", "ticket_id"]

    SyncKnowledgeNowArgs:
      description: |
        **sync_knowledge_now** [storage] (mutation)
        Fuerza la sincronizacion inmediata de los facts aprendidos al Vector Store (normalmente se hace automaticamente)
      type: object

    TestCrmEndpointArgs:
      description: |
        **test_crm_endpoint** [advanced] (query)
        Prueba la conectividad y respuesta de un endpoint CRM personalizado configurado en la tienda
      type: object
      properties:
        type:
          type: string
          description: "Tipo de endpoint: sidePanel_CustomerInfo, ai_CustomerInitialInfo, sidePanel_CustomerFindToJoin, search_Products, globalSearch"
          enum: ["sidePanel_CustomerInfo", "ai_CustomerInitialInfo", "sidePanel_CustomerFindToJoin", "search_Products", "globalSearch"]
        url:
          type: string
          description: "URL del endpoint a probar"
        method:
          type: string
          description: "Metodo HTTP (GET o POST, default GET)"
          enum: ["GET", "POST"]
          default: "GET"
        auth:
          type: object
          description: "Configuracion de autenticacion con type (header, basic, body, query) y campos"
        test_phone:
          type: string
          description: "Telefono de prueba (default +34600000000)"
      required: ["type", "url"]

    TestEcommerceConnectionArgs:
      description: |
        **test_ecommerce_connection** [integrations] (query)
        Verifica que la conexion con la plataforma e-commerce (Shopify, WooCommerce, PrestaShop o VTEX) funciona correctamente. Usa las credenciales guardadas si no se proporcionan.
      type: object

    TestEmailConnectionArgs:
      description: |
        **test_email_connection** [email] (query)
        Verifica que la conexion IMAP y SMTP de una cuenta de email funciona correctamente.
      type: object
      properties:
        account_id:
          type: integer
          description: "ID de la cuenta a probar"
        imap_host:
          type: string
          description: "Servidor IMAP"
        imap_port:
          type: string
          description: "Puerto IMAP"
        imap_user:
          type: string
          description: "Usuario IMAP"
        imap_password:
          type: string
          description: "Contrasena IMAP"
        smtp_host:
          type: string
          description: "Servidor SMTP"
        smtp_port:
          type: string
          description: "Puerto SMTP"
        smtp_user:
          type: string
          description: "Usuario SMTP"
        smtp_password:
          type: string
          description: "Contrasena SMTP"
        email_address:
          type: string
          description: "Direccion de email"
      required: ["account_id", "imap_host", "imap_port", "imap_user", "imap_password", "smtp_host", "smtp_port", "smtp_user", "smtp_password", "email_address"]

    TestShopifyConnectionArgs:
      description: |
        **test_shopify_connection** [integrations] (query)
        Valida la conexion con una tienda Shopify verificando las credenciales y los permisos OAuth. Si no se proporcionan credenciales, usa las almacenadas en la configuracion de la tienda.
      type: object
      properties:
        shopify_url:
          type: string
          description: "URL de la tienda Shopify (ej: mitienda.myshopify.com). Si no se proporciona, usa las credenciales guardadas"
        shopify_token:
          type: string
          description: "Token de acceso Shopify. Si no se proporciona, usa el token guardado"

    TestVapiKeyArgs:
      description: |
        **test_vapi_key** [voice] (query)
        Valida una API key de Vapi contra el servicio sin guardarla. Util para comprobar que la clave es correcta antes de activar el asistente de voz.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        voice_api_key:
          type: string
          description: "API key privada de Vapi a validar. No se almacena, solo se comprueba contra el servicio."
      required: ["action", "voice_api_key"]

    TestWebhookArgs:
      description: |
        **test_webhook** [advanced] (mutation)
        Envia un webhook de prueba. Usa automaticamente la URL y secret configurados en la tienda si no se proporcionan parametros.
      type: object
      properties:
        webhook_url:
          type: string
          description: "URL del webhook a probar. Si no se envia, usa la URL guardada en la configuracion"
        webhook_secret:
          type: string
          description: "Secret para firmar el webhook. Si no se envia, usa el secret guardado en la configuracion"

    ToggleAnalyticsArgs:
      description: |
        **toggle_analytics** [stats] (mutation)
        Activa o desactiva el registro de analytics con structured outputs para esta tienda
      type: object
      properties:
        enable_structured_outputs:
          type: boolean
          description: "true para activar analytics con structured outputs, false para desactivar"
      required: ["enable_structured_outputs"]

    ToggleAutoDescribeImagesArgs:
      description: |
        **toggle_auto_describe_images** [general] (mutation)
        Activa o desactiva el analisis automatico de imagenes, documentos PDF y audios enviados por clientes via WhatsApp. Afecta a todos los sistemas de IA (Piloto Automatico, WhatsApp Auto, respuestas manuales)
      type: object
      properties:
        auto_describe_images:
          type: boolean
          description: "true para activar, false para desactivar"
        auto_sentiment_analysis:
          type: boolean
          description: "Estado actual del analisis de sentimiento"
      required: ["auto_describe_images"]

    ToggleAutoSentimentAnalysisArgs:
      description: |
        **toggle_auto_sentiment_analysis** [general] (mutation)
        Activa o desactiva el análisis automático de sentimiento en las conversaciones de WhatsApp. Cuando esta activado, la IA analiza el sentimiento del cliente y muestra indicadores de satisfaccion, urgencia e intencion en la extension de Chrome.
      type: object
      properties:
        auto_sentiment_analysis:
          type: boolean
          description: "true para activar, false para desactivar"
        auto_describe_images:
          type: boolean
          description: "Estado actual de la descripcion automatica de imagenes"
      required: ["auto_sentiment_analysis"]

    ToggleAutoTranslateArgs:
      description: |
        **toggle_auto_translate** [general] (mutation)
        Activa o desactiva la traduccion automatica de mensajes
      type: object
      properties:
        translateallways:
          type: boolean
          description: "true para activar, false para desactivar"
      required: ["translateallways"]

    ToggleAutolearningArgs:
      description: |
        **toggle_autolearning** [prompt] (mutation)
        Activa o desactiva el aprendizaje automatico de la IA
      type: object
      properties:
        autolearning_enabled:
          type: boolean
          description: "true para activar, false para desactivar"
      required: ["autolearning_enabled"]

    ToggleKnowledgeFileArgs:
      description: |
        **toggle_knowledge_file** [storage] (mutation)
        Activa o pausa un archivo sin eliminarlo (la IA solo usa archivos activos)
      type: object
      properties:
        file_id:
          type: integer
          description: "ID del archivo"
        is_active:
          type: boolean
          description: "true para activar, false para pausar"
      required: ["file_id", "is_active"]

    ToggleSnippetPermanentArgs:
      description: |
        **toggle_snippet_permanent** [knowledge] (mutation)
        Alterna el estado permanente de un snippet (protege de expiracion por antiguedad)
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        id:
          type: integer
          description: "ID del snippet"
      required: ["action", "id"]

    ToggleWebSearchArgs:
      description: |
        **toggle_web_search** [prompt] (mutation)
        Activa o desactiva la busqueda en internet de la IA. Cuando esta activa, la IA puede buscar informacion actualizada en internet para responder preguntas sobre tendencias, precios del mercado, noticias o datos que cambian frecuentemente.
      type: object
      properties:
        enable_web_search:
          type: boolean
          description: "true para activar busqueda web, false para desactivar"
        prompt:
          type: string
          description: "Prompt actual (se preserva al cambiar web search)"
      required: ["enable_web_search"]

    ToggleWhatsappWorkflowArgs:
      description: |
        **toggle_whatsapp_workflow** [automation] (mutation)
        Activa o pausa un workflow de WhatsApp existente
      type: object
      properties:
        id:
          type: integer
          description: "ID del workflow a modificar"
        enabled:
          type: boolean
          description: "true para activar, false para pausar"
      required: ["id", "enabled"]

    TranslateConversationArgs:
      description: |
        **translate_conversation** [ai_analysis] (query)
        Traduce los ultimos mensajes de una conversacion a otro idioma usando IA
      type: object
      properties:
        action:
          type: string
        phone:
          type: string
          description: "Telefono del cliente"
        target_language:
          type: string
          description: "Idioma destino (es, en, de, fr, pt, it, etc.)"
        last_n:
          type: integer
          description: "Ultimos N mensajes a traducir (default 20, max 50)"
        summary_type:
          type: string
          description: "Tipo de resumen: quick (rapido), actionable (con acciones), detailed (detallado)"
          enum: ["quick", "actionable", "detailed"]
        days:
          type: integer
          description: "Numero de dias a analizar"
        tone:
          type: string
          description: "Tono para la respuesta"
        hours:
          type: integer
          description: "Ultimas N horas a analizar"
        limit:
          type: integer
          description: "Maximo de resultados"
      required: ["action", "phone", "target_language"]

    TriggerSmartFollowupArgs:
      description: |
        **trigger_smart_followup** [smart_followup] (mutation)
        Lanza manualmente el analisis de seguimiento inteligente para esta tienda. Si ya hay una ejecucion en curso (cron o manual), devuelve error.
        ⚠️ Requires confirmation
      type: object
      properties:
        conversation_hash:
          type: string
          description: "Hash de conversación específica"

    UnarchiveCampaignArgs:
      description: |
        **unarchive_campaign** [mass_marketing] (mutation)
        Restaura una campaña archivada a la lista principal
      type: object
      properties:
        action:
          type: string
        campaign_id:
          type: integer
          description: "ID de la campaña a desarchivar"
      required: ["action", "campaign_id"]

    UnassignCalendarAgentArgs:
      description: |
        **unassign_calendar_agent** [calendar] (mutation)
        Desasigna un agente de un calendario
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        calendar_id:
          type: integer
          description: "ID del calendario"
        agent_id:
          type: integer
          description: "ID del agente"
      required: ["action", "calendar_id", "agent_id"]

    UnlinkEmailContactArgs:
      description: |
        **unlink_email_contact** [email] (mutation)
        Elimina la vinculacion de un contacto de WhatsApp con un hilo de email
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        thread_id:
          type: integer
          description: "ID del hilo de email"
      required: ["action", "thread_id"]

    UnpublishFaqArgs:
      description: |
        **unpublish_faq** [plugins] (mutation)
        Despublica una o varias FAQs del plugin Product Q&A
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        faq_ids:
          type: array
          description: "IDs de las FAQs a despublicar"
      required: ["action", "faq_ids"]

    UnsnoozeEmailThreadArgs:
      description: |
        **unsnooze_email_thread** [email] (mutation)
        Reactiva un hilo de email que estaba pospuesto, devolviendolo a estado abierto.
      type: object
      properties:
        action:
          type: string
          description: "Debe ser 'unsnooze'"
        thread_id:
          type: integer
          description: "ID del hilo"
      required: ["action", "thread_id"]

    UpdateAgentArgs:
      description: |
        **update_agent** [agents] (mutation)
        Modifica los datos de un agente existente
      type: object
      properties:
        action:
          type: string
        id:
          type: integer
          description: "ID del agente a editar"
        nickname:
          type: string
          description: "Nuevo nombre corto del agente"
        full_name:
          type: string
          description: "Nuevo nombre completo del agente"
        email:
          type: string
          description: "Nuevo email del agente"
        color:
          type: string
          description: "Nuevo color en formato hexadecimal"
        phone:
          type: string
          description: "Nuevo telefono del agente"
        pin:
          type: string
          description: "Nuevo PIN numerico para identificacion en la extension de Chrome"
        permissions_json:
          type: string
          description: "JSON string con los permisos del agente (ej: {"ai_generate": true, "notes_view": true}). Alternativa a save_agent_permissions."
        permissions:
          type: object
          description: "Permisos del agente (objeto JSON con permisos por seccion)"
      required: ["action", "id"]

    UpdateAiErrorArgs:
      description: |
        **update_ai_error** [knowledge] (mutation)
        Update an existing AI correction. Can change the content, category, or status (active/rejected).
      type: object
      properties:
        id:
          type: integer
          description: "ID of the correction to update"
        fact_content:
          type: string
          description: "New corrected text"
        category:
          type: string
          description: "New category: shipping, pricing, warranty, product, tone, policy, communication, general"
        status:
          type: string
          description: "New status: active or rejected"
      required: ["id"]

    UpdateAiTicketArgs:
      description: |
        **update_ai_ticket** [tickets] (mutation)
        Actualiza campos de un ticket interno: titulo, descripcion, estado, prioridad, categoria o fecha limite.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        ticket_id:
          type: integer
          description: "ID del ticket"
        title:
          type: string
          description: "Nuevo titulo del ticket"
        description:
          type: string
          description: "Nueva descripcion interna del caso"
        status:
          type: string
          description: "Nuevo estado del ticket"
          enum: ["new", "pending_customer", "pending_internal", "agent_replied", "customer_notified", "resolved", "closed", "reopened", "escalated"]
        priority:
          type: string
          description: "Nueva prioridad interna"
          enum: ["P0", "P1", "P2", "P3"]
        category:
          type: string
          description: "Nueva categoria interna"
        due_at:
          type: string
          description: "Fecha limite (YYYY-MM-DD HH:MM:SS)"
      required: ["action", "ticket_id"]

    UpdateAiTicketsSettingsArgs:
      description: |
        **update_ai_tickets_settings** [tickets] (mutation)
        Activa o desactiva el sistema de Tickets IA para la tienda.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        enabled:
          type: boolean
          description: "true para activar Tickets IA, false para desactivarlo"
      required: ["action", "enabled"]

    UpdateBillingInfoArgs:
      description: |
        **update_billing_info** [account] (mutation)
        Actualiza los datos de facturacion para las facturas
      type: object
      properties:
        billing_name:
          type: string
          description: "Nombre o razon social para facturacion"
        billing_tax_id:
          type: string
          description: "NIF/CIF/VAT ID"
        billing_address:
          type: string
          description: "Direccion linea 1"
        billing_address2:
          type: string
          description: "Direccion linea 2 (piso, puerta, etc.)"
        billing_city:
          type: string
          description: "Ciudad"
        billing_state:
          type: string
          description: "Provincia o estado"
        billing_postal_code:
          type: string
          description: "Codigo postal"
        billing_country:
          type: string
          description: "Pais"
        client_name:
          type: string
          description: "Nombre del titular de la cuenta"
        client_phone:
          type: string
          description: "Telefono de contacto de la cuenta"
        email_change_code:
          type: string
          description: "Codigo de verificacion para cambio de email"

    UpdateBusinessInfoArgs:
      description: |
        **update_business_info** [general] (mutation)
        Actualiza el tipo de negocio, tipo de venta y descripcion del negocio. Esta informacion ayuda a la IA a entender mejor tu negocio y dar respuestas mas relevantes.
      type: object
      properties:
        business_type:
          type: string
          description: "Tipo de negocio"
          enum: ["ecommerce", "professional_services", "restaurant_hospitality", "health_wellness", "education", "real_estate", "automotive", "other"]
        sale_type:
          type: string
          description: "Tipo de venta: products (productos), services (servicios), mixed (ambos), support_only (solo soporte)"
          enum: ["products", "services", "mixed", "support_only"]
        business_description:
          type: string
          description: "Descripcion breve del negocio (max 500 caracteres)"

    UpdateBusinessNameArgs:
      description: |
        **update_business_name** [general] (mutation)
        Actualiza el nombre publico de tu negocio. Se muestra en los mensajes de marketing y en la pagina de baja de WhatsApp.
      type: object
      properties:
        business_name:
          type: string
          description: "Nombre del negocio (max 255 caracteres)"
      required: ["business_name"]

    UpdateCalendarArgs:
      description: |
        **update_calendar** [calendar] (mutation)
        Actualiza propiedades de un calendario (nombre, descripcion, color, estado por defecto)
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        calendar_id:
          type: integer
          description: "ID del calendario"
        name:
          type: string
          description: "Nombre del calendario"
        description:
          type: string
          description: "Descripcion del calendario"
        color:
          type: string
          description: "Color del calendario"
        is_default:
          type: boolean
          description: "Si es el calendario por defecto"
      required: ["action", "calendar_id"]

    UpdateCalendarAvailabilityArgs:
      description: |
        **update_calendar_availability** [calendar] (mutation)
        Actualiza una regla de disponibilidad existente
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        rule_id:
          type: integer
          description: "ID de la regla de disponibilidad"
        start_time:
          type: string
          description: "Hora inicio HH:MM"
        end_time:
          type: string
          description: "Hora fin HH:MM"
        label:
          type: string
          description: "Etiqueta descriptiva"
        is_available:
          type: boolean
          description: "Si esta disponible"
        rule_type:
          type: string
          description: "Tipo de regla: weekly o specific_date"
        day_of_week:
          type: integer
          description: "Dia de la semana (0=lunes, 6=domingo). Solo para rule_type=weekly"
        specific_date:
          type: string
          description: "Fecha especifica YYYY-MM-DD. Solo para rule_type=specific_date"
      required: ["action", "rule_id"]

    UpdateCalendarEventArgs:
      description: |
        **update_calendar_event** [calendar] (mutation)
        Modifica un evento existente del calendario
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        event_id:
          type: integer
          description: "ID del evento"
        title:
          type: string
        description:
          type: string
        start_datetime:
          type: string
        end_datetime:
          type: string
        assigned_agent_id:
          type: integer
        all_day:
          type: integer
        date_from:
          type: string
          description: "Fecha inicio para filtrar"
        date_to:
          type: string
          description: "Fecha fin para filtrar"
        agent_id:
          type: integer
          description: "ID del agente"
        phone:
          type: string
          description: "Telefono del cliente"
      required: ["action", "event_id"]

    UpdateCalendarEventStatusArgs:
      description: |
        **update_calendar_event_status** [calendar] (mutation)
        Cambia el estado de un evento de calendario (pendiente, confirmado, cancelado, completado, no-show)
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        event_id:
          type: integer
          description: "ID del evento"
        status:
          type: string
          description: "Nuevo estado: pending, confirmed, cancelled, completed, no_show"
      required: ["action", "event_id", "status"]

    UpdateCalendarNotificationArgs:
      description: |
        **update_calendar_notification** [calendar] (mutation)
        Actualiza una notificacion automatica de calendario
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        notification_id:
          type: integer
          description: "ID de la notificacion"
        notification_type:
          type: string
          description: "Tipo de notificacion"
        channel:
          type: string
          description: "Canal de envio"
        timing_minutes:
          type: integer
          description: "Minutos antes/despues"
        template_text:
          type: string
          description: "Texto de la notificacion"
        is_enabled:
          type: boolean
          description: "Si esta habilitada"
      required: ["action", "notification_id"]

    UpdateCalendarServiceArgs:
      description: |
        **update_calendar_service** [calendar] (mutation)
        Actualiza propiedades de un servicio/tipo de cita existente
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        service_id:
          type: integer
          description: "ID del servicio"
        name:
          type: string
          description: "Nombre del servicio"
        duration_minutes:
          type: integer
          description: "Duracion en minutos"
        description:
          type: string
          description: "Descripcion"
        buffer_before_minutes:
          type: integer
          description: "Minutos de buffer antes"
        buffer_after_minutes:
          type: integer
          description: "Minutos de buffer despues"
        max_concurrent:
          type: integer
          description: "Maximo de citas concurrentes"
        price:
          type: string
          description: "Precio"
        currency:
          type: string
          description: "Moneda"
        requires_confirmation:
          type: boolean
          description: "Si requiere confirmacion"
        is_active:
          type: boolean
          description: "Si el servicio esta activo"
        sort_order:
          type: integer
          description: "Orden de visualizacion"
      required: ["action", "service_id"]

    UpdateCampaignArgs:
      description: |
        **update_campaign** [mass_marketing] (mutation)
        Modifica los datos de una campaña de marketing masivo existente (solo en estado borrador)
      type: object
      properties:
        action:
          type: string
        campaign_id:
          type: integer
          description: "ID de la campaña a actualizar"
        name:
          type: string
          description: "Nuevo nombre de la campaña"
        list_id:
          type: integer
          description: "ID de la lista de contactos"
        message_text:
          type: string
          description: "Texto del mensaje"
        send_interval_seconds:
          type: integer
          description: "Intervalo entre mensajes en segundos"
        translate_by_prefix:
          type: boolean
          description: "Traducir según prefijo telefónico"
        include_unsubscribe_link:
          type: boolean
          description: "Incluir enlace de baja"
        archive_after_send:
          type: boolean
          description: "Archivar tras enviar solo si el chat no estaba activo antes del envio"
        scheduled_at:
          type: string
          description: "Fecha/hora de envío programado (ISO 8601)"
        session_ids:
          type: array
          description: "IDs de sesiones WhatsApp a usar"
        media_url:
          type: string
          description: "URL del archivo multimedia"
        media_type:
          type: string
          description: "Tipo de multimedia (image, video, document)"
        media_filename:
          type: string
          description: "Nombre del archivo multimedia"
        segment_filters:
          type: object
          description: "Filtros de segmentacion para enviar solo a contactos que cumplan criterios"
        is_recurring:
          type: boolean
          description: "Si true, la campana se ejecuta de forma recurrente segun recurring_cron"
        recurring_cron:
          type: string
          description: "Expresion cron para campanas recurrentes. Requerido si is_recurring es true."
      required: ["action", "campaign_id"]

    UpdateContactInfoArgs:
      description: |
        **update_contact_info** [account] (mutation)
        Actualiza nombre, email y telefono de la cuenta
      type: object
      properties:
        client_name:
          type: string
          description: "Nombre del titular de la cuenta"
        client_email:
          type: string
          description: "NO USAR - El email requiere verificacion OTP y solo se puede cambiar desde la pagina Mi Cuenta del dashboard. El asistente no puede cambiar el email."
        client_phone:
          type: string
          description: "Telefono de contacto"
        billing_name:
          type: string
          description: "Nombre fiscal"
        billing_tax_id:
          type: string
          description: "NIF/CIF/Tax ID"
        billing_address:
          type: string
          description: "Direccion fiscal"
        billing_address2:
          type: string
          description: "Direccion linea 2 (piso, puerta, etc.)"
        billing_city:
          type: string
          description: "Ciudad"
        billing_state:
          type: string
          description: "Provincia o estado"
        billing_postal_code:
          type: string
          description: "Codigo postal"
        billing_country:
          type: string
          description: "Pais"
        email_change_code:
          type: string
          description: "Codigo de verificacion para cambio de email"

    UpdateCrmCustomerArgs:
      description: |
        **update_crm_customer** [crm] (mutation)
        Actualiza los datos de un contacto existente en el CRM interno
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        whatsapp_number:
          type: string
          description: "Numero de WhatsApp del contacto a actualizar"
        full_name:
          type: string
          description: "Nombre completo"
        company_alias:
          type: string
          description: "Nombre de empresa"
        email:
          type: string
          description: "Email de contacto"
        alternate_phone:
          type: string
          description: "Telefono alternativo"
        address_street:
          type: string
          description: "Calle"
        address_city:
          type: string
          description: "Ciudad"
        address_state_province:
          type: string
          description: "Provincia o estado"
        address_postal_code:
          type: string
          description: "Codigo postal"
        address_country:
          type: string
          description: "Codigo de pais (ISO 2 letras)"
        tax_id:
          type: string
          description: "NIF/CIF/Tax ID"
        is_company:
          type: boolean
          description: "Si es empresa (true) o persona (false)"
        preferred_language:
          type: string
          description: "Idioma preferido del contacto"
        time_zone:
          type: string
          description: "Zona horaria del contacto"
      required: ["action", "whatsapp_number"]

    UpdateCrmEndpointsArgs:
      description: |
        **update_crm_endpoints** [advanced] (mutation)
        Define endpoints para sincronizar datos con tu CRM
        ⚠️ Requires confirmation
      type: object
      properties:
        add_crm_endpoint:
          type: string
          description: "JSON de UN endpoint para ANADIR sin borrar los existentes. Formato: {"type": "TIPO", "url": "https://...", "method": "GET|POST"}. Tipos validos: sidePanel_CustomerInfo, ai_CustomerInitialInfo, sidePanel_CustomerFindToJoin, search_Products, globalSearch, verify_conversion. USAR SIEMPRE ESTE."
        remove_crm_endpoint:
          type: string
          description: "Tipo del endpoint a eliminar"

    UpdateCustomFunctionsArgs:
      description: |
        **update_custom_functions** [advanced] (mutation)
        Define APIs que la IA puede llamar durante conversaciones
        ⚠️ Requires confirmation
      type: object
      properties:
        add_function:
          type: string
          description: "JSON de UNA funcion para ANADIR sin borrar las existentes. USAR SIEMPRE ESTE para crear nuevas funciones."
        remove_function:
          type: string
          description: "Nombre de la funcion a eliminar"

    UpdateCustomerAiErrorArgs:
      description: |
        **update_customer_ai_error** [knowledge] (mutation)
        Edit an existing correction for the customer-facing WhatsApp AI.
      type: object
      properties:
        id:
          type: integer
          description: "ID of the correction to update"
        fact_content:
          type: string
          description: "Updated correct information"
        category:
          type: string
          description: "Updated category"
        status:
          type: string
          description: "New status: active or rejected"
      required: ["id"]

    UpdateCustomerTagsArgs:
      description: |
        **update_customer_tags** [general] (mutation)
        Configura las etiquetas para clasificar clientes
      type: object
      properties:
        add_tag:
          type: string
          description: "JSON de UNA etiqueta para ANADIR sin borrar las existentes. Formato: {"name": "VIP", "color": "#ff0000"}. USAR SIEMPRE ESTE."
        remove_tag:
          type: string
          description: "Nombre de la etiqueta a eliminar"
        customerTags:
          type: array
          description: "Array completo de tags (reemplaza todos)"

    UpdateDateFormatArgs:
      description: |
        **update_date_format** [general] (mutation)
        Cambia el formato en que se muestran las fechas
      type: object
      properties:
        dateformat_pref:
          type: string
          description: "Formato de fecha"
          enum: ["DD/MM/YYYY", "MM/DD/YYYY", "YYYY/MM/DD"]
      required: ["dateformat_pref"]

    UpdateDocqaAssistantArgs:
      description: |
        **update_docqa_assistant** [plugins] (mutation)
        Modifica la configuracion de un asistente de documentacion existente
      type: object
      properties:
        assistant_id:
          type: integer
          description: "ID del asistente a modificar (obtener de list_docqa_assistants)"
        display_name:
          type: string
          description: "Nuevo nombre del asistente"
        prompt:
          type: string
          description: "Nuevas instrucciones para la IA"
        is_enabled:
          type: boolean
          description: "true para activar, false para desactivar"
        language_mode:
          type: string
          description: "Modo de idioma"
          enum: ["auto", "fixed", "selector"]
        language_fixed:
          type: string
          description: "Idioma fijo"
        rate_limit_per_session:
          type: integer
          description: "Limite de preguntas por sesion"
        allowed_domains:
          type: array
          description: "Dominios permitidos"
        language_available:
          type: array
          description: "Idiomas disponibles (array)"
        language_show_selector:
          type: boolean
          description: "Mostrar selector de idioma"
        rate_limit_window_minutes:
          type: integer
          description: "Ventana de rate limit en minutos"
        config_design:
          type: object
          description: "Configuracion de diseno (JSON)"
        config_texts:
          type: object
          description: "Textos personalizados (JSON)"
      required: ["assistant_id"]

    UpdateEmailAccountArgs:
      description: |
        **update_email_account** [email] (mutation)
        Modifica los campos de una cuenta de correo existente. Solo se actualizan los campos enviados.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        id:
          type: integer
          description: "ID de la cuenta a actualizar"
        label:
          type: string
          description: "Nuevo nombre descriptivo"
        email_address:
          type: string
          description: "Nueva direccion de email"
        imap_host:
          type: string
          description: "Servidor IMAP"
        imap_port:
          type: integer
          description: "Puerto IMAP"
        imap_user:
          type: string
          description: "Usuario IMAP"
        imap_password:
          type: string
          description: "Nueva contrasena IMAP (se cifra automaticamente)"
        smtp_host:
          type: string
          description: "Servidor SMTP"
        smtp_port:
          type: integer
          description: "Puerto SMTP"
        smtp_user:
          type: string
          description: "Usuario SMTP"
        smtp_password:
          type: string
          description: "Nueva contrasena SMTP (se cifra automaticamente)"
        smtp_from_name:
          type: string
          description: "Nuevo nombre del remitente"
        signature_html:
          type: string
          description: "Firma HTML para los emails"
        is_active:
          type: integer
          description: "1 para activar, 0 para desactivar la cuenta"
        agent_hashes:
          type: array
          description: "Lista de phone_hash de agentes asignados. Reemplaza la asignacion actual"
        auth_type:
          type: string
          description: "Tipo de autenticacion: 'basic' (IMAP/SMTP) o 'oauth2'"
        oauth_provider:
          type: string
          description: "Proveedor OAuth: 'gmail', 'microsoft' o 'none'. Requerido cuando auth_type=oauth2"
        ai_classification_enabled:
          type: integer
          description: "1 para activar clasificacion IA de emails, 0 para desactivar"
        ai_transcription_enabled:
          type: integer
          description: "1 para activar transcripcion IA de adjuntos, 0 para desactivar"
      required: ["action", "id"]

    UpdateEmailAgentsArgs:
      description: |
        **update_email_agents** [email] (mutation)
        Actualiza los agentes asignados a una cuenta de correo electronico.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        id:
          type: integer
          description: "ID de la cuenta de email"
        agent_hashes:
          type: array
          description: "Lista de phone_hash de agentes a asignar. Array vacio para quitar todos"
      required: ["action", "id"]

    UpdateEmailAutoresponderArgs:
      description: |
        **update_email_autoresponder** [email] (mutation)
        Configura el auto-responder IA para una cuenta de email. Puede generar borradores o enviar respuestas automaticas.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        id:
          type: integer
          description: "ID de la cuenta de email"
        auto_responder_enabled:
          type: boolean
          description: "Activar o desactivar el auto-responder"
        auto_responder_mode:
          type: string
          description: "Modo: 'draft' (genera borrador para revision) o 'automatic' (envia automaticamente)"
        auto_responder_schedule:
          type: string
          description: "Horario: 'always' (siempre) o 'outside_hours' (solo fuera de horario)"
        auto_responder_thread_limit:
          type: integer
          description: "Maximo de respuestas automaticas por hilo (1-10). Default: 2"
        auto_responder_daily_limit:
          type: integer
          description: "Limite diario de auto-respuestas"
        auto_responder_custom_instructions:
          type: string
          description: "Instrucciones personalizadas para la IA del auto-responder"
      required: ["action", "id"]

    UpdateEmailFoldersArgs:
      description: |
        **update_email_folders** [email] (mutation)
        Configura el mapeo de carpetas IMAP para una cuenta de email (Enviados, Papelera, Archivo, Spam). Necesario para la sincronizacion bidireccional.
      type: object
      properties:
        action:
          type: string
          description: "Debe ser 'update_folders'"
        id:
          type: integer
          description: "ID de la cuenta de email"
        sent_folder:
          type: string
          description: "Nombre de la carpeta de enviados"
        trash_folder:
          type: string
          description: "Nombre de la carpeta de papelera"
        archive_folder:
          type: string
          description: "Nombre de la carpeta de archivo"
        spam_folder:
          type: string
          description: "Nombre de la carpeta de spam"
      required: ["action", "id"]

    UpdateEmailRetentionArgs:
      description: |
        **update_email_retention** [email] (mutation)
        Cambia el periodo de retencion de emails. Los emails mas antiguos se eliminan automaticamente.
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        retention_days:
          type: integer
          description: "Dias de retencion: 30, 60, 90 o 180"
          enum: [30, 60, 90, 180]
        id:
          type: integer
          description: "ID de la cuenta de correo"
      required: ["action", "retention_days", "id"]

    UpdateEmailRuleArgs:
      description: |
        **update_email_rule** [email] (mutation)
        Actualiza una regla de email existente. Puede modificar nombre, prioridad, estado, condiciones o acciones.
      type: object
      properties:
        action:
          type: string
          description: "Debe ser 'update'"
        id:
          type: integer
          description: "ID de la regla a actualizar"
        name:
          type: string
          description: "Nuevo nombre"
        priority:
          type: integer
          description: "Nueva prioridad"
        is_active:
          type: integer
          description: "1=activa, 0=desactivada"
        conditions:
          type: array
          description: "Nuevas condiciones (reemplaza las actuales)"
        actions:
          type: array
          description: "Nuevas acciones (reemplaza las actuales)"
      required: ["action", "id"]

    UpdateEmailSyncArgs:
      description: |
        **update_email_sync** [email] (mutation)
        Configura el modo de sincronizacion IMAP para una cuenta: solo bandeja de entrada o bidireccional (sincroniza acciones como archivar, eliminar, spam con el servidor).
      type: object
      properties:
        action:
          type: string
          description: "Debe ser 'update_sync'"
        id:
          type: integer
          description: "ID de la cuenta de email"
        sync_mode:
          type: string
          description: "Modo de sincronizacion: inbox_only o bidirectional"
      required: ["action", "id"]

    UpdateKnowledgeFileArgs:
      description: |
        **update_knowledge_file** [storage] (mutation)
        Cambia el titulo, descripcion y/o contenido de un archivo de conocimiento. Para archivos de texto (txt, md, csv, json, html) tambien permite editar el contenido del archivo.
      type: object
      properties:
        file_id:
          type: integer
          description: "ID del archivo"
        title:
          type: string
          description: "Nuevo titulo (max 200 caracteres)"
        description:
          type: string
          description: "Nueva descripcion (max 500 caracteres)"
        content:
          type: string
          description: "Nuevo contenido del archivo (solo para archivos de texto: txt, md, csv, json, html). Si se envia, el archivo se reemplaza en OpenAI y se re-indexa en el Vector Store. No enviar este parametro si solo se quiere cambiar titulo/descripcion."
      required: ["file_id", "title"]

    UpdateKnowledgeSnippetArgs:
      description: |
        **update_knowledge_snippet** [prompt] (mutation)
        Permite aprobar, rechazar, editar o eliminar un dato aprendido. Usa filter=pending en list_knowledge_snippets para ver los pendientes de revision. IMPORTANTE: Esta accion requiere confirmacion - ver seccion confirmation_flow.
        ⚠️ Requires confirmation
      type: object
      properties:
        id:
          type: integer
          description: "ID del snippet a gestionar"
        action:
          type: string
          description: "Accion a realizar: approve, reject, edit, delete, resolve_conflict, keep_both, toggle_permanent, reject_and_propose"
          enum: ["approve", "reject", "edit", "delete", "resolve_conflict", "keep_both", "toggle_permanent", "reject_and_propose"]
        content:
          type: string
          description: "Nuevo contenido (solo para action=edit)"
        category:
          type: string
          description: "Nueva categoria (solo para action=edit)"
        keep_id:
          type: integer
          description: "ID del snippet a mantener (solo para action=resolve_conflict)"
      required: ["id", "action"]

    UpdateLanguageArgs:
      description: |
        **update_language** [general] (mutation)
        Cambia el idioma del dashboard y las respuestas de la IA
      type: object
      properties:
        language:
          type: string
          description: "Codigo del idioma (es=Espanol, en=Ingles, de=Aleman, fr=Frances, pt=Portugues, hu=Hungaro, it=Italiano)"
          enum: ["es", "en", "de", "fr", "pt", "hu", "it"]
      required: ["language"]

    UpdateOrderSettingsArgs:
      description: |
        **update_order_settings** [general] (mutation)
        Configura prefijos de pedidos y telefonos/emails a ignorar
      type: object
      properties:
        order_prefix:
          type: string
          description: "Prefijo para numeros de pedido (ej: #, PED-)"
          default: "#"
        order_suffix:
          type: string
          description: "Sufijo para numeros de pedido"
        add_ignore_phone:
          type: string
          description: "Telefono a ANADIR sin borrar los existentes. USAR SIEMPRE ESTE para anadir telefonos."
        remove_ignore_phone:
          type: string
          description: "Telefono a eliminar de la lista de ignorados"
        add_ignore_email:
          type: string
          description: "Email a ANADIR sin borrar los existentes. USAR SIEMPRE ESTE para anadir emails."
        remove_ignore_email:
          type: string
          description: "Email a eliminar de la lista de ignorados"
        add_helper:
          type: string
          description: "JSON para crear o actualizar un atajo. Formato: {"name": "NOMBRE_CORTO", "text": "TEXTO_DEL_ATAJO", "send": true/false}. El campo 'send' activa el envio automatico (el atajo se envia al cliente sin que el agente pulse enviar). Si no se incluye 'send', se desactiva por defecto. Ejemplo con envio automatico: {"name": "compra VIN ok", "text": "la compra esta correcta para dicho numero de bastidor", "send": true}. Si ya existe un atajo con el mismo nombre, se actualiza (util para activar/desactivar envio automatico sin recrear el atajo)."
        remove_helper:
          type: string
          description: "Nombre corto del atajo a eliminar (ej: bastidor)"
        ignore_phones:
          type: string
          description: "Lista de telefonos a ignorar (JSON array)"
        ignore_emails:
          type: string
          description: "Lista de emails a ignorar (JSON array)"
        helpers:
          type: string
          description: "Lista de helpers (JSON array)"

    UpdateScheduledMessageArgs:
      description: |
        **update_scheduled_message** [whatsapp_ops] (mutation)
        Updates a pending scheduled WhatsApp message. Can modify text, datetime and/or logical sender role. Only pending messages can be edited.
        ⚠️ Requires confirmation
      type: object
      properties:
        action:
          type: string
        id:
          type: integer
          description: "ID of the scheduled message to update"
        message_text:
          type: string
          description: "New message text"
        scheduled_at:
          type: string
          description: "New date and time in format YYYY-MM-DD HH:MM (shop timezone)"
        sender_role:
          type: string
          description: "New logical WhatsApp sender role"
          enum: ["general", "operations", "marketing"]
        agent_id:
          type: integer
          description: "ID del agente que modifica el mensaje"
      required: ["action", "id"]

    UpdateStoreUrlArgs:
      description: |
        **update_store_url** [general] (mutation)
        Actualiza la URL de tu tienda online
      type: object
      properties:
        url_tienda:
          type: string
          description: "URL completa de la tienda (ej: https://mitienda.com)"
      required: ["url_tienda"]

    UpdateTaskArgs:
      description: |
        **update_task** [tasks] (mutation)
        Modifica una tarea existente: cambiar estado, texto, prioridad, fecha limite o asignacion
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        task_id:
          type: integer
          description: "ID de la tarea a actualizar"
        task_text:
          type: string
          description: "Nuevo texto de la tarea"
        status:
          type: string
          description: "Nuevo estado"
          enum: ["pending", "in_progress", "completed", "cancelled"]
        due_date:
          type: string
          description: "Nueva fecha limite (YYYY-MM-DD)"
        priority:
          type: string
          enum: ["low", "medium", "high"]
        assigned_agent_id:
          type: integer
          description: "Nuevo agente asignado"
        agent_id:
          type: integer
          description: "ID del agente"
        phone:
          type: string
          description: "Telefono del cliente"
        limit:
          type: integer
          description: "Maximo de resultados"
        offset:
          type: integer
          description: "Posicion de inicio para paginacion"
        include_completed:
          type: boolean
          description: "Incluir tareas completadas"
      required: ["action", "task_id"]

    UpdateTasksSettingsArgs:
      description: |
        **update_tasks_settings** [tasks] (mutation)
        Activa o desactiva el modulo de tareas para la tienda
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        enabled:
          type: boolean
          description: "Si el modulo de tareas debe quedar activado (true) o desactivado (false)"
      required: ["action", "enabled"]

    UpdateTimezoneArgs:
      description: |
        **update_timezone** [general] (mutation)
        Cambia la zona horaria para mostrar fechas y horas correctamente
      type: object
      properties:
        timezone_pref:
          type: string
          description: "Zona horaria en formato IANA (ej: Europe/Madrid, America/Mexico_City)"
      required: ["timezone_pref"]

    UpdateWhatsappProfileArgs:
      description: |
        **update_whatsapp_profile** [whatsapp_ops] (mutation)
        Actualiza campos del perfil de WhatsApp: info/about, y datos de empresa (descripcion, direccion, email, web, horario). El nombre solo se puede cambiar en cuentas personales (no Business). Opcionalmente aplica los cambios a otras sesiones conectadas.
      type: object
      properties:
        session_id:
          type: integer
          description: "ID de la sesion WhatsApp"
        name:
          type: string
          description: "Nuevo nombre (min 3 chars, solo cuentas personales, NO funciona en Business)"
        status:
          type: string
          description: "Nuevo texto de info/about (max 139 chars)"
        description:
          type: string
          description: "Descripcion de empresa (solo Business)"
        address:
          type: string
          description: "Direccion de empresa (solo Business)"
        email:
          type: string
          description: "Email de empresa (solo Business)"
        websites:
          type: array
          description: "URLs de la empresa (solo Business)"
        apply_to_sessions:
          type: array
          description: "IDs de otras sesiones conectadas a las que aplicar los mismos cambios"
      required: ["session_id"]

    UpdateWhatsappSessionArgs:
      description: |
        **update_whatsapp_session** [automation] (mutation)
        Actualiza la etiqueta y uno o varios roles lógicos de un número de WhatsApp. Un mismo número puede ser General, Operaciones y Marketing a la vez; no guardes IDs físicos en automatizaciones.
      type: object
      properties:
        session_id:
          type: integer
          description: "ID de la sesion a editar. Usa get_whatsapp_status para obtener los IDs."
        label:
          type: string
          description: "Etiqueta para identificar la sesion (max 50 caracteres). Null para quitar la etiqueta."
        routing_roles:
          type: array
          description: "Uno o varios usos del número: general=conversaciones y destino público; operations=pedidos, reseñas y avisos; marketing=campañas masivas. General requiere que el número ya esté conectado."
      required: ["session_id"]

    UpdateWhatsappWorkflowArgs:
      description: |
        **update_whatsapp_workflow** [automation] (mutation)
        Modifica un workflow existente (cambiar condiciones, añadir/quitar palabras clave, editar acciones, renombrar, activar/desactivar). Soporta update parcial: solo se sobreescriben los campos que se envian, los demas se mantienen sin cambios. IMPORTANTE: el parametro 'id' es OBLIGATORIO y debe ser el ID numerico del workflow (obtenido de list_whatsapp_workflows). Si el usuario dice 'ajustalo', 'yes apply', 'hazlo' u otra respuesta de seguimiento, DEBES recordar el workflow_id del contexto previo de la conversacion y enviarlo. NUNCA enviar esta accion sin 'id'. Para cambiar solo el mensaje de una accion: SIEMPRE leer primero con list_whatsapp_workflows, copiar el array de actions completo preservando TODOS los valores originales (especialmente delay seconds), y enviar el array modificado. Si solo cambias name, conditions o status, NO envies 'actions' — se preservan automaticamente.
      type: object
      properties:
        id:
          type: integer
          description: "ID numerico del workflow a editar. OBLIGATORIO siempre. Obtenerlo de list_whatsapp_workflows. Sin este parametro la peticion se trata como creacion y fallara si falta el nombre."
        name:
          type: string
          description: "Nombre del workflow (max 100 caracteres). Si no se envia, se mantiene el nombre actual"
        trigger_type:
          type: string
          description: "Tipo de trigger: 'message.received' o 'message.sent'. Si no se envia, se mantiene el valor actual"
          enum: ["message.received", "message.sent"]
          default: "message.received"
        conditions:
          type: object
          description: "Objeto con 'logic' (AND/OR) y 'rules' (array de condiciones). Si no se envia, se mantienen las condiciones actuales"
        actions:
          type: array
          description: "Array de acciones a ejecutar. Si no se envia, se mantienen las acciones actuales. IMPORTANTE: si envias este campo, debes enviar el array COMPLETO de acciones (no solo la que cambias). Para editar solo el mensaje de una accion reply/reply_with_ai: 1) llama list_whatsapp_workflows para obtener las acciones actuales, 2) modifica solo el campo que necesitas, 3) envia el array completo con todos los valores existentes preservados. Tipos soportados: reply_with_ai (con pre_send_check opcional), reply (con no_repeat opcional), delay (seconds: 1-300, OBLIGATORIO), ai_filter (filtro IA que decide si responder, previene bucles, ideal como primera accion), ai_archive_decision (decide si archivar; archive_policy:'always' o 'preserve_if_previously_archived'). Para ai_filter y ai_archive_decision se puede añadir prompt:'instrucciones' para personalizar criterios. En ai_archive_decision, archiva cuando no queda tarea humana aunque el siguiente paso sea del cliente. archive_policy define que hacer si la IA decide ARCHIVAR: 'always' archiva el chat; 'preserve_if_previously_archived' archiva solo si el chat no estaba activo antes del mensaje. VALIDACION: cada accion delay DEBE tener 'seconds' entre 1 y 300. Si copias un delay existente, manten su valor original de seconds."
        session_id:
          type: integer
          description: "ID de la sesion de WhatsApp a la que asignar este workflow. null = todos los numeros. Usa get_whatsapp_status para ver las sesiones."
        status:
          type: string
          description: "Estado del workflow: 'enabled' para activar, 'disabled' para desactivar"
          enum: ["enabled", "disabled"]
      required: ["id"]

    UploadDocqaFileArgs:
      description: |
        **upload_docqa_file** [plugins] (mutation)
        Sube un documento a un asistente Doc-QA para que pueda responder preguntas sobre su contenido
      type: object
      properties:
        assistant_id:
          type: integer
          description: "ID del asistente Doc-QA"
        file:
          type: string
          description: "Archivo a subir (multipart/form-data)"
      required: ["assistant_id", "file"]

    UploadEmailAttachmentArgs:
      description: |
        **upload_email_attachment** [email] (mutation)
        Sube un archivo para adjuntarlo a un email
      type: object
      properties:
        action:
          type: string
          description: "Accion fija"
        file_data:
          type: string
          description: "Contenido del archivo en base64"
        file_name:
          type: string
          description: "Nombre del archivo"
        file_mime:
          type: string
          description: "Tipo MIME del archivo"
        file_size:
          type: integer
          description: "Tamano del archivo en bytes"
      required: ["action", "file_data", "file_name", "file_mime", "file_size"]

    VerifyEcommerceWritePermissionArgs:
      description: |
        **verify_ecommerce_write_permission** [integrations] (query)
        Verifica si la conexion con la plataforma e-commerce tiene permisos de escritura para sincronizar FAQs. Requiere plataforma conectada Y plugin Product Q&A configurado.
      type: object
