Pular para o conteúdo principal

Documentação oficial desta página · v0.20.6

Sessões

O Hermes Agent salva automaticamente cada conversa como uma sessão. As sessões permitem retomar conversas, buscar em várias sessões e gerenciar todo o histórico de conversas.

Como as sessões funcionam​

Toda conversa — venha da CLI, do Telegram, do Discord, do Slack, do WhatsApp, do Signal, do Matrix, do Teams ou de qualquer outra plataforma de mensagens — é guardada como uma sessão com o histórico completo de mensagens. As sessões são rastreadas em:

  1. Banco SQLite (~/.hermes/state.db) — metadados estruturados da sessão com busca em texto completo FTS5, mais o histórico completo de mensagens

O banco SQLite guarda:

  • ID da sessão, plataforma de origem, ID do usuário
  • Título da sessão (único, legível por pessoas)
  • Nome e configuração do modelo
  • Retrato do prompt de sistema
  • Histórico completo de mensagens (papel, conteúdo, chamadas de ferramenta, resultados de ferramenta)
  • Contagem de tokens (entrada/saída)
  • Marcas de tempo (started_at, ended_at)
  • ID da sessão pai (para a divisão de sessão disparada por compressão)

O que conta para o contexto​

O Hermes guarda o histórico da sessão para poder retomar conversas, mas não fica reenviando cada byte que já passou por ele. A cada turno, o modelo vê o prompt de sistema selecionado, a janela de conversa atual e qualquer conteúdo que o Hermes injete explicitamente naquele turno.

Anexos de mídia são tratados como entradas com escopo de turno:

  • Imagens podem ser anexadas nativamente à próxima chamada de modelo, ou pré-analisadas numa descrição de texto quando o modelo ativo não suporta visão nativa.
  • Áudio é transcrito em texto quando a conversão de fala em texto está configurada.
  • Documentos de texto podem ter o texto extraído incluído; outros tipos de documento em geral são representados por um caminho local salvo e uma nota curta.
  • Caminhos de anexos e texto extraído/derivado podem aparecer na transcrição, mas os bytes crus da imagem, do áudio ou do arquivo binário não são copiados repetidamente para os prompts futuros.

Por exemplo, se um usuário manda uma imagem e pede ao Hermes para fazer um meme a partir dela, o Hermes pode inspecionar essa imagem uma vez com visão e rodar um script de processamento de imagem. Os turnos seguintes não carregam automaticamente o JPEG original no contexto. Eles carregam só o que foi escrito na conversa, como o pedido do usuário, uma descrição curta da imagem, um caminho de cache local ou a resposta final do assistente.

A causa mais comum de crescimento do contexto não é o arquivo de mídia em si. É texto prolixo: transcrições coladas, logs inteiros, saídas grandes de ferramenta, diffs longos, relatórios de status repetidos e despejos detalhados de comprovação. Prefira resumos, caminhos de arquivo, trechos focados e consultas via ferramenta a copiar artefatos grandes para o chat.

dica

Use /compress quando uma sessão fica longa, /new para uma linha nova, e hermes sessions prune só quando quiser apagar do armazenamento sessões antigas já encerradas. Se o state.db simplesmente cresceu muito, comece pela opção não destrutiva: hermes sessions optimize mescla os segmentos do índice FTS5 e roda VACUUM no banco sem tocar em nenhum dado de sessão. A compressão reduz o contexto ativo; não é uma exclusão por privacidade. Passe um nome para /new (por exemplo, /new refatoracao-pagamentos) para definir o título inicial da nova sessão de saída — útil para encontrá-la depois com /resume <nome> ou no seletor do /sessions.

Origens de sessão​

Cada sessão é marcada com a plataforma de origem:

OrigemDescrição
cliCLI interativa (hermes ou hermes chat)
telegramMensageiro Telegram
discordServidor/DM do Discord
slackEspaço de trabalho do Slack
whatsappMensageiro WhatsApp
signalMensageiro Signal
matrixSalas e DMs do Matrix
mattermostCanais do Mattermost
emailE-mail (IMAP/SMTP)
smsSMS via Twilio
dingtalkMensageiro DingTalk
feishuMensageiro Feishu/Lark
wecomWeCom (WeChat Work)
weixinWeixin (WeChat pessoal)
bluebubblesApple iMessage via servidor BlueBubbles no macOS
qqbotQQ Bot (Tencent QQ) via API oficial v2
homeassistantConversa do Home Assistant
webhookWebhooks de entrada
api-serverRequisições do servidor de API
acpIntegração com editor via ACP
cronTarefas agendadas por cron
batchExecuções de processamento em lote

Retomar sessões na CLI​

Retome conversas anteriores pela CLI com --continue ou --resume:

Continuar a última sessão​

# Retoma a sessão de CLI mais recente
hermes --continue
hermes -c

# Ou com o subcomando de chat
hermes chat --continue
hermes chat -c

Isso busca a sessão cli mais recente no banco SQLite e carrega todo o histórico da conversa.

Continuar por terminal​

Um -c sozinho conhece o terminal: cada sessão de CLI deixa um pequeno arquivo de migalha em ~/.hermes/terminal-sessions/, indexado pelo terminal em que roda (dispositivo tty, painel do tmux, janela do kitty, painel do wezterm, painel do Zellij, sessão do Windows Terminal, ...). Quando você roda hermes -c de novo no mesmo terminal, o Hermes retoma a sessão daquele terminal — então dois painéis lado a lado continuam cada um a sua própria conversa, em vez de os dois agarrarem a mais recente do sistema. Se não existe migalha para o terminal (primeiro uso, sessão apagada ou migalha velha de mais de 30 dias), o -c volta ao comportamento de sessão mais recente. -c "nome" e --resume não são afetados. Desative com session.terminal_continue: false no config.yaml.

Retomar por nome​

Se você deu um título a uma sessão (veja Nomear sessões abaixo), pode retomá-la pelo nome:

# Retoma uma sessão nomeada
hermes -c "meu projeto"

# Se existem variantes de linhagem (meu projeto, meu projeto #2, meu projeto #3),
# isto retoma automaticamente a mais recente
hermes -c "meu projeto" # → retoma "meu projeto #3"

Retomar uma sessão específica​

# Retoma uma sessão específica pelo ID
hermes --resume 20250305_091523_a1b2c3d4
hermes -r 20250305_091523_a1b2c3d4

# Retoma pelo título
hermes --resume "refatorando a autenticação"

# Retoma a sessão mais recente — a mesma busca do -c
hermes --resume latest

# Ou com o subcomando de chat
hermes chat --resume 20250305_091523_a1b2c3d4

Os IDs de sessão aparecem quando você sai de uma sessão de CLI, e podem ser encontrados com hermes sessions list.

observação

latest é uma palavra reservada do --resume. Uma sessão intitulada literalmente "latest" continua alcançável pelo ID ou via -c latest (que casa por título).

Retomar em um diretório específico​

Passe --in <dir> para entrar num diretório antes de iniciar ou retomar. Combinado com --resume latest (ou -c), a sessão mais recente do espaço de trabalho daquele diretório é escolhida — sem precisar dar cd antes nem lembrar IDs de sessão:

# Retoma a última sessão que pertence a ./meu-projeto
hermes --resume latest --in ./meu-projeto

# Funciona com a TUI também
hermes --tui --resume latest --in ./meu-projeto

O --in também fixa a sessão naquele diretório: o diretório de trabalho registrado na sessão retomada não é restaurado (como se --no-restore-cwd tivesse sido passado).

Retomar restaura o diretório de trabalho​

Retomar uma sessão de CLI também faz cd de volta ao diretório de trabalho registrado na sessão (a raiz do repositório git ou o diretório do projeto), para a conversa continuar no espaço de trabalho a que pertencia. Se você preferir ficar onde está, passe --no-restore-cwd:

hermes --resume 20250305_091523_a1b2c3 --no-restore-cwd

Uma linha ↪ restored workspace dir: … confirma a troca. Falhas na restauração nunca quebram a retomada em si.

Filtrar sessões por espaço de trabalho​

O hermes sessions list aceita --workspace <trecho> para mostrar só as sessões cuja chave de espaço de trabalho (raiz do repositório git, ou o cwd) casa — por parte do caminho ou pelo nome exato do diretório:

hermes sessions list --workspace meu-projeto
hermes sessions list --workspace ~/code/hermes-agent

Recapitulação da conversa ao retomar​

Quando você retoma uma sessão, o Hermes mostra uma recapitulação compacta da conversa anterior num painel estilizado, antes do prompt de entrada:

Prévia estilizada do painel de recapitulação Conversa Anterior, mostrado ao retomar uma sessão do Hermes.

O modo de retomada mostra um painel compacto de recapitulação com os turnos recentes do usuário e do assistente antes de devolver você ao prompt ao vivo.

A recapitulação:

  • Mostra as mensagens do usuário (● dourado) e as respostas do assistente (◆ verde)
  • Corta mensagens longas (300 caracteres para o usuário, 200 caracteres / 3 linhas para o assistente)
  • Colapsa chamadas de ferramenta numa contagem com os nomes das ferramentas (por exemplo, [3 tool calls: terminal, web_search])
  • Esconde mensagens de sistema, resultados de ferramenta e raciocínio interno
  • Limita às últimas 10 trocas, com um indicador "... N earlier messages ..."
  • Usa estilo apagado para se distinguir da conversa ativa

Para desativar a recapitulação e manter o comportamento mínimo de uma linha, defina em ~/.hermes/config.yaml:

display:
resume_display: minimal # padrão: full
dica

Os IDs de sessão seguem o formato YYYYMMDD_HHMMSS_<hex> — sessões de CLI/TUI usam um sufixo hex de 6 caracteres (por exemplo, 20250305_091523_a1b2c3), sessões de gateway usam um sufixo de 8 caracteres (por exemplo, 20250305_091523_a1b2c3d4). Você pode retomar pelo ID (completo ou por um prefixo único) ou pelo título — ambos funcionam com -c e -r.

Passagem entre plataformas​

Use /handoff <plataforma> dentro de uma sessão de CLI para transferir a conversa ao vivo para o canal principal de uma plataforma de mensagens. O agente continua exatamente de onde a CLI parou — mesmo id de sessão, transcrição completa com papéis, chamadas de ferramenta e tudo.

# Dentro de uma sessão de CLI
/handoff telegram

O que acontece:

  1. A CLI valida que a <plataforma> está habilitada e tem um canal principal definido (rode /sethome uma vez no chat de destino para configurá-lo).

  2. A CLI marca a sessão como pendente e consulta o gateway em bloqueio. Ela recusa se o agente estiver no meio de um turno — espere a resposta atual terminar primeiro.

  3. O observador do gateway assume a passagem e pede ao adaptador de destino uma linha nova:

    • Telegram — abre um novo tópico de fórum (tópicos em DM se o modo Topics da Bot API 9.4+ estiver habilitado no chat, ou um tópico de supergrupo de fórum).
    • Discord — cria uma linha com arquivamento automático de 1440 min sob o canal de texto principal.
    • Slack — publica uma mensagem semente e usa o ts dela como âncora da linha.
    • WhatsApp / Signal / Matrix / SMS — sem linhas nativas, cai direto no canal principal.
  4. O gateway reassocia a chave de destino ao id da sua sessão de CLI existente e, então, forja um turno sintético de usuário pedindo ao agente para confirmar e resumir. A resposta chega na linha nova.

  5. Quando o gateway confirma o sucesso, a CLI imprime uma dica de /resume e sai de forma limpa:

    ↻ Handoff complete. The session is now active on telegram.
    Resume it on this CLI later with: /resume my-session-title
  6. Desse ponto em diante, a conversa vive na plataforma. Responda na linha nova — qualquer pessoa autorizada naquele canal compartilha a mesma sessão, e qualquer mensagem real de usuário que venha depois na linha entra sem atrito, porque sessões de linha são indexadas sem user_id.

Retomar de volta na CLI: quando quiser voltar para um desktop, basta rodar /resume <título> (ou hermes -r "<título>" no shell) e continuar de onde a plataforma parou.

Modos de falha:

  • Nenhum canal principal configurado → a CLI recusa com uma dica de /sethome.
  • Plataforma não habilitada / gateway não rodando → a CLI expira em 60s com uma mensagem clara e sua sessão de CLI fica intacta.
  • Criação da linha falha (permissões, modo de tópicos desligado) → cai direto no canal principal e ainda assim conclui; sem isolamento por linha, mas a passagem em si funciona.
  • adapter.send falha (limite de taxa, erro transitório de API) → a passagem é marcada como falha com o motivo; a linha do registro é limpa para você tentar de novo.

Limitação que vale saber: em plataformas sem suporte a linhas, com canais principais de grupo multiusuário, o turno sintético é indexado como uma sessão em estilo de DM. Isso funciona para canais principais de auto-DM (a configuração típica), mas não é ideal para chats de grupo genuinamente compartilhados. As linhas cobrem Telegram / Discord / Slack — de longe o caso comum — então a maioria das configurações nunca encosta nisso.

Nomear sessões​

Dê às sessões títulos legíveis por pessoas, para você encontrá-las e retomá-las com facilidade.

Títulos gerados automaticamente​

O Hermes gera automaticamente um título curto e descritivo (3 a 7 palavras) para cada sessão depois da primeira troca. Isso roda numa thread de fundo com um modelo auxiliar rápido, então não acrescenta latência. Você vê os títulos automáticos ao navegar pelas sessões com hermes sessions list ou hermes sessions browse.

A titulação automática dispara uma única vez por sessão, e é pulada se você já definiu um título manualmente.

Definir um título manualmente​

Use o comando de barra /title dentro de qualquer sessão de chat (CLI ou gateway):

/title meu projeto de pesquisa

O título é aplicado na hora. Se a sessão ainda não foi criada no banco (por exemplo, você roda /title antes de mandar a primeira mensagem), ele fica na fila e é aplicado quando a sessão começa.

Você também pode renomear sessões existentes pela linha de comando:

hermes sessions rename 20250305_091523_a1b2c3d4 "refatorando o módulo de autenticação"

Regras de título​

  • Único — duas sessões não podem ter o mesmo título
  • Máximo de 100 caracteres — mantém a saída das listagens limpa
  • Higienizado — caracteres de controle, caracteres de largura zero e sobrescritas RTL são removidos automaticamente
  • Unicode normal está de boa — emoji, CJK e caracteres acentuados funcionam

Linhagem automática na compressão​

Quando o contexto de uma sessão é comprimido (manualmente via /compress ou automaticamente), o Hermes cria uma nova sessão de continuação. Se a original tinha título, a nova sessão ganha automaticamente um título numerado:

"meu projeto" → "meu projeto #2" → "meu projeto #3"

Quando você retoma pelo nome (hermes -c "meu projeto"), ele escolhe automaticamente a sessão mais recente da linhagem.

/title nas plataformas de mensagens​

O comando /title funciona em todas as plataformas de gateway (Telegram, Discord, Slack, WhatsApp):

  • /title Minha Pesquisa — define o título da sessão
  • /title — mostra o título atual

Comandos de gerenciamento de sessão​

O Hermes oferece um conjunto completo de comandos de gerenciamento de sessão via hermes sessions:

Listar sessões​

# Lista as sessões recentes (padrão: últimas 20)
hermes sessions list

# Filtra por plataforma
hermes sessions list --source telegram

# Mostra mais sessões
hermes sessions list --limit 50

Quando as sessões têm títulos, a saída mostra títulos, prévias e marcas de tempo relativas:

Title Preview Last Active ID
────────────────────────────────────────────────────────────────────────────────────────────────
refactoring auth Help me refactor the auth module please 2h ago 20250305_091523_a
my project #3 Can you check the test failures? yesterday 20250304_143022_e
— What's the weather in Las Vegas? 3d ago 20250303_101500_f

Quando nenhuma sessão tem título, um formato mais simples é usado:

Preview Last Active Src ID
──────────────────────────────────────────────────────────────────────────────────────
Help me refactor the auth module please 2h ago cli 20250305_091523_a
What's the weather in Las Vegas? 3d ago tele 20250303_101500_f

Exportar sessões​

O hermes sessions export é uma única porta para todos os formatos de export, escolhidos com --format:

FormatoSaídaUse para
jsonl (padrão)um objeto JSON por sessãobackups, ida e volta por máquina
md / qmdum arquivo Markdown/Quarto por sessão + manifestoarquivos legíveis, notas
htmlpágina única autocontida (barra lateral para várias sessões)compartilhar, navegar
traceJSONL do Claude CodeHF Agent Trace Viewer, --upload

Mais o --only user-prompts para uma visão só dos prompts (jsonl ou md).

Todos os formatos compartilham os mesmos botões de seleção: --session-id para uma sessão, ou o conjunto completo de filtros de prune/archive para operação em massa — --older-than / --newer-than / --before / --after (durações como 5h/2d/1w, número puro de dias, ou marcas de tempo ISO), --source, --title, --model, --provider, --cwd, --min/--max-messages, --min/--max-tokens, --min/--max-cost, --min/--max-tool-calls, --user, --chat-id, --chat-type, --branch, --end-reason. O --dry-run mostra a prévia do conjunto casado sem escrever nada. O --redact limpa segredos (chaves de API, tokens, credenciais) do conteúdo exportado em qualquer formato — recomendado para tudo que você pretende compartilhar. Observação: os filtros em massa casam com sessões encerradas; um export sem filtro despeja tudo, inclusive as ativas.

JSONL (padrão)​

# Exporta todas as sessões para um arquivo JSONL
hermes sessions export backup.jsonl

# Exporta sessões de uma plataforma específica
hermes sessions export telegram-history.jsonl --source telegram

# Exporta uma única sessão
hermes sessions export session.jsonl --session-id 20250305_091523_a1b2c3d4

# Remove chaves de API/tokens/credenciais do conteúdo exportado
hermes sessions export backup.jsonl --redact

Os arquivos exportados contêm um objeto JSON por linha, com todos os metadados da sessão e todas as mensagens.

HTML​

O --format html escreve um único arquivo HTML autocontido — sem dependências remotas — com bolhas de mensagem estilizadas, saída de ferramenta colapsável e (para exports de várias sessões) uma barra lateral para alternar entre sessões:

# Uma sessão como página HTML independente
hermes sessions export --format html --session-id 20250305_091523_a1b2c3d4 transcript.html

# Todas as sessões do Telegram da última semana num só arquivo, com segredos removidos
hermes sessions export --format html --newer-than 1w --source telegram --redact archive.html

Só os prompts​

O --only user-prompts exporta apenas os prompts que você escreveu — sem respostas do assistente, saída de ferramenta ou contexto de sistema. Útil para montar bibliotecas de prompt ou rever o que você pediu:

# Um registro JSONL por prompt (id da sessão, índice, marca de tempo, texto)
hermes sessions export prompts.jsonl --session-id 20250305_091523_a1b2c3d4 --only user-prompts

# Markdown, direto para a saída padrão
hermes sessions export - --session-id 20250305_091523_a1b2c3d4 --only user-prompts --format md

Funciona com --format jsonl (padrão) ou md, respeita os mesmos filtros do export em massa, e combina com --redact.

Traços (HF Agent Trace Viewer)​

O --format trace emite JSONL do Claude Code — o formato de transcrição que o Hugging Face Hub detecta automaticamente no seu Agent Trace Viewer. Escreva localmente, ou acrescente --upload para enviar ao seu próprio dataset privado hermes-traces (que lê HF_TOKEN):

# Traço da sessão mais recente, para a saída padrão
hermes sessions export --format trace

# Uma sessão para um arquivo de traço local
hermes sessions export --format trace --session-id 20250305_091523_a1b2c3d4 trace.jsonl

# Envia direto para seu dataset privado de traços no HF
hermes sessions export --format trace --session-id 20250305_091523_a1b2c3d4 --upload

Exports de traço vêm com segredos removidos por padrão (eles nascem para sair da máquina); --no-redact desiste disso depois de uma revisão manual. O --upload é privado, a menos que você passe --public. O export de traço em massa com filtros escreve um <id>.trace.jsonl por sessão.

Markdown / QMD​

Passe --format md ou --format qmd quando quiser um arquivo legível, baseado em arquivos, antes de esconder ou apagar sessões antigas. Exports Markdown/QMD escrevem um arquivo por sessão num diretório (padrão: ~/.hermes/session-exports).

# Exporta uma sessão para Markdown
hermes sessions export --format md --session-id 20250305_091523_a1b2c3d4

# Exporta uma linhagem de compressão como um documento lógico único
hermes sessions export --format md --session-id 20250305_091523_a1b2c3d4 --lineage logical

# Prévia das sessões encerradas com mais de 90 dias, sem escrever arquivos
hermes sessions export --format md --older-than 90 --dry-run

# Exporta sessões encerradas do Telegram com mais de 2 semanas para arquivos QMD
hermes sessions export --format qmd --older-than 2w --source telegram

# Exporta sessões longas do Claude, com segredos removidos
hermes sessions export --format md --model sonnet --min-messages 50 --redact

# Só depois de verificar, exporta e apaga uma sessão nomeada explicitamente
hermes sessions export --format md --session-id 20250305_091523_a1b2c3d4 --delete-after-verified --yes

O export Markdown/QMD escreve um arquivo .md ou .qmd por sessão exportada, mais um manifest.jsonl com o caminho do arquivo, a contagem de mensagens, os ids da linhagem e o SHA-256. O export em massa exige pelo menos um filtro; um export em massa pelado é recusado. O --delete-after-verified é intencionalmente limitado ao --session-id e exige --yes. Como apagar uma sessão pai também remove as sessões dos seus delegados/subagentes, esse modo exporta e verifica cada delegado num arquivo separado antes de apagar qualquer coisa. Se o conjunto de delegados muda durante o export, a exclusão é recusada. O --redact limpa segredos (chaves de API, tokens, credenciais) do conteúdo das mensagens e da saída de ferramenta antes de escrever — recomendado para qualquer export que você pretenda compartilhar.

Apagar uma sessão​

# Apaga uma sessão específica (com confirmação)
hermes sessions delete 20250305_091523_a1b2c3d4

# Apaga sem confirmação
hermes sessions delete 20250305_091523_a1b2c3d4 --yes

Renomear uma sessão​

# Define ou muda o título de uma sessão
hermes sessions rename 20250305_091523_a1b2c3d4 "depurando o fluxo de autenticação"

# Títulos de várias palavras não precisam de aspas na CLI
hermes sessions rename 20250305_091523_a1b2c3d4 depurando fluxo de autenticacao

Se o título já está em uso por outra sessão, um erro é exibido.

Fixar uma sessão​

Fixar define uma marca durável de "manter": sessões fixadas ficam isentas da varredura de sessões paradas do sessions.auto_archive e sempre aparecem nas listagens. É a mesma marca que a seção Fixadas da barra lateral do Desktop usa — fixe de qualquer uma das duas superfícies e as duas veem.

# Fixa uma ou mais sessões (prefixos únicos de ID funcionam)
hermes sessions pin 20250305_091523_a1b2c3d4
hermes sessions pin 20250305 20250306

# Remove a fixação
hermes sessions unpin 20250305_091523_a1b2c3d4

# Lista as sessões fixadas
hermes sessions pinned

# Saída legível por máquina, por exemplo para um backup noturno do seu conjunto de fixadas
hermes sessions pinned --json > pinned-sessions.json

Podar sessões antigas​

# Apaga sessões encerradas e inativas há 90 dias (padrão)
hermes sessions prune

# Limite de idade personalizado — números puros são dias
hermes sessions prune --older-than 30

# Durações também funcionam: 5h, 30m, 2d, 1w
hermes sessions prune --older-than 12h

# Apaga só uma janela de tempo específica (por exemplo, um lote de sessões
# de teste criadas nas últimas 5 horas)
hermes sessions prune --newer-than 5h

# Janela explícita com marcas de tempo absolutas
hermes sessions prune --after "2026-07-05 09:00" --before "2026-07-05 14:30"

# Poda só sessões de uma plataforma específica (todas as idades — qualquer filtro
# desliga o padrão implícito de 90 dias)
hermes sessions prune --source telegram
hermes sessions prune --source cron --older-than 60 # some um filtro de tempo para estreitar

# Mais filtros — todos combinam com E
hermes sessions prune --newer-than 5h --title "smoke test" # parte do título
hermes sessions prune --older-than 30 --max-messages 3 # sessões minúsculas
hermes sessions prune --cwd ~/scratch --end-reason done # por cwd / motivo de fim
hermes sessions prune --model gpt-5 --older-than 1w # por modelo (parte do nome)
hermes sessions prune --provider openrouter --older-than 60 # por provedor de cobrança
hermes sessions prune --branch feature/old-experiment # por branch do git
hermes sessions prune --user 12345678 --chat-type group # pela origem de mensagens
hermes sessions prune --max-tokens 500 --older-than 7 # pelo uso de tokens
hermes sessions prune --max-cost 0.01 --max-tool-calls 0 # execuções baratas e sem ferramenta

# Prévia do que seria apagado, sem apagar nada
hermes sessions prune --newer-than 5h --dry-run

# Pula a confirmação
hermes sessions prune --older-than 30 --yes

Valores de tempo (--older-than, --newer-than, --before, --after) aceitam uma duração (5h, 30m, 2d, 1w), um número puro de dias, ou uma marca de tempo ISO (2026-07-05, 2026-07-05 14:30). --older-than/--before definem o limite superior; --newer-than/--after definem o limite inferior. O par --older-than/--newer-than usa a atividade da última mensagem (caindo para o início da sessão em sessões vazias); --before/--after usa explicitamente a hora de início da sessão. Combine qualquer um dos pares para formar uma janela.

Filtros por atributo: --source (plataforma, exato), --title / --model / --branch (parte do texto, sem diferenciar maiúsculas), --provider (provedor de cobrança, exato), --end-reason, --user, --chat-id, --chat-type (exatos), --cwd (prefixo de caminho), mais os limites numéricos --min/--max-messages, --min/--max-tokens (entrada+saída), --min/--max-cost (em USD, o real caindo para o estimado) e --min/--max-tool-calls. Usar qualquer filtro desliga o padrão implícito de 90 dias, então hermes sessions prune --source cron ou --model gpt-4o casa com todas as idades — some um filtro de tempo para estreitar. Só um hermes sessions prune completamente pelado mantém o corte de 90 dias. Toda execução sem --yes mostra a contagem de casamentos, mais a sessão casada mais antiga e a mais nova, antes de pedir confirmação.

Sessões arquivadas são puladas por padrão; passe --include-archived para apagá-las também.

informação

A poda só apaga sessões encerradas (sessões explicitamente encerradas ou reiniciadas automaticamente). Sessões ativas nunca são podadas.

Arquivar sessões em massa​

Se você quer tirar sessões das suas listagens sem apagar nada, o hermes sessions archive aceita os mesmos filtros do prune, mas esconde suavemente as sessões casadas em vez de apagá-las (define a mesma marca de arquivada que arquivar uma sessão individual pela interface do Desktop/Painel — mensagens e busca ficam intactas):

# Arquiva tudo das últimas 5 horas (por exemplo, 75 sessões de smoke test da CI)
hermes sessions archive --newer-than 5h

# Arquiva por parte do título, com prévia primeiro
hermes sessions archive --title "dry run" --dry-run
hermes sessions archive --title "dry run" --yes

Pelo menos um filtro é obrigatório — um hermes sessions archive pelado se recusa a arquivar todo o seu histórico. Sessões arquivadas ficam escondidas do hermes sessions list e do /resume, mas permanecem no banco e podem ser desarquivadas na lista de sessões do Desktop/Painel.

Estatísticas de sessão​

hermes sessions stats

Saída:

Total sessions: 142
Total messages: 3847
cli: 89 sessions
telegram: 38 sessions
discord: 15 sessions
Database size: 12.4 MB

Para análises mais profundas — uso de tokens, estimativas de custo, detalhamento por ferramenta e padrões de atividade — use o hermes insights.

Reparar sessões de gateway órfãs​

Se uma conversa de gateway alguma vez "voltar no tempo" depois de um reinício — retomando um tópico de dias atrás como se as mensagens recentes nunca tivessem acontecido — a conversa ao vivo pode estar órfã numa linha de sessão que perdeu sua identidade de roteamento (a classe de dano corrigida no trabalho de continuidade de sessão da v0.21; as versões atuais impedem isso por construção e se autocuram em tempo de execução).

O hermes sessions repair-routing encontra linhas de sessão que têm mensagens mas nenhuma identidade de roteamento, e reanexa cada uma à conversa que ela continua — mas só quando a evidência é inequívoca:

# Só relatório — mostra cada órfã, a adoção proposta e a evidência
hermes sessions repair-routing

# Executa as adoções (pare o gateway primeiro — um gateway rodando mantém
# o roteamento antigo em memória e escreveria de volta sobre o reparo)
hermes sessions repair-routing --apply

# Alarga/estreita a janela de contiguidade (padrão: 900 segundos)
hermes sessions repair-routing --max-gap-seconds 300

Regras de evidência:

  • linhagem — o parent_session_id da órfã aponta para uma linha indexada da mesma plataforma (um fato registrado; nenhuma janela de tempo se aplica)
  • contiguidade — exatamente uma linha indexada da mesma plataforma ficou quieta dentro da janela do início da órfã

Qualquer coisa ambígua (dois candidatos a predecessor, duas órfãs reivindicando o mesmo predecessor) é reportada com um motivo e deixada intacta — uma adoção errada emendaria uma conversa dentro de outro chat. A linha superada é aposentada sob superseded_by_repair, para a recuperação no reinício nunca poder ressuscitá-la.

O reparo não é automático de propósito: se o chat já construiu um segundo histórico desde então, escolher qual linha ele continua é decisão sua. A conversa órfã continua legível pelo /resume e pela busca de sessões nos dois casos — o roteamento é a única coisa que o reparo muda. Faça backup primeiro (cp ~/.hermes/state.db ~/.hermes/state.db.bak).

Importar sessões do Claude Code e da Codex CLI​

Começou uma conversa em outra CLI de agente? Você pode trazê-la para o Hermes e continuar aqui. O Hermes lê os logs de sessão do Claude Code (~/.claude/projects/) e os rollouts da Codex CLI (~/.codex/sessions/) — os arquivos alheios são apenas lidos, nunca modificados.

# Seletor interativo nas duas ferramentas, mais novas primeiro
hermes sessions import

# Limita a uma ferramenta, ou aponta para um arquivo específico
hermes sessions import --from claude
hermes sessions import --from codex ~/.codex/sessions/2026/08/15/rollout-....jsonl

# Importar e retomar num passo só
hermes --resume @claude
hermes --resume @codex

O hermes sessions import cria uma nova sessão do Hermes intitulada Imported from Claude Code: <primeira mensagem do usuário> (ou Codex CLI) e imprime o id mais um comando hermes --resume <id> pronto para colar. --resume @claude / --resume @codex mostram o mesmo seletor e jogam você direto dentro da conversa importada.

O que vem junto: a conversa ordenada de usuário/assistente, com a atividade de ferramenta condensada em notas curtas [ran tool: …] dentro dos turnos do assistente. Prompts de sistema, contexto injetado, traços de raciocínio e saída crua de ferramenta ficam para trás — a importação é uma transcrição limpa, não uma repetição byte a byte.

Ferramenta de busca em sessões​

O agente tem uma ferramenta embutida session_search que faz busca em texto completo em todas as conversas passadas, usando o motor FTS5 do SQLite — e deixa o agente percorrer qualquer sessão que encontrar. Ela não faz nenhuma chamada de LLM e devolve visões das mensagens reais do banco, em vez de gerar resumos.

Quatro formas de chamada​

A ferramenta deduz o que você quer a partir de quais argumentos você define. Não existe parâmetro mode.

1. Descoberta — passe query:

session_search(query="refatoração da autenticação", limit=3)

Roda o FTS5, remove duplicatas dos acertos por linhagem de sessão, e devolve as N melhores sessões. A descoberta usa detalhe adaptativo por padrão: o resultado melhor classificado inclui a janela de contexto completa e os extremos, enquanto os resultados de classificação mais baixa ficam compactos. Passe detail="full" para hidratar completamente cada resultado.

Cada resultado traz:

  • session_id, title, when, source
  • snippet — trecho do casamento, destacado pelo FTS5
  • detail — full ou compact
  • bookend_start / bookend_end — as 3 primeiras/últimas mensagens de usuário+assistente para resultados completos; listas vazias para resultados compactos
  • messages — ±5 mensagens em torno do casamento do FTS5 para resultados completos; só a mensagem-âncora sinalizada para resultados compactos
  • match_message_id, messages_before, messages_after

O melhor resultado reconstrói objetivo → casamento → resolução na hora. Se outro resultado compacto parece mais promissor, use os IDs de sessão e de mensagem dele com a forma de rolagem. O tempo típico de parede é de dezenas de milissegundos num banco de sessões real.

2. Rolagem — passe session_id + around_message_id:

session_search(session_id="20260510_174648_805cc2", around_message_id=590803, window=10)

Devolve uma janela de ±window mensagens centrada na âncora. Sem FTS5, sem extremos — só a fatia. Use depois de uma chamada de descoberta, quando você precisa de mais contexto que a janela padrão de ±5.

  • Para rolar para frente: passe messages[-1].id de volta como around_message_id
  • Para rolar para trás: passe messages[0].id de volta como around_message_id
  • A mensagem da fronteira aparece nas duas janelas, como marcador de orientação
  • Quando messages_before ou messages_after é menor que window, você está no começo ou no fim da sessão

Tempo típico de parede: 1 a 2 ms por chamada de rolagem.

3. Leitura — passe session_id sem âncora:

session_search(session_id="20260510_174648_805cc2")

Devolve a sessão inteira, ou uma visão limitada de começo/fim para sessões grandes. Esta forma também é usada para resolver um link @session:<perfil>/<id>.

4. Navegação — sem argumentos:

session_search()

Devolve as sessões recentes em ordem cronológica (títulos, prévias, marcas de tempo). Útil quando o usuário pergunta "no que eu estava trabalhando" sem nomear um assunto.

Sintaxe de consulta do FTS5​

O modo de palavras-chave suporta a sintaxe padrão de consulta do FTS5:

  • Palavras-chave simples: docker deployment (o FTS5 usa E por padrão)
  • Frases: "frase exata"
  • Booleano: docker OR kubernetes, python NOT java
  • Prefixo: deploy*

Parâmetros opcionais​

  • sort — newest ou oldest, por cima da classificação do FTS5. Omita para ordenar só por relevância (o padrão; adequado para lembrança exploratória). Use newest para perguntas do tipo "onde a gente parou em X", oldest para perguntas do tipo "como X começou".
  • detail — adaptive (padrão) hidrata completamente só o melhor resultado da descoberta; full hidrata todos os resultados da descoberta.
  • role_filter — papéis a incluir, separados por vírgula. A descoberta usa user,assistant por padrão (a saída de ferramenta em geral é ruído). Passe user,assistant,tool para incluir a saída de ferramenta (ao depurar comportamento de ferramenta) ou tool para buscar só na saída de ferramenta.

Quando ela é usada​

O agente é instruído a usar a busca em sessões automaticamente:

"When the user references something from a past conversation or you suspect relevant prior context exists, use session_search to recall it before asking them to repeat themselves."

("Quando o usuário faz referência a algo de uma conversa passada, ou você suspeita que existe contexto anterior relevante, use session_search para lembrar disso antes de pedir que ele repita.")

Disparos típicos: "a gente fez isso antes", "lembra quando", "da última vez", "como eu falei", ou qualquer referência a um projeto/pessoa/conceito que não está na janela atual.

Rastreamento de sessão por plataforma​

Sessões de gateway​

Nas plataformas de mensagens, as sessões são indexadas por uma chave de sessão determinística, montada a partir da origem da mensagem:

Tipo de chatFormato padrão da chaveComportamento
DM do Telegramagent:main:telegram:dm:<chat_id>Uma sessão por chat de DM
DM do Discordagent:main:discord:dm:<chat_id>Uma sessão por chat de DM
DM do WhatsAppagent:main:whatsapp:dm:<canonical_identifier>Uma sessão por usuário de DM (apelidos LID/telefone colapsam numa identidade quando existe mapeamento)
Chat de grupoagent:main:<platform>:group:<chat_id>:<user_id>Por usuário dentro do grupo, quando a plataforma expõe um ID de usuário
Linha/tópico de grupoagent:main:<platform>:group:<chat_id>:<thread_id>Sessão compartilhada por todos os participantes da linha (padrão). Por usuário com thread_sessions_per_user: true.
Canalagent:main:<platform>:channel:<chat_id>:<user_id>Por usuário dentro do canal, quando a plataforma expõe um ID de usuário

Quando o Hermes não consegue obter um identificador de participante para um chat compartilhado, ele cai para uma única sessão compartilhada naquela sala.

Sessões de grupo compartilhadas ou isoladas​

Por padrão, o Hermes usa group_sessions_per_user: true no config.yaml. Isso significa que:

  • Alice e Bob podem os dois falar com o Hermes no mesmo canal do Discord sem compartilhar o histórico da transcrição
  • a tarefa longa e cheia de ferramentas de um usuário não polui a janela de contexto de outro
  • o tratamento de interrupção também fica por usuário, porque a chave do agente em execução casa com a chave da sessão isolada

Se você quer um único "cérebro da sala" compartilhado, defina:

group_sessions_per_user: false

Isso reverte grupos/canais para uma única sessão compartilhada por sala, o que preserva o contexto conversacional compartilhado, mas também compartilha custos de token, estado de interrupção e crescimento de contexto.

Políticas de reinício de sessão​

Por padrão, sessões de gateway nunca reiniciam automaticamente (mode: none). Você pode optar por reinícios automáticos na seção session_reset do config.yaml:

  • none — nunca reinicia automaticamente (padrão; contexto gerenciado pelo /reset e pela compressão)
  • idle — reinicia depois de N minutos de inatividade
  • daily — reinicia numa hora específica de cada dia
  • both — reinicia no que vier primeiro (inatividade ou horário diário)

Antes de uma sessão ser reiniciada automaticamente, o agente recebe um turno para salvar memórias ou skills importantes da conversa.

Sessões com processos de fundo ativos nunca são reiniciadas automaticamente, seja qual for a política.

Continuidade depois de quedas e reinícios​

Um chat de gateway foi desenhado para ser uma sessão contínua — compactada repetidamente conforme cresce — até você rodar explicitamente /new (ou /reset). Isso vale por cima de quedas, reinícios e atualizações do gateway:

  • A identidade da sessão (chave de roteamento, chat, origem) é escrita atomicamente quando a linha da sessão é criada, em todo caminho de criação (/new, primeira mensagem, filhos do /branch). Se essa escrita falhar, a atualização de roteamento do turno seguinte repara a linha automaticamente.
  • Depois de um reinício, o gateway resolve de novo cada chat para a sessão com a atividade real mais recente — uma linha antiga e parada nunca pode vencer a conversa que você estava realmente tendo.
  • A recuperação respeita as fronteiras do /new: se o evento mais recente de um chat é um reinício intencional, a recuperação começa do zero em vez de esticar o braço atrás do reinício para ressuscitar uma sessão antiga. As sessões recuperadas também mantêm o tempo real de inatividade, então uma política opcional de reinício por inatividade/diário se aplica corretamente a elas, em vez de tratar toda sessão recuperada como novinha.

Onde ficam os dados​

O queCaminhoDescrição
Banco SQLite~/.hermes/state.dbTodos os metadados de sessão + mensagens com FTS5
Mensagens de gateway~/.hermes/state.dbSQLite — armazenamento canônico de todas as mensagens de sessão
Índice de roteamento do gatewaytabela gateway_routing em ~/.hermes/state.dbMapeia chaves de sessão para IDs de sessão ativos (metadados de origem, marcas de expiração)
Espelho legado de roteamento~/.hermes/sessions/sessions.jsonEspelho de compatibilidade retroativa do índice de roteamento, escrito quando gateway.write_sessions_json: true (o padrão)

O banco SQLite usa o modo WAL para leitores concorrentes e um único escritor, o que combina bem com a arquitetura multiplataforma do gateway.

O sessions.json não é a lista de sessões

O índice de roteamento do gateway vive na tabela gateway_routing dentro do state.db; o ~/.hermes/sessions/sessions.json é um espelho legado dele, mantido por compatibilidade retroativa (desative com gateway.write_sessions_json: false). Ele mapeia chaves de sessão de mensagens (agent:main:<platform>:...) para IDs de sessão ativos. Ele só contém entradas de gateway/mensagens, então, se você roda uma plataforma de mensagens, vai ver apenas essas (por exemplo, agent:main:whatsapp:dm:...).

Isso é esperado e não significa que suas sessões de CLI estão faltando. O hermes sessions list, o /sessions e o painel todos leem o state.db, que guarda todas as sessões (CLI, TUI e gateway). Os retratos do /save em ~/.hermes/sessions/saved/*.json são exports de conveniência, não o índice.

Se as sessões de CLI genuinamente não aparecem no hermes sessions list, a causa é o state.db não estar recebendo elas — rode hermes sessions repair e fique de olho num aviso ⚠ Session store unavailable na partida da CLI, que significa que a persistência no SQLite falhou naquela execução.

Transcrições JSONL legadas

Sessões criadas antes de o state.db se tornar canônico podem ter arquivos *.jsonl sobrando em ~/.hermes/sessions/. Eles não são mais escritos nem lidos pelo Hermes. Seguro apagar depois de verificar que a sessão correspondente existe no state.db.

Esquema do banco​

Tabelas principais no state.db:

  • sessions — metadados da sessão (id, source, user_id, model, title, marcas de tempo, contagem de tokens). Os títulos têm um índice único (títulos NULL são permitidos, só os não-NULL precisam ser únicos).
  • messages — histórico completo de mensagens (role, content, tool_calls, tool_name, token_count)
  • messages_fts — tabela virtual FTS5 para busca em texto completo no conteúdo das mensagens

Expiração e limpeza de sessões​

Limpeza automática​

  • Sessões de gateway reiniciam automaticamente conforme a política de reinício configurada
  • Antes do reinício, o agente salva memórias e skills da sessão que está expirando
  • Poda automática opcional: quando sessions.auto_prune é true, as sessões encerradas e inativas por sessions.retention_days (padrão 90) são podadas na partida da CLI/gateway
  • Depois de uma poda que realmente removeu linhas, o state.db passa por VACUUM para recuperar espaço em disco, quando pelo menos sessions.min_vacuum_interval_days (padrão 30) se passaram desde o último VACUUM bem-sucedido (o SQLite não encolhe o arquivo num DELETE simples)
  • A poda roda no máximo uma vez a cada sessions.min_interval_hours (padrão 24); a marca de tempo da última execução é rastreada dentro do próprio state.db, então é compartilhada por todos os processos do Hermes no mesmo HERMES_HOME

O padrão é desligado — o histórico de sessões é valioso para a lembrança do session_search, e apagá-lo em silêncio poderia surpreender os usuários. Habilite em ~/.hermes/config.yaml:

sessions:
auto_prune: true # opte por entrar — o padrão é false
retention_days: 90 # mantém as sessões encerradas ativas dentro desta janela
vacuum_after_prune: true # recupera espaço em disco depois de uma varredura de poda
min_vacuum_interval_days: 30 # não reescreve o banco com mais frequência que isso
min_interval_hours: 24 # não repete a varredura com mais frequência que isso

Sessões ativas nunca são podadas automaticamente, seja qual for a idade. As sessões encerradas envelhecem a partir da última mensagem, então uma conversa de vida longa usada recentemente não é apagada só porque começou antes da janela de retenção.

Limpeza manual​

# Poda sessões com mais de 90 dias
hermes sessions prune

# Apaga uma sessão específica
hermes sessions delete <session_id>

# Exporta antes de podar (backup)
hermes sessions export backup.jsonl
hermes sessions prune --older-than 30 --yes
dica

O banco cresce devagar (típico: 10 a 15 MB para centenas de sessões) e o histórico de sessões alimenta a lembrança do session_search em conversas passadas, então a poda automática vem desligada. Habilite se você roda uma carga pesada de gateway/cron em que o state.db está afetando o desempenho de forma sensível (modo de falha observado: um state.db de 384 MB com cerca de 1000 sessões deixando lentas as inserções no FTS5 e a listagem do /resume). Use hermes sessions prune para uma limpeza pontual, sem ligar a varredura automática.