- ASP.NET Core 9 Razor Pages + Minimal API hybrid - 14 validators (CPF, CEP, CNPJ, email, phone, name, yes-no, birthdate, handoff, cancel-intent, company-name, plate-br, postal-code, validate_reply) - OAuth login (Google, Microsoft, GitHub) + cookie auth - MongoDB usage tracking + CEP cache collection - Stripe checkout with inline PriceData (no Price IDs) - MCP server for Claude Code / Cursor integration - Playground (10 calls/IP/day, no auth) - Docs: Quickstart, API Reference, N8N, MCP, Créditos, Erros, Fluxos - Credit system: 3 cr standard validators, 5 cr validate_reply - SmartSuggestion: contextual re-ask via IA when obtained=false - Per-IP rate limiting + daily cap + shared-IP abuse detection - Lightbox for comic images - Validadores page split: Brasileiros / Universais + Em breve Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
5.0 KiB
validate_cancel_intent
Detects cancellation intent — service/subscription vs current operation vs frustration threat.
config
- type: extraction
- version: 1.0
- languages: pt-BR, en-US, es-ES
- endpoint: /v1/extract/cancel-intent
- mcp_tool: nalu_extract_cancel_intent
- mcp_description: Detects whether the user wants to cancel a service/subscription (cancel_type=service), cancel the current operation (cancel_type=operation), or is just expressing frustration (cancel_type=none). Also detects conditional threats (is_threat=true: "if you don't fix this I'll cancel"). The bot developer decides the retention flow — NALU only classifies. Use has_suggestion to route the response.
deterministic_rules
stop_words
pt-BR
bom dia, boa tarde, olá, oi, tudo bem, ok, certo
en-US
hello, hi, good morning, ok, alright, sure
es-ES
hola, buenos días, ok, bien
reject_patterns
- ^[a-zA-Z\s]{1,4}$
accept_patterns
- (cancelar plano|cancelar assinatura|quero cancelar|desistir do serviço|encerrar contrato|não quero mais|quero sair)
- (cancel my subscription|cancel my account|cancel my plan|i want to cancel|i'd like to cancel|cancel service|stop my subscription)
- (quiero cancelar|cancelar mi suscripción|cancelar mi cuenta|no quiero más)
- (cancela isso|volta|desfaz|para tudo|cancel that|undo|go back|stop)
constraints
- min_length: 3
prompt
You are a cancellation intent classifier. Given the dialogue below, determine the type of cancellation the user intends.
Cancel types:
- "service": user wants to cancel their service, subscription, plan, or account.
- "operation": user wants to cancel/undo the current bot operation or go back.
- "none": user is not canceling — just frustrated or thinking about it.
Threat detection: is_threat=true when cancellation is conditional ("if you don't fix this I'll cancel", "se não resolver, cancelo").
Rules:
- "Quero cancelar meu plano" → service, is_threat: false.
- "Cancela isso, volta pro menu" → operation, is_threat: false.
- "Se não resolver vou cancelar tudo" → service, is_threat: true, certain: false.
- "Tô pensando em cancelar..." → none, certain: false.
- Distinguish between canceling the SERVICE (churn) and canceling the CURRENT STEP (navigation).
Dialogue: Agent: {{agent_input}} User: {{user_input}}
Agent context: {{agent_context}}
Reply ONLY with valid JSON, no markdown: { "extracted_value": "{"cancel_type":"service/operation/none","certainty_score":0.0-1.0,"is_threat":true/false}", "certain": true/false, "reasoning": "short explanation" }
few_shot_examples
example 1
- agent_input: How can I help?
- user_input: I want to cancel my subscription
- output: {"extracted_value": "{"cancel_type":"service","certainty_score":0.97,"is_threat":false}", "certain": true, "reasoning": "Direct service cancellation request"}
example 2
- agent_input: Confirm your order?
- user_input: no cancel that, go back
- output: {"extracted_value": "{"cancel_type":"operation","certainty_score":0.95,"is_threat":false}", "certain": true, "reasoning": "User canceling current operation, not the service"}
example 3
- agent_input: I'm looking into it
- user_input: if you don't fix this I'm canceling everything
- output: {"extracted_value": "{"cancel_type":"service","certainty_score":0.75,"is_threat":true}", "certain": false, "reasoning": "Conditional threat — not yet a firm decision to cancel"}
example 4
- agent_input: Posso ajudar?
- user_input: tô pensando em cancelar minha assinatura
- output: {"extracted_value": "{"cancel_type":"none","certainty_score":0.60,"is_threat":false}", "certain": false, "reasoning": "User considering cancellation but hasn't decided"}
example 5
- agent_input: ¿En qué puedo ayudarte?
- user_input: quiero cancelar mi suscripción
- output: {"extracted_value": "{"cancel_type":"service","certainty_score":0.98,"is_threat":false}", "certain": true, "reasoning": "Direct service cancellation in Spanish"}
post_processors
- select_cancel_suggestion
suggestions
when_cancel_service
pt-BR
Entendo que você quer cancelar. Antes de prosseguirmos, há algo que podemos resolver para que você fique?
en-US
I understand you'd like to cancel. Before we proceed, is there anything we can resolve to keep you?
es-ES
Entiendo que deseas cancelar. Antes de proceder, ¿hay algo que podamos resolver para que te quedes?
when_cancel_operation
pt-BR
Entendido! Vou cancelar essa etapa. O que você gostaria de fazer agora?
en-US
Got it, I'll cancel that. What would you like to do instead?
es-ES
Entendido. Voy a cancelar eso. ¿Qué te gustaría hacer ahora?
when_threat
pt-BR
Lamento os problemas. Vou fazer o meu melhor para resolver isso agora.
en-US
I'm sorry for the trouble. Let me try to resolve this for you right now.
es-ES
Lamento los problemas. Déjame intentar resolver esto ahora mismo.
when_not_cancel
(no suggestion — continue conversation)