Todas as janelas minimizadas, ventoinha ainda girando: o Hermes Desktop para de pintar o que ninguém vê


Você aperta enviar e muda para o navegador para pesquisar algo. A janela do Hermes fica em segundo plano, transmitindo a resposta caractere por caractere. Vinte minutos depois você fecha a tampa, desconecta e sai. Ao voltar, a bateria caiu mais do que deveria, e a ventoinha claramente trabalhou enquanto você estava fora.

Uma janela escondida não deveria funcionar assim. Ninguém está olhando para ela, e mesmo assim ela repintava cada caractere na velocidade de primeiro plano.

O comportamento antigo: uma conversa em streaming, todas as janelas acordadas

Na implementação anterior, o estado “uma conversa está em streaming” mantinha toda janela do desktop totalmente acordada: o loop de pintura continuava rodando, e as páginas de preview também ficavam acordadas, para que a captura de automação e de anotação estivesse sempre pronta.

Com uma janela, era invisível. Com várias janelas, turnos longos e a bateria de um notebook, era um custo de fundo constante.

A metade do preview era mais sutil: mesmo uma página completamente ociosa nunca entrava no throttling de segundo plano do Chromium, porque a anotação ou a automação poderia precisar dela a qualquer momento.

Agora: a pintura segue a visibilidade

A pintura do streaming fica limitada a duas janelas: as visíveis e a única janela que tem sua própria conversa de voz ao vivo (essa continua acordada mesmo escondida, porque a voz precisa dela). Todo o resto — incluindo pares minimizados — pode sofrer throttling.

Note o que isso não é: “Ler respostas em voz alta” não compra mais uma isenção de despertar para cada janela. Antes isso implicava que cada janela precisava ficar acordada para falar seu conteúdo; agora os pares minimizados continuam limitados e o progresso concluído mais a resposta final ainda são falados exatamente uma vez.

Ao mesmo tempo, as coisas que não podem depender do desenho foram desacopladas dos frames de animação: entrega de stream, Stop, journaling de turno e recuperação de crash funcionam sem eles. Restaurar uma janela mostra o estado mais recente em vez de reexecutar um acúmulo de pinturas.

Atualizações de texto parcial são agrupadas. Progresso concluído e respostas finais são publicados sem esperar o próximo frame — e é por isso que uma janela escondida ainda consegue ler em voz alta, uma vez. Quando duas janelas têm respostas ao mesmo tempo, elas compartilham a posse do turno pendente, então a narração não se perde nem é falada duas vezes.

Páginas de preview: ocioso significa ocioso

A segunda mudança é sobre o preview embutido: uma página ociosa agora pode usar o throttling de segundo plano do próprio Chromium em vez de segurar um despertar para si.

A página convidada e a janela dona dela só são despertadas para trabalho real, e o despertar é mantido por operação. Operações sobrepostas mantêm cada uma o seu próprio bloqueio, então terminar uma não pode suspender outra. Depois da navegação, o despertar é reaplicado mesmo quando uma operação existente ainda não despachou outro script.

Várias arestas foram fechadas ao mesmo tempo:

  • Trabalho abandonado por uma navegação efetivada é cancelado, enquanto valores de retorno de script, consentimento de plugin, entrada confiável, sandbox e CSP permanecem intactos.
  • A espera da pintura de anotação e a captura de imagem compartilham um único prazo cancelável de oito segundos. Esperar pela próxima anotação do usuário não mantém nada acordado.
  • Instalações e desmontagens de anotação na fila são cercadas por sessão, então um cancelamento não pode deixar para trás um bloqueador de clique invisível nem remover uma sobreposição substituta.
  • Scripts de plugin mantêm a semântica de conclusão existente: o bloqueio de despertar dura até a liquidação ou o cancelamento, mesmo para uma promise que nunca se resolve. Scripts de plugin e ações longas de digitação não herdam o prazo de captura.

Sem novas dependências, permissões ou mudanças de CSP, e nada foi truncado no transcript ou no scrollback.

Como ver por conta própria

O caminho de aceitação é deliberadamente manual:

  1. Abra a mesma conversa em duas janelas, minimize uma, transmita uma resposta longa. Digite na janela visível e depois restaure a outra — ambas devem mostrar a resposta completa.
  2. Pressione Stop na janela visível. A saída cancelada não pode voltar quando você restaurar o par.
  3. Ative “Ler respostas em voz alta” nas duas janelas: os pares minimizados continuam limitados, mas o progresso concluído e a resposta final ainda são falados uma vez.
  4. Inicie uma conversa de voz em apenas uma janela: o streaming no par não deve interromper a captura nem a reprodução dela.
  5. Recarregue durante o streaming: a recuperação mantém o texto mais recente, incluindo a cauda silenciosa depois que o provedor para de enviar.

Quando você vai notar de verdade

Três situações: um notebook deixado acompanhando uma tarefa longa, quem mantém a mesma conversa aberta em duas ou três janelas para comparar, e quem lê documentação no preview embutido enquanto anota.

Não vai deixar seu modelo mais rápido nem suas respostas mais curtas. Só permite que janelas que ninguém está olhando fiquem quietas.

Você já pode usar?

As duas mudanças entraram na main em 4 de novembro, depois do ponto da release v0.22.7 — então, até a data deste texto, não estão em uma release; o post da v0.22.7 cobre o que de fato saiu. A latência de digitação no desktop tem sua própria análise, e, se o que você realmente quer é ser avisado quando algo precisa de você, o guia de atenção e notificações é a ponta receptora.