Gerencia sessões do sistema Ravi. Use quando o usuário quiser:
- Listar, ver detalhes ou renomear sessões
- Resetar ou deletar sessões
- Configurar modelo ou thinking level por sessão
- Limpar sessões inativas com dry-run e filtros explícitos
- Criar sessões efêmeras com TTL
- Estender, manter ou excluir sessões efêmeras
- Enviar prompts, perguntas ou comandos entre sessões
- Ler histórico de mensagens de uma sessão
- Inspecionar trace SQLite de uma sessão para incidentes de runtime/canal
- A...
9 stars
0 votes
0 copies
0 views
Added October 20, 2026
ai-agentsgobashsql
Works with
terminal
cli
Security analysis
B75/100
criticalImpersonates system messages to override safety constraints
Installs into .claude/skills of the current project.
Are you the author of Sessions?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/filipexyz-sessions)
---
name: sessions
description: |
Gerencia sessões do sistema Ravi. Use quando o usuário quiser:
- Listar, ver detalhes ou renomear sessões
- Resetar ou deletar sessões
- Configurar modelo ou thinking level por sessão
- Limpar sessões inativas com dry-run e filtros explícitos
- Criar sessões efêmeras com TTL
- Estender, manter ou excluir sessões efêmeras
- Enviar prompts, perguntas ou comandos entre sessões
- Ler histórico de mensagens de uma sessão
- Inspecionar trace SQLite de uma sessão para incidentes de runtime/canal
- Atachar um chat como output target de uma sessão
- Atachar múltiplos chats numa mesma sessão sem fork de histórico
---
# Sessions Manager
> Verbos: AGIR (mandar a chat ou sessão) · RELATAR (followups). Compõe com: triggers, whatsapp.
> Solução com mais de uma peça? `ravi skills show solucoes` primeiro.
Sessões são conversas persistentes entre agents e usuários. Cada sessão tem um nome único, um agent associado, e pode ter canal de saída (WhatsApp, Matrix, etc).
Sessões são a superfície de comunicação do Ravi. Não são o task runtime. Se o trabalho precisa de dono, progresso e estado terminal, use `ravi tasks ...`. Se a pergunta é medir regressão ou comparar comportamento, use `ravi eval ...`.
## Contrato Do CLI
Rode com `--json` sempre que for decidir programaticamente. Com `--json`, falha sai em envelope `{success:false, op, error:{code, message, retryable, suggestedAction, acceptedFlags?}}`.
Taxonomia de saída:
- `0` sucesso.
- `1` erro de execução (ex.: `SESSION_NOT_FOUND`, `MESSAGE_NOT_FOUND`). `SESSION_NOT_FOUND` NÃO traz `suggestions` de propósito: o isolamento de escopo mascara sessão não-autorizada como not-found, e sugerir nomes reais vazaria sessões de outros escopos. Liste as visíveis com `ravi sessions list --json`.
- `2` erro de uso (flag/argumento inválido). O envelope traz `acceptedFlags`: corrija a chamada, não insista na mesma sintaxe.
- `3` freio de escrita — não é erro. Nada foi gravado; o envelope traz `dryRun:true` e `plan`. Revise e repita com `--execute`.
Onde o freio existe hoje: `reset` (contexto é irrecuperável), `delete` (permanente), `delete-message`, `edit-message` (mutação irreversível no canal) e runtime `follow-up`/`rollback`/`fork` (disparam trabalho ou alteram histórico) são dry-run por default e exigem `--execute`. `prune` já era dry-run nativo com `--execute` e mantém seu payload rico de candidatos (exit 0 no preview). Mensagens rotineiras, configurações reversíveis e runtime `interrupt`/`steer` continuam imediatos; o stop de emergência não ganha uma confirmação que aumentaria o dano.
Compact mode: `sessions list` aceita `--fields a,b,c` (ex.: `--fields name,agentId,updatedAt`).
Checklist antes de responder sobre sessões:
- Tratei exit 3 como freio (revisei o `plan`) e não como falha?
- Chequei `ravi sessions list --json` antes de declarar que uma sessão não existe?
## Tipos de Sessão
- **Permanent** (padrão): Sessão normal, sem expiração.
- **Ephemeral**: Sessão com TTL (time-to-live). Expira automaticamente após o tempo definido. 10 minutos antes de expirar, o agent recebe um aviso com comandos CLI para estender, manter ou excluir.
## Comandos
### Listagem e Info
```bash
# Listar todas as sessões (mostra tipo e data de expiração)
ravi sessions list
# Filtrar por agent
ravi sessions list --agent <id>
# Listar só efêmeras
ravi sessions list --ephemeral
# Ver detalhes de uma sessão
ravi sessions info <name>
# Ler histórico durável da sessão (normalizado, sem tool calls; atravessa restarts/resets de provider)
ravi sessions read <name> [-n count]
# Recap computado e limitado de uma sessão (identidade, goal, cauda recente; sem MEMORY.md)
ravi sessions recap <name> [--json]
# Inspecionar timeline operacional persistida em SQLite
ravi sessions trace <name> --since 2h --explain
```
### Gerenciamento
```bash
# Renomear o nome canonico da sessao (sessions.name)
ravi sessions rename <name> <novo-nome-canonico>
# Definir label humano/display-only
ravi sessions set-display <name> "Novo Nome Humano"
# Definir modelo override (vence agent/global/env no próximo turno)
ravi sessions set-model <name> <model>
# Definir provider override (eixo independente do model)
ravi sessions set-provider <name> <provider|clear>
# Defaults globais do próximo turno (sem restart; env fica só fallback)
# ravi settings set runtime.defaultProvider claude
# ravi settings set runtime.defaultModel opus
# Definir thinking level
ravi sessions set-thinking <name> <level>
# Resetar sessão (limpa conversa, mantém config; sem --execute é dry-run, exit 3)
ravi sessions reset <name> --execute
# Deletar sessão permanentemente (abort + delete; sem --execute é dry-run, exit 3)
ravi sessions delete <name> --execute
# Preview de limpeza por inatividade (não apaga nada)
ravi sessions prune --inactive-for 2d --json
# Deletar sessões inativas há mais de 2 dias
ravi sessions prune --inactive-for 2d --execute
```
`prune` usa `updated_at`/última atividade da sessão, não `created_at`.
Isso evita apagar uma sessão antiga que teve atividade recente.
Filtros úteis:
```bash
ravi sessions prune --inactive-for 1d --agent dev
ravi sessions prune --inactive-for 2d --name-prefix task-
ravi sessions prune --inactive-for 12h --ephemeral
```
Sem `--execute`, `prune` é sempre dry-run. Use o dry-run antes de apagar em lote.
### Attach (multiple chats, one history)
**Diferença chave vs routes:** `routes` decide qual *agent* atende um chat; `attach` decide quais chats alimentam uma sessão. Cada inbound responde automaticamente no próprio chat ou thread. O default só é usado por turnos sem origem inbound.
**Regra crítica:** `sessions attach` NÃO cria, corrige nem troca a route do chat. Use attach apenas quando a route já resolve para o agent correto, ou depois de criar uma route explícita para esse agent. Para chat novo/rota errada, configure a rota primeiro; se quiser forçar a mesma sessão já na route, use `ravi instances routes add <instance> <pattern> <agent> --session <session>`.
Ver spec `sessions/attach` pro modelo completo.
```bash
# Listar chats atachados e qual é o output default
ravi sessions subscriptions <session>
# Atachar um chat e selecioná-lo como output default da sessão
ravi sessions attach <session> --chat <chat-id> [--reason "..."]
# Desatachar subscription/output
ravi sessions detach <session> --chat <chat-id>
```
**Receitas operacionais (validadas em produção):**
1. **Responder em outro grupo com a mesma sessão.** Caso típico: você está falando com `dev` no grupo de teste, mas quer que o resultado apareça no grupo principal.
- `sessions attach dev --chat <chat-id-do-grupo-principal>`
- Inbounds continuam respondendo no próprio chat. O grupo principal vira o default apenas para turnos sem inbound.
- O comando imprime o hint de detach para desligar esse output depois.
2. **Unificar histórico de N grupos numa sessão.** Caso: dev atende o grupo `ravi - dev` e você quer que o mesmo dev também receba inbound de `ravi - dev - test`.
- Primeiro garanta que a route do grupo novo aponta para o agent `dev`: `ravi instances routes add <instance> "group:<id>" dev --priority 10`.
- Se a intenção é fixar a sessão canônica já na route, prefira: `ravi instances routes add <instance> "group:<id>" dev --session dev --priority 10`.
- Se o grupo novo já criou uma sessão paralela (`dev-2`, vazia), apague a paralela (`sessions delete dev-2 --execute`) antes de consolidar.
- Depois use `sessions attach dev --chat <chat-id-do-test>` para ligar o chat à sessão existente.
3. **Migrar grupo de um agent pra outro (sem unificar sessão).** Caso: grupo nasceu na sessão de onboarding (auto-criada pelo default agent da instance), você quer mover pro agent `dev` com sessão SEPARADA.
- `ravi instances routes add <instance> group:<id> <novo-agent> --priority 10`
- O `routes add` faz cleanup automático de session conflitante (chama `Cleaned N conflicting session(s)`).
- Próxima inbound: matchRoute → novo agent → cria sessão nova pra esse (agent, grupo).
- Não confunda com attach — essa NÃO compartilha histórico.
**Como compõe na prática (sequence diagram resumido):**
```
inbound chega ─► consumer normaliza chat
─► matchRoute resolve agent + session_key candidato
─► [Fase 2] consumer.findSessionByAttachedChat(chat_id)
│ se subscription existe ─► matched.sessionKey = subscription.sessionKey
│ (subscription override prevalece sobre matchRoute)
─► policy checks
─► commitMatchedRoute + attachChatToSession (idempotente)
─► dispatch turn na sessão escolhida
─► runtime gera resposta
─► resolveSessionOutputTarget:
1. inbound com source inscrito → source
2. turno sem inbound → output default
3. source não inscrito ou nenhum destino → fail closed
─► gateway emite no target resolvido
```
**Anti-patterns:**
- ❌ Adicionar route pra "trocar destino" quando o chat já está atachado em outra sessão. A subscription override puxa o inbound de volta. Use detach/delete da sessão antiga antes, ou attach explícito na nova.
- ❌ Usar `sessions attach` como se ele configurasse route. Attach não muda o agent que atende o chat; ele só liga o chat a uma sessão quando a route/agent já está correta.
- ❌ Tentar usar `focus` pra responder em outro chat. Focus foi removido; `attach` é o primitive que escolhe o chat de output.
- ❌ Deixar inbound-route bookkeeping roubar o default escolhido pelo operador.
- ❌ Esperar que `attach` sozinho mude o agent que atende o chat. Attach decide sessão; agent vem da route ou do default da instance.
**Quando route vs attach:**
| Você quer | Use |
|-----------|-----|
| Outro agent atender o chat (histórico isolado) | `instances routes add` |
| Mesma sessão em chat cuja route já aponta para o agent correto | `sessions attach` |
| Mesma sessão em chat novo ou com route errada | `instances routes add ... --session <name>` e depois `sessions attach` |
| Forçar uma sessão específica num chat | `routes add ... --session <name>` (redirect estático) |
### Sessões Efêmeras
```bash
# Tornar sessão efêmera com TTL (ex: 5h, 30m, 1d)
ravi sessions set-ttl <name> <duration>
# Estender TTL de uma sessão efêmera (+5h default)
ravi sessions extend <name> [duration]
# Tornar sessão efêmera em permanente
ravi sessions keep <name>
```
**Fluxo automático:**
1. Sessão criada com `set-ttl` recebe TTL
2. 10 min antes de expirar, o agent recebe aviso via `[System] Inform:` com os comandos CLI
3. O agent pode executar `extend`, `keep`, ou `delete`
4. Sem ação → sessão é automaticamente deletada pelo runner
### Session Followups
Use `sessions followups` para cadências de inatividade em sessões/chats/listas. Isso é diferente de cron: `--every` conta a partir da última atividade externa relevante.
```bash
# Criar followup simples
ravi sessions followups add "Follow-up ravi-dev" --target-chat <chat-id> --every 15m --message "Revise o contexto e faça follow-up curto."
# Criar cadência progressiva
ravi sessions followups add "Follow-up ravi-dev" --target-chat <chat-id> \
--step "15m=Revise o contexto e faça um follow-up curto." \
--step "30m=Estude o próximo passo relevante e recomende uma ação concreta."
# Editar uma cadência existente sem recriar
ravi sessions followups update <id> \
--step "15m=Revise o contexto e faça um follow-up curto." \
--step "30m=Estude o próximo passo relevante e recomende uma ação concreta."
# Atualizar mensagem de cadência single-step
ravi sessions followups update <id> --message "Nova mensagem."
```
Regras:
- Use `update`, não recrie/pausa cadência, quando a intenção é editar nome, descrição, barrier, mensagem ou steps.
- Em cadências progressivas, `--step` substitui a lista inteira de steps. Não use `--message` para tentar editar o segundo step.
- `update` preserva `nextRunAt` por padrão; use `--recalculate-next` só quando quiser recalcular a próxima execução.
### Comunicação Inter-Sessão
```bash
# Enviar prompt/contexto
ravi sessions send <name> "mensagem" [-w] [-a agent] [-i]
# -w: espera e streama a resposta
# -a: cria sessão com esse agent se não existir
# -i: modo interativo (loop)
# Perguntar algo (fire-and-forget, agent pergunta no chat se não souber)
ravi sessions ask <name> "pergunta" [sender]
# Responder uma pergunta de outra sessão (agent NUNCA silencia)
ravi sessions answer <name> "resposta" [sender]
# Executar comando (fire-and-forget, agent executa sem responder)
ravi sessions execute <name> "tarefa"
# Informar algo (fire-and-forget, agent pode silenciar se irrelevante)
ravi sessions inform <name> "info"
```
### Threads do Slack (orquestração)
A sessão de um DM ou canal do Slack orquestra as threads que abre; cada thread é uma sessão filha. Os comandos inferem a sessão atual.
```bash
# Abrir uma thread nova na raiz do canal; a mensagem é a raiz visível e a primeira instrução da filha
ravi sessions create-thread "<mensagem inicial>" [--model <model>]
# Na sessão do canal: listar as threads (abertas; --all inclui fechadas) e mandar instruções para uma
ravi sessions threads [--all] --json
ravi sessions thread-send <sessão-da-thread|request-id|thread-ts> "instruções"
# Na thread: avisar a sessão do canal sem fechar, e fechar (com ou sem resultado)
ravi sessions report "progresso, bloqueio ou decisão"
ravi sessions close-thread [--return "resultado"]
```
A raiz da thread aparece no canal como um card: a primeira linha da mensagem inicial é o título (escreva um título curto nela), o resto vira um resumo, e a mensagem inteira abre a thread quando não cabe no card. O card mostra quem pediu (quem escreveu o turno; nos turnos do operador, o contato dono) e o status, e muda sozinho com `report`, `close-thread` e quando `thread-send` reabre a thread.
Progresso e resultado chegam na sessão do canal como `[System] Inform: Slack thread "<título>" (<sessão-da-thread>) ...`. `thread-send` reabre uma thread fechada; a filha responde dentro da thread.
`sessions send` envia prompt/contexto para a sessão do agent; ele não publica texto visível diretamente em WhatsApp, Telegram, Matrix ou outro canal externo. Se o objetivo é falar com uma pessoa/canal, deixe a sessão responder normalmente ou use uma CLI explícita de canal/mídia/outbound apropriada.
### Session Trace
Use `ravi sessions trace` quando precisar entender uma sessão real ponta a ponta:
inbound de canal, routing, prompt publish, decisões de dispatch, request final
do adapter, tools, resposta, delivery e falhas.
SQLite (`ravi.db`) é a fonte canônica do trace. NATS/logs são apoio para debug
ao vivo, não a fonte primária para reconstruir incidente.
```bash
# Golden path de incidente
ravi sessions trace <name> --since 2h --explain
# Filtros úteis
ravi sessions trace <name> --turn <turn_id> --explain
ravi sessions trace <name> --run <run_id>
ravi sessions trace <name> --message <source_message_id> --explain
ravi sessions trace <name> --correlation <correlation_id> --raw --explain
# Cortes de leitura
ravi sessions trace <name> --only adapter
ravi sessions trace <name> --only tools
ravi sessions trace <name> --only delivery
ravi sessions trace <name> --only dispatch
ravi sessions trace <name> --only turn
ravi sessions trace <name> --since 30m --limit 40
ravi sessions trace <name> --json
# Payloads grandes só quando necessário
ravi sessions trace <name> --show-system-prompt
ravi sessions trace <name> --turn <turn_id> --show-user-prompt
ravi sessions trace <name> --turn <turn_id> --raw
```
`--show-system-prompt` resolve o system prompt mais recente da sessão e não
depende do `turn` estar visível no recorte/limit. User prompt e raw request
continuam escopados a turn/request.
Leitura rápida:
- `channel.message.received` = inbound chegou no Ravi.
- `route.resolved` = rota escolheu sessão e agent.
- `prompt.published` = prompt entrou no stream da sessão.
- `dispatch.*` = cold start, push em sessão viva, queue, interrupt, restart ou task barrier.
- `runtime.start` = runtime começou ou falhou antes do provider.
- `adapter.request` = Ravi montou a request final para o provider. Se existe, chegou no handoff.
- `tool.start` / `tool.end` = atividade de tool do provider.
- `assistant.message` = texto do assistant recebido do provider.
- `response.emitted` = Ravi emitiu resposta para o gateway.
- `delivery.*` = gateway observou delivered, failed, dropped ou outro status.
- `turn.complete` / `turn.failed` / `turn.interrupted` = estado terminal do turno.
- `session.stalled` = evento legado do watchdog de runtime; hoje deve aparecer só em traces históricos. Código novo deve fechar o turno via evento terminal do provider.
Achados comuns do `--explain`:
- `prompt-without-adapter-request`: prompt nao chegou no handoff do provider; olhar dispatch, debounce, task barrier ou runtime startup.
- `adapter-request-without-terminal-turn`: request foi criada, mas nao houve terminal turn; olhar provider/runtime apos handoff.
- `response-without-delivery`: resposta saiu do runtime mas nao teve delivery observado.
- `delivery-failed` / `delivery-dropped`: falha ou drop no outbound; olhar payload de delivery e target.
- `interruption-or-abort`: houve interrupt/abort; ler `abortReason`, `session.abort` e `dispatch.interrupt_requested`.
- `runtime-stalled`: trace historico contem `session.stalled` do watchdog removido; verificar se foi produzido por daemon antigo.
- `timeout`: timeout interrompeu a sessao/turno.
- `resume-disabled-with-provider-session`: havia provider session id mas `resume=false`; investigar reset/delete/fork/troca de provider ou modelo.
- `tool-start-without-end`: tool iniciou e nao completou no trace.
- `system-prompt-changed`: hashes de system prompt mudaram entre turns.
Golden path SDE para "agent viu a mensagem mas nao respondeu":
1. `ravi sessions trace <name> --since 2h --explain`
2. `ravi sessions trace <name> --message <source_message_id> --explain`
3. `ravi sessions trace <name> --turn <turn_id> --explain`
Classifique pela ultima linha confiavel:
- sem `channel.message.received`: inbound nao chegou ou janela/sessao errada.
- `channel.message.received` sem `route.resolved`: routing/contact resolution.
- `route.resolved` sem `prompt.published`: publish no stream da sessao.
- `prompt.published` sem `adapter.request`: dispatch, task barrier, debounce, concorrencia ou runtime startup.
- `adapter.request` sem terminal turn: provider/runtime apos handoff.
- `session.stalled`: trace histórico do watchdog removido; se aparecer em evento novo, há daemon antigo rodando.
- `assistant.message` sem `response.emitted`: resposta silenciosa, suppressao ou interrupcao.
- `response.emitted` sem `delivery.*`: gateway/outbound observation.
- `delivery.failed` / `delivery.dropped`: entrega final no canal.
Para abort/context loss, procure `session.abort`, `session.timeout`,
`turn.interrupted`, `provider_session_id_before`, `provider_session_id_after` e
hash de system prompt. `resume=false` com provider session id existente e
suspeito, exceto se reset/delete/fork/troca de provider/modelo/capability
explicar.
Use placeholders em runbooks e issues (`<name>`, `<turn_id>`, `<message_id>`).
Nao cole telefones reais, ids de grupo/chat, prompts de cliente, context keys,
tokens ou provider session ids em documentacao compartilhada.
## Notas
- **Reset vs Delete**: `reset` limpa a conversa mas mantém nome/routing/config. `delete` remove a sessão inteira.
- **Session names**: nomes canonicos unicos usados em routing, historico e topicos NATS. Use um token sem espacos, pontos (`.`), `*` ou `>`. `sessions rename` muda esse nome canonico e atualiza rotas que apontavam para o nome antigo.
- **Display labels**: labels humanos vivem em `display_name`. Use `sessions set-display` para nomes com espaco, acentos ou contexto visual; isso nao altera routing nem historico.
- **Source automático**: Todos os comandos de comunicação incluem source (channel/chatId) automaticamente — o agent sabe onde responder.
- **`send` vs `inform`**: `send` é a opção mais geral e pode esperar resposta com `-w`; `inform` é fogo-e-esqueça explícito para contexto.
- **Isolamento de contexto**: `sessions read` deve recuperar apenas a sessão atual. Nunca use histórico de outro grupo/DM como fallback para responder uma sessão fria.