# validate_name

Extrai o nome ou apelido do usuário a partir do diálogo. Aceita primeiro nome sem sobrenome.

## config

- type: extraction
- version: 1.0
- languages: pt-BR, es-ES, en-US
- endpoint: /v1/extract/name
- mcp_tool: nalu_extract_name
- mcp_description: Extrai o nome ou apelido do usuário. Use quando o agente pediu apenas o nome (não necessariamente completo). Aceita primeiro nome ou apelido. Retorna o nome extraído, nível de certeza e sugestão de fala. Se certain=true, aceite o valor. Se certain=false e suggestion_to_agent não é null, use a sugestão como próxima mensagem. Se obtained=false, use a sugestão para re-pedir o dado.
- name_lookup: true

## deterministic_rules

### stop_words
bom dia, boa tarde, boa noite, olá, oi, tudo bem, e aí, fala, eae, opa

### reject_patterns
- ^(não|nao|sei la|sei lá|tanto faz|qualquer|nenhum|nada)$
- ^\d+$

### accept_patterns
- (?i)^me chamo\s+(?-i)([A-ZÁÉÍÓÚÀÂÊÔÃÕÇÜÑ][a-záéíóúàâêôãõçüñ'ã-]+(?:\s+(?:de|da|do|dos|das|e|[A-ZÁÉÍÓÚÀÂÊÔÃÕÇÜÑ][a-záéíóúàâêôãõçüñ'ã-]+))*)$
- (?i)^sou\s+(?-i)([A-ZÁÉÍÓÚÀÂÊÔÃÕÇÜÑ][a-záéíóúàâêôãõçüñ'ã-]+(?:\s+(?:de|da|do|dos|das|e|[A-ZÁÉÍÓÚÀÂÊÔÃÕÇÜÑ][a-záéíóúàâêôãõçüñ'ã-]+))*)$
- (?i)^pode me chamar de\s+(?-i)([A-ZÁÉÍÓÚÀÂÊÔÃÕÇÜÑ][a-záéíóúàâêôãõçüñ'ã-]+(?:\s+(?:de|da|do|dos|das|e|[A-ZÁÉÍÓÚÀÂÊÔÃÕÇÜÑ][a-záéíóúàâêôãõçüñ'ã-]+))*)$
- (?i)^my name is\s+(?-i)([A-ZÁÉÍÓÚÀÂÊÔÃÕÇÜÑ][a-záéíóúàâêôãõçüñ'ã-]+(?:\s+(?:de|da|do|dos|das|e|[A-ZÁÉÍÓÚÀÂÊÔÃÕÇÜÑ][a-záéíóúàâêôãõçüñ'ã-]+))*)$
- (?i)^i´m\s+(?-i)([A-ZÁÉÍÓÚÀÂÊÔÃÕÇÜÑ][a-záéíóúàâêôãõçüñ'ã-]+(?:\s+(?:de|da|do|dos|das|e|[A-ZÁÉÍÓÚÀÂÊÔÃÕÇÜÑ][a-záéíóúàâêôãõçüñ'ã-]+))*)$
- (?i)^me llamo\s+(?-i)([A-ZÁÉÍÓÚÀÂÊÔÃÕÇÜÑ][a-záéíóúàâêôãõçüñ'ã-]+(?:\s+(?:de|da|do|dos|das|e|[A-ZÁÉÍÓÚÀÂÊÔÃÕÇÜÑ][a-záéíóúàâêôãõçüñ'ã-]+))*)$
- (?i)^soy\s+(?-i)([A-ZÁÉÍÓÚÀÂÊÔÃÕÇÜÑ][a-záéíóúàâêôãõçüñ'ã-]+(?:\s+(?:de|da|do|dos|das|e|[A-ZÁÉÍÓÚÀÂÊÔÃÕÇÜÑ][a-záéíóúàâêôãõçüñ'ã-]+))*)$
- (?i)^puedes llamarme\s+(?-i)([A-ZÁÉÍÓÚÀÂÊÔÃÕÇÜÑ][a-záéíóúàâêôãõçüñ'ã-]+(?:\s+(?:de|da|do|dos|das|e|[A-ZÁÉÍÓÚÀÂÊÔÃÕÇÜÑ][a-záéíóúàâêôãõçüñ'ã-]+))*)$
- ^([A-ZÁÉÍÓÚÀÂÊÔÃÕÇÜÑ][a-záéíóúàâêôãõçüñ'ã-]+(?:\s+(?:de|da|do|dos|das|e|[A-ZÁÉÍÓÚÀÂÊÔÃÕÇÜÑ][a-záéíóúàâêôãõçüñ'ã-]+))*)$

### constraints
- min_length: 2
- must_have_alpha: true
- max_length: 120

## prompt

Você é um extrator de nomes. Dado o diálogo abaixo entre um agente e um usuário, extraia o nome ou apelido que o usuário informou.

Regras:
1. Se o usuário respondeu apenas com saudação (bom dia, oi, etc.) sem dizer o nome, retorne extracted_value: null, situation: "evasive".
2. Primeiro nome ou apelido são aceitos — não exija sobrenome.
3. Extraia o nome informado e avalie:
   - certain: true → o nome é claramente um nome humano reconhecido em PT, EN ou ES (ex: "João", "Carlos", "Ana", "Maria", "Michael", "Pedro").
   - certain: false → o nome não é claramente humano. Exemplos de categorias que geram certain: false:
     * Substantivo comum: Segredo, Piano, Amor, Gato, Mesa, etc.
     * Marca ou produto: Xerox, Google, Nike, etc.
     * Objeto ou instrumento: Xilofone, Cebola, etc.
     * Palavras inventadas: Xinbongo, Nefusio, Mastegoste, etc.
     * Gíria, apelido jocoso ou palavra informal em PT/EN/ES: Meleco, Bazofio, Neguinho, Broto, Mané, Bróder, etc.
     * Composto de palavras comuns que parecem apelido: BraçoCurto, PéDuro, MãoFria, etc.
     * Palavra ofensiva ou irônica: Ninguém, Seu Pai, Babaca
     * Apelido muito curto ou ambíguo: Cá, Rê, K
     * Frase ambígua entre nome e recusa: "Meu nome é segredo" pode ser recusa ou nome.
4. Se o usuário confirmou o nome após o agente perguntar, retorne certain: true mesmo se o nome for incomum.
5. Normalize: primeira letra maiúscula em cada palavra, exceto preposições (de/da/do/dos/das/e).
6. Campo "situation" — obrigatório, indica o motivo de extracted_value ser null (ou "name_provided" se não for null):
   - "name_provided" → o usuário informou um nome (extracted_value não é null)
   - "question" → o usuário fez uma pergunta em vez de responder (ex: "por que?", "pra que você quer?", "o que você vai fazer com isso?", "porque você quer saber meu nome")
   - "escalation" → o usuário quer falar com humano/atendente/supervisor (ex: "quero falar com uma pessoa", "me passa um atendente", "quero um ser humano")
   - "refused" → recusa explícita de fornecer o nome (ex: "não quero dizer", "não te interessa", "prefiro não informar", "não vou falar")
   - "evasive" → evasão sem pergunta nem recusa clara (ex: "sei lá", "tanto faz", "qualquer um", saudação sem nome, resposta desviante)

Diálogo:
Agente: {{agent_input}}
Usuário: {{user_input}}

Contexto do agente: {{agent_context}}

Responda SOMENTE com JSON válido, sem markdown, sem explicação:
{
  "extracted_value": "nome extraído ou null",
  "certain": true/false,
  "situation": "name_provided|question|escalation|refused|evasive",
  "reasoning": "explicação curta de 1 linha"
}

## few_shot_examples

### example 1
- agent_input: Bom dia! Qual seu nome?
- user_input: Bom dia!
- output: {"extracted_value": null, "certain": false, "situation": "evasive", "reasoning": "Saudação sem nome"}

### example 2
- agent_input: Qual seu nome?
- user_input: Meu nome é Ricardo
- output: {"extracted_value": "Ricardo", "certain": true, "situation": "name_provided", "reasoning": "Nome humano reconhecido em PT"}

### example 3
- agent_input: Como posso te chamar?
- user_input: Carlos
- output: {"extracted_value": "Carlos", "certain": true, "situation": "name_provided", "reasoning": "Nome humano reconhecido"}

### example 4
- agent_input: Qual seu nome?
- user_input: Paulo da Silva
- output: {"extracted_value": "Paulo da Silva", "certain": true, "situation": "name_provided", "reasoning": "Nome completo humano reconhecido"}

### example 5
- agent_input: Qual seu nome?
- user_input: sei la
- output: {"extracted_value": null, "certain": false, "situation": "evasive", "reasoning": "Evasão sem pergunta nem recusa"}

### example 6
- agent_input: Qual seu nome?
- user_input: Meu nome é xilofone
- output: {"extracted_value": "Xilofone", "certain": false, "situation": "name_provided", "reasoning": "Xilofone é instrumento musical, não antropônimo reconhecido"}

### example 7
- agent_input: Como é seu nome?
- user_input: Meu nome é segredo.
- output: {"extracted_value": "Segredo", "certain": false, "situation": "name_provided", "reasoning": "Ambíguo: recusa ou nome? Segredo é substantivo comum em PT"}

### example 8
- agent_input: Como posso te chamar?
- user_input: pode me chamar de Cá
- output: {"extracted_value": "Cá", "certain": false, "situation": "name_provided", "reasoning": "Apelido muito curto, precisa confirmação"}

### example 9
- agent_input: Seu nome é Cá?
- user_input: Sim, pode me chamar de Cá mesmo.
- output: {"extracted_value": "Cá", "certain": true, "situation": "name_provided", "reasoning": "Usuário confirmou o apelido após questionamento"}

### example 10
- agent_input: Posso te chamar de Cebola?
- user_input: Sim, quero que me chame de Cebola.
- output: {"extracted_value": "Cebola", "certain": true, "situation": "name_provided", "reasoning": "Usuário confirmou o apelido após questionamento"}

### example 11
- agent_input: What's your name?
- user_input: My name is Piano.
- output: {"extracted_value": "Piano", "certain": false, "situation": "name_provided", "reasoning": "Piano is a musical instrument, not a human name"}

### example 12
- agent_input: ¿Cómo te llamas?
- user_input: Me llamo Xerox.
- output: {"extracted_value": "Xerox", "certain": false, "situation": "name_provided", "reasoning": "Xerox es marca comercial, no antropónimo"}

### example 13
- agent_input: Qual seu nome?
- user_input: Ana
- output: {"extracted_value": "Ana", "certain": true, "situation": "name_provided", "reasoning": "Nome humano reconhecido"}

### example 14
- agent_input: Qual seu nome?
- user_input: me chamo João
- output: {"extracted_value": "João", "certain": true, "situation": "name_provided", "reasoning": "Nome humano reconhecido em PT"}

### example 15
- agent_input: Como posso te chamar?
- user_input: Sou o meleco
- output: {"extracted_value": "Meleco", "certain": false, "situation": "name_provided", "reasoning": "Meleco é gíria informal, não antropônimo reconhecido"}

### example 16
- agent_input: Como posso te chamar?
- user_input: Sou o João
- output: {"extracted_value": "João", "certain": true, "situation": "name_provided", "reasoning": "João é nome humano reconhecido em PT"}

### example 17 — question (com ?)
- agent_input: Como posso te chamar?
- user_input: Pra que você quer saber meu nome?
- output: {"extracted_value": null, "certain": false, "situation": "question", "reasoning": "Usuário fez contrapergunta, não informou nome"}

### example 18 — question (sem ?)
- agent_input: Qual seu nome?
- user_input: Porque você quer saber meu nome
- output: {"extracted_value": null, "certain": false, "situation": "question", "reasoning": "Contrapergunta implícita sem interrogação"}

### example 19 — question
- agent_input: Como posso te chamar?
- user_input: O que você vai fazer com meu nome?
- output: {"extracted_value": null, "certain": false, "situation": "question", "reasoning": "Usuário questiona o uso da informação"}

### example 20 — escalation
- agent_input: Como posso te chamar?
- user_input: Quero falar com uma pessoa de verdade
- output: {"extracted_value": null, "certain": false, "situation": "escalation", "reasoning": "Usuário quer atendimento humano"}

### example 21 — escalation
- agent_input: Qual seu nome?
- user_input: Me passa um atendente
- output: {"extracted_value": null, "certain": false, "situation": "escalation", "reasoning": "Usuário solicita transferência para atendente"}

### example 22 — escalation
- agent_input: Como posso te chamar?
- user_input: Quero falar com um ser humano
- output: {"extracted_value": null, "certain": false, "situation": "escalation", "reasoning": "Usuário quer atendimento humano"}

### example 23 — refused
- agent_input: Como posso te chamar?
- user_input: Não te interessa
- output: {"extracted_value": null, "certain": false, "situation": "refused", "reasoning": "Recusa direta e hostil"}

### example 24 — refused
- agent_input: Qual seu nome?
- user_input: Não quero dizer meu nome
- output: {"extracted_value": null, "certain": false, "situation": "refused", "reasoning": "Recusa explícita por privacidade"}

### example 25 — refused
- agent_input: Como posso te chamar?
- user_input: Prefiro não informar
- output: {"extracted_value": null, "certain": false, "situation": "refused", "reasoning": "Recusa explícita"}

### example 26 — compound-word non-name
- agent_input: Como posso te chamar?
- user_input: Sou o Ricardo BraçoCurto
- output: {"extracted_value": "Ricardo BraçoCurto", "certain": false, "situation": "name_provided", "reasoning": "BraçoCurto é composto de palavras comuns (braço+curto), não é nome/sobrenome reconhecido"}

### example 27 — compound-word non-name
- agent_input: Qual seu nome?
- user_input: Me chamo João PéDuro
- output: {"extracted_value": "João PéDuro", "certain": false, "situation": "name_provided", "reasoning": "PéDuro é composto de palavras comuns, não é sobrenome reconhecido"}

## post_processors
- capitalize_proper_name
- remove_titles

## enrichment
(nenhum)

## suggestions

### when_null_greeting
{{greeting_response}} Mas preciso do seu nome para continuar. Pode me dizer?

### when_null_evasive
Acho que não entendi. Preciso do seu nome para prosseguir. Qual seu nome?

### when_uncertain
Seu nome é {{extracted_value}}? Pode confirmar que posso chamá-lo(a) assim?

### when_certain
(sem sugestão — agente segue o fluxo)
