Last updated on

O prompt de aprovação que sumia no meio do café agora espera por você


Você pede ao seu agent para limpar um cache de build que não toca há meses. Ele pergunta se pode rodar o comando. Você aperta Enter e sai para pegar mais café. Quando volta, o prompt sumiu, o comando nunca rodou, e o transcript diz uma coisa só: aprovação expirada por timeout. Você não respondeu errado — o relógio simplesmente foi mais rápido que você.

Atualização (2026-10-03): A mudança foi revertida na mesma noite (PR #130826: a espera infinita já havia sido rejeitada como direção e deixava o hermes chat -q travado, onde ninguém pode responder). Os prompts de aprovação e de clarify no CLI, no TUI e no Desktop voltam a seguir approvals.timeout e agent.clarify_timeout. Motivos completos e o que fazer no lugar: a nota de reversão.

Esse relógio era o approvals.timeout, 300 segundos por padrão. Agora ele se divide por uma linha bem simples: a pessoa está olhando para a tela? Os prompts do CLI, do TUI e do Desktop ficam abertos até você responder, interromper o turno ou fechar a sessão. As plataformas de mensagens mantêm o prazo. Veja o que mudou e o que isso significa para o seu setup.

Primeiro, a barreira dos cinco minutos

As aprovações seguem uma regra não negociável: timeout não é um sim. Não é “ninguém respondeu, então pode ir” — é “ninguém respondeu, então não vá”. Esse é o padrão seguro, mas custa a você uma ação descartada em silêncio, e no transcript isso parece quase idêntico a “o comando falhou”.

Por que cinco minutos? Os comentários da config são honestamente diretos sobre isso: aprovações em plataformas de mensagens chegam como notificação push, e 60 segundos se mostraram apertados demais — no Telegram e no Discord o prompt muitas vezes expirava antes de o usuário alcançar o celular. Por isso o padrão foi elevado para 300.

O problema é que 300 segundos fazem sentido para uma notificação push e nenhum sentido quando o humano já está sentado em frente ao prompt. Você se levantou para beber um copo d’água, e o que encontrou ao voltar não foi “ainda esperando”, foi “você já perdeu”.

A nova regra, dividida por superfície

Superfície Por quanto tempo o prompt fica aberto
CLI interativo (hermes chat) até você responder ou interromper o turno
TUI o mesmo
App de Desktop o mesmo
Telegram / Discord / Slack e outras plataformas de mensagens ainda approvals.timeout (300 s por padrão)
Editores ACP e plugins de transporte de aprovação ainda approvals.timeout

A linha divisória não é qual superfície é mais sofisticada — é se o usuário consegue ver o prompt imediatamente. Numa plataforma de mensagens, uma aprovação é um push que pode ficar horas sem ser lido, e os próprios botões da plataforma expiram. Essas superfícies precisam de um prazo. No CLI, no TUI e no desktop, o prompt é pintado na tela que você já está olhando, então não há nada a perder.

Um limite que vale ter em mente: nada roda enquanto ele espera. O contrato não mudou — isso continua sendo fail-closed, nenhuma ferramenta é liberada enquanto o prompt está aberto, e interrompê-lo conta como negação.

Como isso é conectado

A mudança toca vários módulos, mas o núcleo é um switch vinculado uma vez por turno:

Onde O que faz
tools/approval_context.py adiciona set_prompts_wait_for_answer() / reset_prompts_wait_for_answer() atrás de uma variável de contexto por turno, e torna approval_wait_seconds() o único resolvedor para a janela de aprovação embutida
agent/deadline.py MAX_SAFE_TIMEOUT_S: 365 dias fora do Windows, e no Windows o teto de milissegundos do DWORD (cerca de 49,7 dias) — ambos semanticamente “sem limite”, dimensionados para que os limites de Lock.acquire / Thread.join derivados dele não estourem
tools/approval_human_wait.py human_wait_ceiling() retorna a janela de aprovação mais uma margem de 60 segundos, para que o loop de deadline em lote e o lock de serialização do gate de autorização compartilhem um único teto em vez de cada um inventar o seu
hermes_cli/cli_chat_turn_mixin.py vincula o switch em torno de cada turno, e o reconfigura no teardown
tui_gateway/prompt_turn.py TUI e Desktop compartilham esse backend: vinculado quando a entrada do turno é preparada, reconfigurado na saída

Um bug sutil foi corrigido junto. O loop de deadline em lote pode ler o teto de espera humana de um contexto que nunca viu o binding, o que faria um prompt sem limite parecer uma janela travada e continuaria estendendo um deadline de lote. Agora ele lê o teto real, e um prompt sem limite é excluído de imediato em vez de medido errado. As janelas de mensagens permanecem limitadas exatamente como antes.

A exceção a lembrar: o modo de consulta única

O hermes chat -q "..." não tem ninguém sentado ao lado, então de propósito não vincula o switch e continua usando approvals.timeout. Normalmente ele nunca espera: approvals.single_query_mode tem como padrão deny, então um comando perigoso é recusado na hora e o agent é empurrado a encontrar outra rota.

Se você roda sessões de consulta única em scripts ou CI, não conte com “esperar mais” — nunca houve ninguém ali para apertar a tecla.

O que verificar na sua máquina

  • O uso interativo não precisa mais de um timeout aumentado. Se você tinha empurrado o approvals.timeout para milhares de segundos só para se dar espaço, pode voltar atrás: agora ele só governa mensagens, ACP e transportes de plugins.
  • Ajuste as mensagens separadamente. hermes config set approvals.timeout 600 afeta apenas aquelas superfícies; a chave está documentada junto com o resto da config na referência do hermes config.
  • Pare de esperar que um timeout signifique sim. Para reduzir interrupções, use aprovações inteligentes; para abrir tudo, existem os níveis yolo; para proibir classes inteiras de comandos, use a deny list. O quadro mais amplo está no guia de aprovações sem supervisão.
  • Faça um dry-run antes de mudar a política. Dry-runs e autoverificações de aprovação mostram qual regra corresponde a qual veredito sem executar nada.
  • Cron e plataformas sem supervisão continuam negando. Seus padrões não mudaram, e é exatamente esse o ponto.

A conclusão

O que parece ser “o prompt parou de sumir” é, na verdade, um parâmetro dividido em duas situações: um humano está olhando, então não há deadline; ninguém está olhando, então precisa haver um. O primeiro caso evita que você perca uma ação por causa da sua própria pausa para o café. O segundo mantém honesta a rota de notificação push.

A regra prática é curta o bastante para memorizar: se o prompt está pintado na tela que você está olhando, ele espera por você; se foi enviado para o seu celular, ele tem que expirar.