"""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