feat(vida): página "Dia a dia" com as decisões e o porquê

Cada decisão tomada com base no que ele aprendeu passa a ser guardada
com o motivo (aprendizado.decidir, até 800, persistidas):
- acordou do cochilo antes da hora: "às 18h de quarta costuma ter
  gente, pelo plano que você contou";
- cochilo com a casa vazia, com a duração e o porquê;
- sensor segurado numa hora em que acordou à toa (no máximo 1 nota a
  cada 10 min);
- gesto escolhido porque costuma agradar (chance ≥ ×1,3);
- fechamento do dia: horas com gente, carinhos e quanto o dia conferiu
  com o plano;
- análise da IA (adotada ou sugestão, com a porcentagem) e rotina
  contada por você.

esperado_e_fonte diz de onde veio a expectativa (plano seu, plano da
IA, o que viu naquele dia da semana ou média). GET /aprendizado/dia
devolve um dia: medido × plano por hora, conferência do dia, resumo e
decisões.

Painel: tela "Dia a dia" (#/dia-a-dia) com navegação entre dias, os
números do dia, as faixas "Viu" × "Esperava" e a linha do tempo das
decisões; atalho no cartão "O que ele aprendeu", no Ctrl+K e no guia.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
julio
2026-10-09 17:34:30 -03:00
co-authored by Claude Opus 5.5
parent 935bf8d586
commit b4cf13df11
10 changed files with 553 additions and 13 deletions
+11 -3
View File
@@ -401,8 +401,10 @@ class Vida:
agora = agora or time.time()
self.pir_eventos = [t for t in self.pir_eventos if agora - t < 120] + [agora]
precisa = PIR_ACORDAR[self.config['ritmo']] if self.config['ligado'] else 1
if self.aprendizado and self.config['ligado']:
precisa += self.aprendizado.extra_pir(agora) # nesta hora já acordou à toa outras vezes
extra = self.aprendizado.extra_pir(agora) if self.aprendizado and self.config['ligado'] else 0
if extra and precisa <= len(self.pir_eventos) < precisa + extra:
self.aprendizado.segurou_sono(agora, precisa, extra)
precisa += extra # nesta hora já acordou à toa outras vezes
if len(self.pir_eventos) >= precisa:
self.pir_eventos = []
if self.aprendizado and self.config['ligado']:
@@ -493,6 +495,7 @@ class Vida:
if (self.aprendizado and not self.sono_profundo and not self.madrugada(agora) and n['energia'] >= 50
and self.aprendizado.chega_logo(agora)):
self.acordar(agora, 'Acordou: daqui a pouco costuma chegar alguém')
self.aprendizado.decidir('acordar', 'Acordou do cochilo antes da hora', self.aprendizado.porque_chegada(agora), agora)
return 'acordar'
return None
if self.config['noite'] and self.madrugada(agora) and agora - self.interagiu_em > PEDIU_ATENCAO:
@@ -519,7 +522,10 @@ class Vida:
# nesta hora a casa costuma ficar vazia: um cochilo longo guarda pique para quando chegarem
if (dia and folga and sozinho and self.aprendizado and n['energia'] < 85
and self.aprendizado.casa_vazia(agora) and self.rng.random() < 0.3):
return self.comecar_atividade(agora, 'dormir', self.rng.uniform(600, 1200))
segundos = self.rng.uniform(600, 1200)
self.aprendizado.decidir('cochilo', 'Tirou um cochilo de %d min para guardar energia' % round(segundos / 60),
self.aprendizado.porque_vazia(agora), agora)
return self.comecar_atividade(agora, 'dormir', segundos)
# alguém por perto e ele aprendeu algo hoje: "Olha o que eu aprendi hoje!"
if dia and perto and humor != 'bravo':
item = self.aprendi_pendente()
@@ -547,6 +553,8 @@ class Vida:
if sozinho: # sem plateia: nada de acenar ou ficar tímido
lista = [a for a in lista if a[0] not in PARA_ALGUEM] or ATOS['tranquilo'][:3]
gesto, texto = self.escolher(lista)
if self.aprendizado and perto:
self.aprendizado.escolheu(gesto, agora)
self.enfileirar(gesto)
if humor == 'entediado':
with self.lock: