Cron jobs (scheduler do Gateway)¶
Cron vs Heartbeat? Veja Cron vs Heartbeat para orientações sobre quando usar cada um.
Cron é o scheduler integrado do Gateway. Ele persiste jobs, acorda o agente no momento certo e pode, opcionalmente, entregar a saída de volta a um chat.
Se você quer “executar isso toda manhã” ou “cutucar o agente em 20 minutos”, cron é o mecanismo.
Solução de problemas: /automation/troubleshooting
TL;DR¶
- Cron roda dentro do Gateway (não dentro do modelo).
- Jobs persistem em
~/.openclaw/cron/para que reinícios não percam agendas. - Dois estilos de execução:
- Sessão principal: enfileira um evento de sistema e executa no próximo heartbeat.
- Isolado: executa um turno dedicado do agente em
cron:<jobId>, com entrega (anunciar por padrão ou nenhuma). - Wakeups são de primeira classe: um job pode solicitar “acordar agora” vs “próximo heartbeat”.
Início rápido (prático)¶
Crie um lembrete pontual, verifique que ele existe e execute imediatamente:
openclaw cron add \
--name "Reminder" \
--at "2026-02-01T16:00:00Z" \
--session main \
--system-event "Reminder: check the cron docs draft" \
--wake now \
--delete-after-run
openclaw cron list
openclaw cron run <job-id>
openclaw cron runs --id <job-id>
Agende um job isolado recorrente com entrega:
openclaw cron add \
--name "Morning brief" \
--cron "0 7 * * *" \
--tz "America/Los_Angeles" \
--session isolated \
--message "Summarize overnight updates." \
--announce \
--channel slack \
--to "channel:C1234567890"
Equivalentes de tool-call (ferramenta cron do Gateway)¶
Para os formatos JSON canônicos e exemplos, veja Esquema JSON para tool calls.
Onde os cron jobs são armazenados¶
Cron jobs são persistidos no host do Gateway em ~/.openclaw/cron/jobs.json por padrão.
O Gateway carrega o arquivo na memória e o grava de volta quando há alterações, então edições manuais
só são seguras quando o Gateway está parado. Prefira openclaw cron add/edit ou a API de tool call
do cron para alterações.
Visão geral para iniciantes¶
Pense em um cron job como: quando executar + o que fazer.
-
Escolha uma agenda - Lembrete pontual →
schedule.kind = "at"(CLI:--at) - Job recorrente →schedule.kind = "every"ouschedule.kind = "cron"- Se seu timestamp ISO omitir fuso horário, ele é tratado como UTC. -
Escolha onde ele roda -
sessionTarget: "main"→ executa durante o próximo heartbeat com o contexto principal. -sessionTarget: "isolated"→ executa um turno dedicado do agente emcron:<jobId>. -
Escolha o payload - Sessão principal →
payload.kind = "systemEvent"- Sessão isolada →payload.kind = "agentTurn"
Opcional: jobs pontuais (schedule.kind = "at") são excluídos após sucesso por padrão. Defina
deleteAfterRun: false para mantê-los (eles serão desativados após o sucesso).
Conceitos¶
Tarefas¶
Um cron job é um registro armazenado com:
- uma agenda (quando deve executar),
- um payload (o que deve fazer),
- modo de entrega opcional (anunciar ou nenhum).
- vinculação de agente opcional (
agentId): executa o job sob um agente específico; se ausente ou desconhecido, o gateway recorre ao agente padrão.
Jobs são identificados por um jobId estável (usado por CLI/APIs do Gateway).
Em tool calls do agente, jobId é canônico; o legado id é aceito por compatibilidade.
Jobs pontuais se autoexcluem após sucesso por padrão; defina deleteAfterRun: false para mantê-los.
Agendas¶
Cron suporta três tipos de agenda:
at: timestamp pontual viaschedule.at(ISO 8601).every: intervalo fixo (ms).cron: expressão cron de 5 campos com fuso horário IANA opcional.
Expressões cron usam croner. Se um fuso horário for omitido, o fuso horário local
do host do Gateway é usado.
Execução principal vs isolada¶
Jobs da sessão principal (eventos de sistema)¶
Jobs principais enfileiram um evento de sistema e opcionalmente acordam o executor de heartbeat.
Eles devem usar payload.kind = "systemEvent".
wakeMode: "now"(padrão): o evento dispara uma execução imediata de heartbeat.wakeMode: "next-heartbeat": o evento aguarda o próximo heartbeat agendado.
Este é o melhor encaixe quando você quer o prompt normal de heartbeat + contexto da sessão principal. Veja Heartbeat.
Jobs isolados (sessões cron dedicadas)¶
Jobs isolados executam um turno dedicado do agente na sessão cron:<jobId>.
Comportamentos-chave:
- O prompt é prefixado com
[cron:<jobId> <job name>]para rastreabilidade. - Cada execução inicia um id de sessão novo (sem reaproveitar conversa anterior).
- Comportamento padrão: se
deliveryfor omitido, jobs isolados anunciam um resumo (delivery.mode = "announce"). delivery.mode(apenas isolado) escolhe o que acontece:announce: entrega um resumo ao canal alvo e publica um breve resumo na sessão principal.none: apenas interno (sem entrega, sem resumo na sessão principal).wakeModecontrola quando o resumo da sessão principal é publicado:now: heartbeat imediato.next-heartbeat: aguarda o próximo heartbeat agendado.
Use jobs isolados para tarefas ruidosas, frequentes ou “tarefas de fundo” que não devem poluir o histórico do chat principal.
Formatos de payload (o que executa)¶
Dois tipos de payload são suportados:
systemEvent: apenas sessão principal, roteado pelo prompt de heartbeat.agentTurn: apenas sessão isolada, executa um turno dedicado do agente.
Campos comuns de agentTurn:
message: prompt de texto obrigatório.model/thinking: substituições opcionais (veja abaixo).timeoutSeconds: substituição opcional de timeout.
Configuração de entrega (apenas jobs isolados):
delivery.mode:none|announce.delivery.channel:lastou um canal específico.delivery.to: alvo específico do canal (telefone/chat/id do canal).delivery.bestEffort: evita falhar o job se a entrega de anúncio falhar.
A entrega por anúncio suprime envios via ferramentas de mensagens durante a execução; use delivery.channel/delivery.to
para direcionar o chat. Quando delivery.mode = "none", nenhum resumo é publicado na sessão principal.
Se delivery for omitido para jobs isolados, o OpenClaw usa por padrão announce.
Fluxo de entrega por anúncio¶
Quando delivery.mode = "announce", o cron entrega diretamente via adaptadores de canal de saída.
O agente principal não é iniciado para elaborar ou encaminhar a mensagem.
Detalhes de comportamento:
- Conteúdo: a entrega usa os payloads de saída da execução isolada (texto/mídia) com fragmentação normal e formatação do canal.
- Respostas apenas de heartbeat (
HEARTBEAT_OKsem conteúdo real) não são entregues. - Se a execução isolada já enviou uma mensagem ao mesmo alvo via ferramenta de mensagem, a entrega é ignorada para evitar duplicatas.
- Alvos de entrega ausentes ou inválidos falham o job, a menos que
delivery.bestEffort = true. - Um resumo curto é publicado na sessão principal somente quando
delivery.mode = "announce". - O resumo da sessão principal respeita
wakeMode:nowdispara um heartbeat imediato enext-heartbeataguarda o próximo heartbeat agendado.
Substituições de modelo e thinking¶
Jobs isolados (agentTurn) podem substituir o modelo e o nível de thinking:
model: string de provedor/modelo (ex.:anthropic/claude-sonnet-4-20250514) ou alias (ex.:opus)thinking: nível de thinking (off,minimal,low,medium,high,xhigh; apenas modelos GPT-5.2 + Codex)
Nota: Você pode definir model em jobs da sessão principal também, mas isso altera o modelo compartilhado da
sessão principal. Recomendamos substituições de modelo apenas para jobs isolados para evitar
mudanças inesperadas de contexto.
Prioridade de resolução:
- Substituição no payload do job (mais alta)
- Padrões específicos do hook (ex.:
hooks.gmail.model) - Padrão da configuração do agente
Entrega (canal + alvo)¶
Jobs isolados podem entregar a saída a um canal via a configuração de nível superior delivery:
delivery.mode:announce(entregar um resumo) ounone.delivery.channel:whatsapp/telegram/discord/slack/mattermost(plugin) /signal/imessage/last.delivery.to: alvo de destinatário específico do canal.
A configuração de entrega é válida apenas para jobs isolados (sessionTarget: "isolated").
Se delivery.channel ou delivery.to for omitido, o cron pode recorrer à “última rota” da sessão principal
(o último local onde o agente respondeu).
Lembretes de formato de alvo:
- Alvos de Slack/Discord/Mattermost (plugin) devem usar prefixos explícitos (ex.:
channel:<id>,user:<id>) para evitar ambiguidade. - Tópicos do Telegram devem usar o formato
:topic:(veja abaixo).
Alvos de entrega do Telegram (tópicos / threads de fórum)¶
O Telegram suporta tópicos de fórum via message_thread_id. Para entrega por cron, você pode codificar
o tópico/thread no campo to:
-1001234567890(apenas id do chat)-1001234567890:topic:123(preferido: marcador explícito de tópico)-1001234567890:123(atalho: sufixo numérico)
Alvos prefixados como telegram:... / telegram:group:... também são aceitos:
telegram:group:-1001234567890:topic:123
Esquema JSON para tool calls¶
Use estes formatos ao chamar diretamente as ferramentas cron.* do Gateway (tool calls do agente ou RPC).
As flags da CLI aceitam durações humanas como 20m, mas tool calls devem usar uma string ISO 8601
para schedule.at e milissegundos para schedule.everyMs.
Parâmetros de cron.add¶
Job pontual, sessão principal (evento de sistema):
{
"name": "Reminder",
"schedule": { "kind": "at", "at": "2026-02-01T16:00:00Z" },
"sessionTarget": "main",
"wakeMode": "now",
"payload": { "kind": "systemEvent", "text": "Reminder text" },
"deleteAfterRun": true
}
Job recorrente, isolado com entrega:
{
"name": "Morning brief",
"schedule": { "kind": "cron", "expr": "0 7 * * *", "tz": "America/Los_Angeles" },
"sessionTarget": "isolated",
"wakeMode": "next-heartbeat",
"payload": {
"kind": "agentTurn",
"message": "Summarize overnight updates."
},
"delivery": {
"mode": "announce",
"channel": "slack",
"to": "channel:C1234567890",
"bestEffort": true
}
}
Notas:
schedule.kind:at(at),every(everyMs), oucron(expr, opcionaltz).schedule.ataceita ISO 8601 (fuso horário opcional; tratado como UTC quando omitido).everyMsé em milissegundos.sessionTargetdeve ser"main"ou"isolated"e deve corresponder apayload.kind.- Campos opcionais:
agentId,description,enabled,deleteAfterRun(padrão true paraat),delivery. wakeModeusa por padrão"now"quando omitido.
Parâmetros de cron.update¶
{
"jobId": "job-123",
"patch": {
"enabled": false,
"schedule": { "kind": "every", "everyMs": 3600000 }
}
}
Notas:
jobIdé canônico;idé aceito por compatibilidade.- Use
agentId: nullno patch para limpar uma vinculação de agente.
Parâmetros de cron.run e cron.remove¶
{ "jobId": "job-123", "mode": "force" }
{ "jobId": "job-123" }
Armazenamento e histórico¶
- Armazenamento de jobs:
~/.openclaw/cron/jobs.json(JSON gerenciado pelo Gateway). - Histórico de execuções:
~/.openclaw/cron/runs/<jobId>.jsonl(JSONL, auto-podado). - Substituir o caminho de armazenamento:
cron.storena configuração.
Configuração¶
{
cron: {
enabled: true, // default true
store: "~/.openclaw/cron/jobs.json",
maxConcurrentRuns: 1, // default 1
},
}
Desativar o cron completamente:
cron.enabled: false(config)OPENCLAW_SKIP_CRON=1(env)
Início rápido da CLI¶
Lembrete pontual (ISO UTC, autoexclusão após sucesso):
openclaw cron add \
--name "Send reminder" \
--at "2026-01-12T18:00:00Z" \
--session main \
--system-event "Reminder: submit expense report." \
--wake now \
--delete-after-run
Lembrete pontual (sessão principal, acordar imediatamente):
openclaw cron add \
--name "Calendar check" \
--at "20m" \
--session main \
--system-event "Next heartbeat: check calendar." \
--wake now
Job isolado recorrente (anunciar no WhatsApp):
openclaw cron add \
--name "Morning status" \
--cron "0 7 * * *" \
--tz "America/Los_Angeles" \
--session isolated \
--message "Summarize inbox + calendar for today." \
--announce \
--channel whatsapp \
--to "+15551234567"
Job isolado recorrente (entregar a um tópico do Telegram):
openclaw cron add \
--name "Nightly summary (topic)" \
--cron "0 22 * * *" \
--tz "America/Los_Angeles" \
--session isolated \
--message "Summarize today; send to the nightly topic." \
--announce \
--channel telegram \
--to "-1001234567890:topic:123"
Job isolado com substituição de modelo e thinking:
openclaw cron add \
--name "Deep analysis" \
--cron "0 6 * * 1" \
--tz "America/Los_Angeles" \
--session isolated \
--message "Weekly deep analysis of project progress." \
--model "opus" \
--thinking high \
--announce \
--channel whatsapp \
--to "+15551234567"
Seleção de agente (configurações com múltiplos agentes):
# Pin a job to agent "ops" (falls back to default if that agent is missing)
openclaw cron add --name "Ops sweep" --cron "0 6 * * *" --session isolated --message "Check ops queue" --agent ops
# Switch or clear the agent on an existing job
openclaw cron edit <jobId> --agent ops
openclaw cron edit <jobId> --clear-agent
Execução manual (forçar é o padrão; use --due para executar apenas quando devido):
openclaw cron run <jobId>
openclaw cron run <jobId> --due
Editar um job existente (patch de campos):
openclaw cron edit <jobId> \
--message "Updated prompt" \
--model "opus" \
--thinking low
Histórico de execuções:
openclaw cron runs --id <jobId> --limit 50
Evento de sistema imediato sem criar um job:
openclaw system event --mode now --text "Next heartbeat: check battery."
Superfície da API do Gateway¶
cron.list,cron.status,cron.add,cron.update,cron.removecron.run(forçar ou devido),cron.runsPara eventos de sistema imediatos sem um job, useopenclaw system event.
Solução de problemas¶
“Nada executa”¶
- Verifique se o cron está habilitado:
cron.enabledeOPENCLAW_SKIP_CRON. - Verifique se o Gateway está rodando continuamente (o cron roda dentro do processo do Gateway).
- Para agendas
cron: confirme o fuso horário (--tz) vs o fuso do host.
Um job recorrente continua atrasando após falhas¶
- O OpenClaw aplica backoff exponencial de retry para jobs recorrentes após erros consecutivos: 30s, 1m, 5m, 15m, depois 60m entre tentativas.
- O backoff é redefinido automaticamente após a próxima execução bem-sucedida.
- Jobs pontuais (
at) são desativados após uma execução terminal (ok,errorouskipped) e não fazem retry.
O Telegram entrega no lugar errado¶
- Para tópicos de fórum, use
-100…:topic:<id>para que fique explícito e inequívoco. - Se você vir prefixos
telegram:...nos logs ou em alvos de “última rota” armazenados, isso é normal; a entrega por cron os aceita e ainda analisa corretamente os IDs de tópico.