Filtragem e seleção de slots¶
Dado o bruto do OTIMUS (dias com listas enormes de horários), reduzir para algo que caiba em uma mensagem WhatsApp sem poluir a conversa.
Parâmetros de configuração¶
Ambos os projetos usam os mesmos limites (hardcoded):
| Parâmetro | Valor | Descrição |
|---|---|---|
| Dias no futuro | 5 dias | Primeiros dias com disponibilidade |
| Slots manhã/dia | 2 | Horários < 12:00 |
| Slots tarde/dia | 2 | Horários >= 12:00 |
| Descarte passado | Sempre | Dias < hoje e horas <= agora |
Implementação de referência¶
# agendamento.py:502-550 (CLINFETO)
from datetime import date, datetime
def _filter_and_select_slots(data_items: list) -> list[dict]:
"""Filtra slots do OTIMUS e devolve uma lista enxuta para o agente.
Regras:
- Descarta dias < hoje (America/Sao_Paulo).
- Se dia == hoje, descarta horas <= agora.
- Agrupa por dia, depois por período (manhã < 12h, tarde >= 12h).
- Seleciona os 5 primeiros dias com disponibilidade.
- Pega 2 slots manhã + 2 tarde por dia.
"""
hoje = _today_br()
agora = _now_br().replace(tzinfo=None)
slots_by_day: dict[date, dict] = {}
for item in data_items:
item_date = _parse_date_ddmmyyyy(item.get("data", ""))
if item_date is None or item_date < hoje:
continue
for agenda in item.get("agendas", []):
for horario in agenda.get("horarios", []):
hora5 = (horario.get("hora", "") or "").strip()[:5]
try:
hora_h, hora_m = int(hora5.split(":")[0]), int(hora5.split(":")[1])
except ValueError:
continue
# Se for hoje, descartar horas que já passaram
if item_date == hoje:
h_dt = datetime(item_date.year, item_date.month, item_date.day, hora_h, hora_m)
if h_dt <= agora:
continue
if item_date not in slots_by_day:
slots_by_day[item_date] = {"manha": [], "tarde": []}
entry = {
"data": item.get("data"), # DD-MM-YYYY
"hora": hora5, # HH:MM
"dataconsulta": horario.get("dataconsulta", ""),
}
if hora_h < 12:
slots_by_day[item_date]["manha"].append(entry)
else:
slots_by_day[item_date]["tarde"].append(entry)
selected: list[dict] = []
for day in sorted(slots_by_day.keys())[:5]:
day_slots = slots_by_day[day]
selected.extend(day_slots["manha"][:2])
selected.extend(day_slots["tarde"][:2])
return selected
Por que 2 manhã + 2 tarde¶
Dois motivos:
- Legibilidade no WhatsApp — mensagens com 20 horários viram spam.
- Taxa de conversão — paciente escolhe mais rápido com menos opções.
Se a clínica pedir mais opções, aumente mas sem passar de ~6 por dia.
Por que 5 dias¶
Suficiente para o paciente ver "hoje, amanhã, próxima semana" sem scroll
excessivo. Se todos os 5 dias vierem cheios, o paciente pode pedir datas
mais à frente e o agente re-chama a tool com data_interesse.
Ordem dos slots¶
Dentro do dia: manhã primeiro, tarde depois. Mantenha a ordem
cronológica interna (ex: 08:00, 08:30 antes de 14:00, 14:30).
Formato final entregue ao agente¶
Recomendação: JSON list com 3 campos.
[
{"data": "15-04-2026", "hora": "08:00", "dataconsulta": "2026-04-15 08:00:00"},
{"data": "15-04-2026", "hora": "08:30", "dataconsulta": "2026-04-15 08:30:00"},
{"data": "15-04-2026", "hora": "14:00", "dataconsulta": "2026-04-15 14:00:00"},
{"data": "15-04-2026", "hora": "14:30", "dataconsulta": "2026-04-15 14:30:00"},
{"data": "16-04-2026", "hora": "08:00", "dataconsulta": "2026-04-16 08:00:00"}
]
O agente então formata em PT-BR para o paciente:
Temos disponibilidade:
Quarta, 15 de abril
- 08:00 | 08:30 | 14:00 | 14:30
Quinta, 16 de abril
- 08:00
E se só veio 1 dia com disponibilidade?¶
Devolve mesmo assim. O agente diz ao paciente a realidade e pergunta se quer horário em dia mais à frente.
E se não veio nada?¶
Retorna string FALHA_CONSULTA: agenda sem horarios disponiveis. Agente
transfere.