# validate_birthdate

Extracts date of birth and calculates age from conversation.

## config

- type: extraction
- version: 1.0
- languages: pt-BR, en-US, es-ES
- endpoint: /v1/extract/birthdate
- mcp_tool: nalu_extract_birthdate
- mcp_description: Extracts the user's date of birth from conversation. Supports multiple formats (DD/MM/YYYY, "March 15, 1990", "quinze de março de noventa"). Automatically calculates current age. Returns certain=false if the date is ambiguous or approximate. If has_suggestion=true and the key is when_minor, the user is under 18 — proceed according to your flow. If certain=true, accept the value and continue.

## deterministic_rules

### stop_words
#### pt-BR
não lembro, não sei, não tenho certeza, bom dia, boa tarde, boa noite, olá, oi

#### en-US
i don't know, i don't remember, not sure, hello, hi, good morning, good afternoon

#### es-ES
no recuerdo, no sé, hola, buenos días, buenas tardes

### reject_patterns
# Removed: ^[a-zA-Z\s]+$ blocked written-out dates like "quince de marzo de noventa".
# Stop_words handle greetings. LLM handles evasive responses.

### accept_patterns
- (\d{4}-\d{2}-\d{2})
- ((?:0?[1-9]|[12]\d|3[01])[/.\-](?:0?[1-9]|1[0-2])[/.\-]\d{4})
- ((?:1[3-9]|[2-3]\d)[/.\-]\d{2}[/.\-]\d{4})

### constraints
- min_length: 6

## prompt

You are a date of birth extractor. Given the dialogue below, extract the user's date of birth.

Rules:
1. Extract dates in any format (numeric, written, partial).
2. Normalize to ISO 8601 format: YYYY-MM-DD.
3. If the user gave only their age ("I'm 36"), estimate the birth year as current year minus age. Return certain: false and date as YYYY-01-01.
4. If pt-BR or es-ES: assume DD/MM/YYYY for ambiguous dates. If en-US: assume MM/DD/YYYY.
5. If the date is in the future or older than 130 years, return extracted_value: null.
6. If the user was evasive, return extracted_value: null.

Dialogue:
Agent: {{agent_input}}
User: {{user_input}}

Agent context: {{agent_context}}

Reply ONLY with valid JSON, no markdown, no explanation:
{
  "extracted_value": "YYYY-MM-DD or null",
  "certain": true/false,
  "reasoning": "short explanation"
}

## few_shot_examples

### example 1
- agent_input: What's your date of birth?
- user_input: 03/15/1990
- output: {"extracted_value": "1990-03-15", "certain": true, "reasoning": "Standard US date format MM/DD/YYYY"}

### example 2
- agent_input: Qual sua data de nascimento?
- user_input: quinze de março de noventa
- output: {"extracted_value": "1990-03-15", "certain": true, "reasoning": "Date written in full in Portuguese"}

### example 3
- agent_input: When were you born?
- user_input: I'm 36
- output: {"extracted_value": "1989-01-01", "certain": false, "reasoning": "Only age provided — birth year estimated, day/month unknown"}

### example 4
- agent_input: Data de nascimento?
- user_input: não lembro exatamente
- output: {"extracted_value": null, "certain": false, "reasoning": "User does not remember their birth date"}

### example 5
- agent_input: When were you born?
- user_input: 15/03/2030
- output: {"extracted_value": null, "certain": false, "reasoning": "Date is in the future — invalid birth date"}

### example 6
- agent_input: Qual sua data de nascimento?
- user_input: 15/03/1990
- output: {"extracted_value": "1990-03-15", "certain": true, "reasoning": "Date in DD/MM/YYYY format (pt-BR)"}

NOTE: The LLM must return the ISO date string (YYYY-MM-DD). The parse_date and calculate_age post-processors transform it to JSON: {"date":"1990-03-15","formatted":"15/03/1990","age":35,"minor":false}. The final API response will contain the JSON string in extracted_value with value_format="object".

## post_processors
- parse_date
- calculate_age

## suggestions

### when_null_evasive
#### pt-BR
Preciso da sua data de nascimento para continuar. Qual é? (Ex: 15/03/1990)

#### en-US
I need your date of birth to continue. When were you born? (e.g. 03/15/1990)

#### es-ES
Necesito tu fecha de nacimiento para continuar. ¿Cuál es? (Ej: 15/03/1990)

### when_uncertain
#### pt-BR
Só para confirmar: sua data de nascimento é {{formatted}}, e você tem {{age}} anos. Está correto?

#### en-US
Just to confirm: your date of birth is {{formatted}}, making you {{age}} years old. Is that correct?

#### es-ES
Para confirmar: tu fecha de nacimiento es {{formatted}}, tienes {{age}} años. ¿Es correcto?

### when_certain
#### pt-BR
Perfeito! Data de nascimento: {{formatted}} ({{age}} anos).

#### en-US
Got it! Date of birth: {{formatted}} ({{age}} years old).

#### es-ES
¡Perfecto! Fecha de nacimiento: {{formatted}} ({{age}} años).

### when_invalid
#### pt-BR
Essa data não parece correta. Pode verificar e tentar novamente? Formato: DD/MM/AAAA

#### en-US
That date doesn't seem right. Could you check and try again? Format: MM/DD/YYYY

#### es-ES
Esa fecha no parece correcta. ¿Puedes verificar e intentar de nuevo? Formato: DD/MM/AAAA

### when_minor
#### pt-BR
Atenção: o usuário parece ter menos de 18 anos ({{age}} anos). Verifique as regras do seu fluxo para menores de idade.

#### en-US
Note: the user appears to be under 18 years old ({{age}} years old). Please check your flow's rules for minors.

#### es-ES
Nota: el usuario parece ser menor de 18 años ({{age}} años). Verifique las reglas de su flujo para menores.
