feat(vida): jeito de gente e console com o porquê de cada decisão
Console (console.py + tela Console no painel):
- cada parte registra o que fez e o motivo: modo vida (com necessidades
e humor), sentidos, celular (ordens e o que o rosto fez), IA local,
aprendizado e ideias do dia; últimas 400 linhas, ao vivo pelo SSE;
- tela com o "agora" (humor, necessidades, o que está fazendo, próxima
decisão, última decisão, jeito), filtros, detalhes, pausa e busca.
Jeito de gente:
- saudade: a festa cresce com o tempo fora (aceno, "Oi! Você voltou!",
"Senti sua falta!"); bom dia lembrando de ontem;
- pedidos com motivo ("Brinca comigo?", "Me faz um carinho?", mostrar a
figurinha nova), no máximo 1 a cada 20 min;
- larga atividade no meio quando fica chato; personalidade (curiosidade,
brincadeira, timidez) que pesa nos gestos e amadurece com o convívio;
- no rosto: acordar grogue, sonhar com algo do dia (balão no motor),
hesitar antes de gestos, errar na atividade e ficar sem graça, olhar
nos olhos e desviar, sorrir de volta (FaceLandmarker no rastreador do
painel) e reagir à luz (sensor de luz no app 0.10.0);
- ordem "dizer" com legenda e voz de robô.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+50
@@ -0,0 +1,50 @@
|
||||
"""Console: tudo o que o Carinha está fazendo e por quê, ao vivo.
|
||||
|
||||
Cada parte do servidor registra o que fez e o motivo (modo vida, sentidos, IA local, aprendizado,
|
||||
ideias do dia, celular). As linhas ficam na memória (as últimas MAX_LINHAS) e vão para o painel pelo
|
||||
SSE ('console'). Nível 'detalhe' é o que se repete muito (humor reenviado, disparo solto do sensor):
|
||||
o painel esconde por padrão.
|
||||
"""
|
||||
import json
|
||||
import threading
|
||||
import time
|
||||
from collections import deque
|
||||
|
||||
MAX_LINHAS = 400
|
||||
ORIGENS = ('vida', 'sentidos', 'celular', 'ia', 'aprendizado', 'ideias', 'sistema')
|
||||
|
||||
|
||||
class Console:
|
||||
def __init__(self):
|
||||
self.lock = threading.Lock()
|
||||
self.linhas = deque(maxlen=MAX_LINHAS)
|
||||
self.seq = 0
|
||||
self.publicar = lambda tipo, dados: None
|
||||
|
||||
def registrar(self, origem, texto, motivo='', nivel='info', agora=None):
|
||||
if origem not in ORIGENS:
|
||||
origem = 'sistema'
|
||||
with self.lock:
|
||||
self.seq += 1
|
||||
linha = dict(id=self.seq, horario=agora or time.time(), origem=origem, texto=str(texto)[:240],
|
||||
motivo=str(motivo or '')[:300], nivel='detalhe' if nivel == 'detalhe' else 'info')
|
||||
self.linhas.append(linha)
|
||||
try:
|
||||
self.publicar('console', linha)
|
||||
except Exception:
|
||||
pass
|
||||
return linha
|
||||
|
||||
def status(self, desde=0):
|
||||
with self.lock:
|
||||
return dict(linhas=[l for l in self.linhas if l['id'] > desde], seq=self.seq, origens=list(ORIGENS))
|
||||
|
||||
def rotas(self, h, metodo):
|
||||
rota = h.path.split('?', 1)[0]
|
||||
if rota != '/console':
|
||||
return False
|
||||
if metodo != 'GET':
|
||||
h.enviar(json.dumps(dict(erro='Método inválido')), codigo=400)
|
||||
return True
|
||||
h.enviar(json.dumps(self.status(), ensure_ascii=False))
|
||||
return True
|
||||
Reference in New Issue
Block a user