跳转到主要内容
Cron 是 Gateway 网关内置的调度器。它会持久化任务,在合适时间唤醒智能体,并可将输出投递到聊天渠道、webhook,或不投递到任何地方。

快速开始

1

添加一次性提醒

openclaw cron create "2027-02-01T16:00:00Z" \
  --name "Reminder" \
  --session main \
  --system-event "Reminder: check the cron docs draft" \
  --wake now \
  --delete-after-run
2

检查你的任务

openclaw cron list
openclaw cron get <job-id>
openclaw cron show <job-id>
3

查看运行历史

openclaw cron runs --id <job-id>

cron 如何工作

  • Cron 在 Gateway 网关进程内运行,而不是在模型内运行。Gateway 网关必须保持运行,计划才会触发。
  • 任务定义、运行时状态和运行历史会持久化到 OpenClaw 的共享 SQLite 状态数据库中,因此重启不会丢失计划。
  • 每次 cron 执行都会创建一条后台任务记录。
  • 一次性任务(--at)默认会在成功后自动删除;传入 --keep-after-run 可保留它们。
  • 单次运行的挂钟时间预算:设置时使用 --timeout-seconds。否则,隔离/分离的智能体轮次任务会先受 cron 自身 60 分钟 watchdog 限制,随后底层智能体轮次超时(agents.defaults.timeoutSeconds,默认 48 小时)才可能适用;命令任务默认为 10 分钟。
  • Gateway 网关启动时,逾期的隔离智能体轮次任务会被重新调度,而不是立即重放,从而避免模型/工具引导工作进入渠道连接窗口。
  • 如果你通过系统 cron 或其他外部调度器驱动 openclaw agent,即使 CLI 已经处理 SIGTERM/SIGINT,也要用硬终止升级机制包装它。Gateway 网关托管的运行会请求 Gateway 网关中止已接受的运行;本地和嵌入式回退运行会收到相同的中止信号。对于 GNU timeout,优先使用 timeout -k 60 600 openclaw agent ...,而不是普通的 timeout 600 ... —— 如果进程无法及时排空,-k 值就是兜底。对于 systemd 单元,使用带宽限窗口(TimeoutStopSec)的 SIGTERM 停止信号,然后再执行最终终止。当原始 Gateway 网关运行仍处于活动状态时复用 --run-id,重复运行会被报告为正在进行,而不是启动第二次运行。
  • 隔离运行会尽力在完成时关闭其 cron:<jobId> 会话跟踪的浏览器标签页/进程,并通过与主会话和自定义会话运行相同的共享清理路径,释放为该任务创建的任何内置 MCP 运行时实例。清理失败会被忽略,因此 cron 结果仍然优先。
  • 拥有狭窄 cron 自清理授权的隔离运行可以读取调度器状态、只包含自身任务的自过滤列表,以及该任务的运行历史,并且只能移除自身任务。
  • 隔离运行会防范过期确认回复:如果第一个结果只是临时状态更新(on itpulling everything together 和类似提示),并且没有后代子智能体仍负责最终答案,OpenClaw 会在投递前重新提示一次以获取实际结果。
  • 结构化执行拒绝元数据(包括 node-host UNAVAILABLE 包装,其嵌套错误以 SYSTEM_RUN_DENIEDINVALID_REQUEST 开头)会被识别,因此被阻止的命令不会被报告为绿色运行,同时普通助手正文不会被误判为拒绝。
  • 即使没有回复载荷,运行级智能体失败也会计为任务错误,因此模型/提供商失败会递增错误计数器并触发失败通知,而不是将任务清除为成功。
  • 当任务达到 timeoutSeconds 时,cron 会中止运行并给它一个短暂的清理窗口。如果它没有排空,Gateway 网关拥有的清理会在 cron 记录超时前强制清除该运行的会话所有权,因此排队的聊天工作不会卡在过期的处理中会话后面。
  • 设置/启动停滞会获得特定阶段的超时(例如 cron: isolated agent setup timed out before runner startcron: isolated agent run stalled before execution start (last phase: context-engine))。这些 watchdog 覆盖嵌入式和 CLI 托管的提供商,即使在其外部 CLI 进程启动前也会生效,并且会独立于较长的 timeoutSeconds 值进行封顶,因此冷启动/凭证/上下文故障会快速暴露。
Cron 任务对账首先由运行时拥有,其次由持久历史支撑:只要 cron 运行时仍跟踪该任务为正在运行,活动 cron 任务就会保持活动,即使旧的子会话行仍然存在。一旦运行时停止拥有该任务并且 5 分钟宽限窗口过期,维护检查会查看持久化运行日志和任务状态,匹配 cron:<jobId>:<startedAt> 运行。那里的终止结果会最终确定任务账本;否则 Gateway 网关拥有的维护可以将任务标记为 lost。离线 CLI 审计可以从持久历史恢复,但它自身空的进程内活动任务集合不能证明 Gateway 网关拥有的运行已经消失。

计划类型

种类CLI 标志描述
at--at一次性时间戳(ISO 8601 或类似 20m 的相对时间)
every--every固定间隔(10m1h1d
cron--cron5 字段或 6 字段 cron 表达式,可选 --tz
on-exit--on-exit监听的命令退出时触发一次(事件触发器;可跨轮次清理保留;可选 --on-exit-cwd
没有时区的时间戳会被视为 UTC。添加 --tz America/New_York 可在该 IANA 时区解释不带偏移量的 --at 日期时间,或评估 cron 表达式。没有 --tz 的 cron 表达式使用 Gateway 网关主机时区。--tz 不能与 --every--on-exit 一起使用。 整点重复表达式(分钟为 0 且小时字段为通配符)会自动错开最多 5 分钟,以减少负载峰值。使用 --exact 可强制精确计时,或使用 --stagger 30s 指定显式窗口(仅 cron 计划)。

日期和星期使用 OR 逻辑

Cron 表达式由 croner 解析。当日期字段和星期字段都不是通配符时,croner 会在任一字段匹配时匹配,而不是要求两者都匹配。这是标准 Vixie cron 行为。
# Intended: "9 AM on the 15th, only if it's a Monday"
# Actual:   "9 AM on every 15th, AND 9 AM on every Monday"
0 9 15 * 1
这会导致每月大约触发 5-6 次,而不是每月 0-1 次。若要求两个条件同时满足,请使用 croner 的 + 星期修饰符(0 9 15 * +1),或按一个字段调度,并在任务的提示或命令中保护另一个字段。

载荷

每个任务都只携带一种载荷类型,由标志选择:
载荷标志运行
系统事件--system-event <text>入队到主会话,本身不调用模型
智能体消息--message <text>模型支持的智能体轮次
命令--command <shell>--command-argv <json>Gateway 网关主机上的 shell/进程,不调用模型

智能体轮次选项

--message
string
必填
提示文本(隔离/当前/自定义会话任务必需)。
--model
string
模型覆盖;必须解析为允许的模型,否则运行会因验证错误而失败。
--fallbacks
string
每任务回退模型列表,例如 --fallbacks openai/gpt-5.5,openrouter/meta-llama/llama-3.3-70b-instruct:free。传入 --fallbacks "" 可执行没有回退的严格运行。
--clear-fallbacks
boolean
cron edit 上,移除每任务回退覆盖,使任务遵循配置的回退优先级。不能与 --fallbacks 组合使用。
--clear-model
boolean
cron edit 上,移除每任务模型覆盖,使任务遵循常规 cron 模型优先级(已存储的 cron 会话覆盖,否则为智能体/默认模型)。不能与 --model 组合使用。
--thinking
string
Thinking 级别覆盖(off|minimal|low|medium|high|xhigh|adaptive|max)。
--clear-thinking
boolean
cron edit 上,移除每任务 thinking 覆盖。不能与 --thinking 组合使用。
--light-context
boolean
跳过工作区引导文件注入。
--tools
string
限制任务可使用的工具,例如 --tools exec,read
--model 设置任务的主模型;它不会替换会话 /model 覆盖,因此已配置的回退链仍会应用在它之上。无法解析或不允许的模型会让运行以明确的验证错误失败,而不是静默回退到默认值。如果任务有 --model 但没有显式或已配置的回退列表,OpenClaw 会传递一个空的回退覆盖,而不是静默附加智能体主模型作为隐藏重试目标。 隔离任务的模型选择优先级,从高到低:
  1. 每任务载荷 model(显式配置;不允许的模型会让运行失败)
  2. Gmail 钩子模型覆盖(仅当运行来自 Gmail 且该覆盖被允许时)
  3. 用户选择并存储的 cron 会话模型覆盖
  4. 智能体/默认模型选择
快速模式遵循解析后的实时选择。如果所选模型配置具有 params.fastMode,隔离 cron 默认使用它;已存储的会话 fastMode 覆盖(然后是智能体 fastModeDefault)仍会在任一方向上优先于模型配置。自动模式使用模型的 params.fastAutoOnSeconds 截止值,默认为 60 秒。 如果运行遇到实时模型切换交接,cron 会使用切换后的提供商/模型重试,并为活动运行持久化该选择(以及任何新的凭证配置文件)。重试有上限:初始尝试加 2 次切换重试后,cron 会中止而不是循环。 在隔离运行开始前,OpenClaw 会检查已配置 api: "ollama"api: "openai-completions" 提供商的可达本地端点,其 baseUrl 为 loopback、私有网络或 .local。此预检会遍历任务配置的回退链,并且只有在每个候选都不可达后才将运行标记为 skipped--fallbacks "" 会将该遍历严格限制为主模型。宕机端点会将运行记录为 skipped 并附带清晰错误,而不是启动模型调用。结果按端点缓存 5 分钟(不是按任务或模型),因此许多到期任务共享一个失效的本地 Ollama/vLLM/SGLang/LM Studio 服务器时,只需一次探测,而不是形成请求风暴。跳过的预检运行不会递增执行错误退避;设置 failureAlert.includeSkipped 可选择接收重复跳过提醒。

命令载荷

命令载荷在 Gateway 网关调度器内运行确定性脚本,而不启动模型支持的轮次。它们在 Gateway 网关主机上执行,捕获 stdout/stderr,在 cron 历史中记录运行,并复用与智能体轮次任务相同的 announcewebhooknone 投递模式。
命令 cron 是操作员管理员级的 Gateway 网关自动化表面,不是智能体 tools.exec 调用。创建、更新、移除或手动运行 cron 作业需要 operator.admin;计划命令稍后会在 Gateway 网关进程内作为该管理员编写的自动化执行。智能体 exec 策略(tools.exec.mode、审批提示、按智能体配置的工具允许列表)管控模型可见的 exec 工具,而不是命令 cron 载荷。
openclaw cron create "*/15 * * * *" \
  --name "Queue depth probe" \
  --command "scripts/check-queue.sh" \
  --command-cwd "/srv/app" \
  --announce \
  --channel telegram \
  --to "-1001234567890"
--command <shell> 会存储 argv: ["sh", "-lc", <shell>]。使用 --command-argv '["node","scripts/report.mjs"]' 可在不经 shell 解析的情况下执行精确的 argv。可选的 --command-env KEY=VALUE(可重复)、--command-input--timeout-seconds(默认 10 分钟)、--no-output-timeout-seconds--output-max-bytes 用于控制进程环境、stdin 和输出边界。 投递的文本来自进程输出:非空 stdout 优先;如果 stdout 为空且 stderr 非空,则投递 stderr;如果两者都存在,cron 会发送一个小型 stdout: / stderr: 块。退出码 0 会将运行记录为 ok;非零退出、信号、超时或无输出超时会记录为 error,并可能触发失败提醒。只打印 NO_REPLY 的命令会使用常规 cron 静默令牌抑制,不会向聊天发回任何内容。

执行样式

样式--session运行于最适合
主会话main专用 cron 唤醒通道提醒、系统事件
隔离isolated专用 cron:<jobId>报告、后台杂务
当前会话current创建时绑定感知上下文的周期性工作
自定义会话session:custom-id持久命名会话基于历史构建的工作流
主会话作业会将系统事件入队到 cron 所有的运行通道,并可选择唤醒 Heartbeat(--wake now--wake next-heartbeat)。它们可以使用目标主会话最近一次投递上下文来回复,但不会把常规 cron 轮次追加到人工聊天通道,也不会延长目标会话的每日/空闲重置新鲜度。隔离作业会以新会话运行一个专用智能体轮次。自定义会话session:xxx)会跨运行保留上下文,从而支持每日站会这类基于先前摘要构建的工作流。主会话 cron 事件是自包含的系统事件提醒。它们不会自动包含默认 Heartbeat 提示中的 “Read HEARTBEAT.md” 指令;如果提醒需要查阅 HEARTBEAT.md,请在 cron 事件文本中明确说明。
每次运行都有新的转录/会话 id。OpenClaw 会携带安全偏好(思考/快速/详细设置、标签、用户明确选择的模型/凭证覆盖),但不会从旧 cron 行继承环境会话上下文:频道/群组路由、发送或队列策略、提升权限、来源或 ACP 运行时绑定。如果周期性作业应有意基于同一会话上下文构建,请使用 currentsession:<id>
当隔离 cron 运行编排子智能体时,投递会优先使用最终后代输出,而不是过期的父级临时文本。如果后代仍在运行,OpenClaw 会抑制该部分父级更新,而不是公告它。对于纯文本 Discord 公告目标,OpenClaw 会发送一次规范的最终助手文本,而不是同时重放流式/中间文本和最终答案。媒体和结构化 Discord 载荷仍会单独投递,因此附件和组件不会被丢弃。

投递和输出

模式发生的事情
announce如果智能体未发送,则将最终文本回退投递到目标
webhook将完成事件载荷 POST 到 URL
none无运行器回退投递
使用 --announce --channel telegram --to "-1001234567890" 进行渠道投递。对于 Telegram 论坛主题,请使用 -1001234567890:topic:123;OpenClaw 也接受 Telegram 所有的 -1001234567890:123 简写。直接 RPC/配置调用者可以将 delivery.threadId 作为字符串或数字传入。Slack/Discord/Mattermost 目标使用显式前缀(channel:<id>user:<id>)。Matrix 房间 ID 区分大小写;请使用精确的房间 ID,或使用来自 Matrix 的 room:!room:server 形式。 当公告投递使用 channel: "last" 或省略 channel 时,像 telegram:123 这样带提供商前缀的目标可以在 cron 回退到会话历史或单个已配置渠道之前选择渠道。只有已加载插件声明的前缀才是提供商选择器。如果 delivery.channel 是显式的,目标前缀必须命名同一提供商;channel: "whatsapp" 搭配 to: "telegram:123" 会被拒绝,而不是让 WhatsApp 把 Telegram ID 解释为电话号码。目标类型和服务前缀(channel:<id>user:<id>imessage:<handle>sms:<number>)仍属于渠道所有的目标语法,而不是提供商选择器。 对于隔离作业,聊天投递是共享的:如果聊天路由可用,即使带有 --no-deliver,智能体也可以使用 message 工具。如果智能体发送到已配置/当前目标,OpenClaw 会跳过回退公告。否则,announcewebhooknone 只控制智能体轮次结束后运行器如何处理最终回复。 当智能体从活跃聊天创建隔离提醒时,OpenClaw 会存储保留的实时投递目标,用于回退公告路由。内部会话键可能是小写;当前聊天上下文可用时,不会从这些键重建提供商投递目标。 隐式公告投递会使用已配置的渠道允许列表来验证并重路由过期目标。私信配对存储审批不是回退自动化接收者;如果计划作业应主动发送到私信,请设置 delivery.to 或配置渠道 allowFrom 条目。

失败通知

失败通知遵循单独的目标路径:
  • cron.failureDestination 为失败通知设置全局默认值。
  • job.delivery.failureDestination 按作业覆盖该值。
  • 如果两者都未设置,且作业已通过 announce 投递,失败通知会回退到该主要公告目标。
  • delivery.failureDestination 仅支持 sessionTarget="isolated" 作业,除非主投递模式是 webhook
  • failureAlert.includeSkipped: true 会让作业或全局 cron 警报策略加入重复跳过运行提醒。跳过的运行会保留单独的连续跳过计数器,因此不会影响执行错误退避。
  • openclaw cron edit 暴露按作业的提醒调优:--failure-alert/--no-failure-alert--failure-alert-after <n>--failure-alert-channel--failure-alert-to--failure-alert-cooldown--failure-alert-include-skipped/--failure-alert-exclude-skipped--failure-alert-mode--failure-alert-account-id

输出语言

Cron 作业不会从渠道、locale 或先前消息推断回复语言。请将语言规则放入计划消息或模板:
openclaw cron edit <jobId> \
  --message "Summarize the updates. Respond in Chinese; keep URLs, code, and product names unchanged."
对于模板文件,请将语言指令保留在渲染后的提示中,并在作业运行前验证 {{language}} 等占位符已填充。如果输出混合多种语言,请明确规则,例如:“叙述文本使用中文,技术术语保留英文。”

CLI 示例

openclaw cron add \
  --name "Calendar check" \
  --at "20m" \
  --session main \
  --system-event "Next heartbeat: check calendar." \
  --wake now

管理作业

# List all jobs
openclaw cron list

# Get one stored job as JSON
openclaw cron get <jobId>

# Show one job, including resolved delivery route
openclaw cron show <jobId>

# Enable/disable without deleting
openclaw cron enable <jobId>
openclaw cron disable <jobId>

# Edit a job
openclaw cron edit <jobId> --message "Updated prompt" --model "opus"

# Force run a job now
openclaw cron run <jobId>

# Force run a job now and wait for its terminal status
openclaw cron run <jobId> --wait --wait-timeout 10m --poll-interval 2s

# Run only if due
openclaw cron run <jobId> --due

# View run history
openclaw cron runs --id <jobId> --limit 50

# View one exact run
openclaw cron runs --id <jobId> --run-id <runId>

# Delete a job
openclaw cron remove <jobId>

# Agent selection (multi-agent setups)
openclaw cron create "0 6 * * *" "Check ops queue" --name "Ops sweep" --session isolated --agent ops
openclaw cron edit <jobId> --clear-agent
openclaw cron run <jobId> 会在手动运行入队后返回。对于关机钩子、维护脚本或其他必须阻塞到队列运行完成的自动化,请使用 --wait;它会轮询返回的 runId(默认超时 10m,轮询间隔 2s),并在状态为 ok 时以 0 退出,在 errorskipped 或等待超时时以非零退出。 智能体 cron 工具会从 cron(action: "list") 返回紧凑作业摘要(idnameenablednextRunAtMsscheduleKindlastRunStatus);使用 cron(action: "get", jobId: "...") 获取单个完整作业定义。直接 Gateway 网关调用者可以向 cron.list 传入 compact: true;省略它会保留带投递预览的完整响应。 openclaw cron createopenclaw cron add 的别名。新任务可以使用位置式计划("0 9 * * 1""every 1h""20m" 或 ISO 时间戳),后面跟位置式智能体提示。对 cron add|createcron edit 使用 --webhook <url>,可将已完成运行的载荷 POST 到 HTTP 端点;webhook 投递不能与聊天投递标志(--announce--channel--to--thread-id--account)组合使用。在 cron edit 上,--clear-channel--clear-to--clear-thread-id--clear-account 会分别取消设置这些路由字段(每个都会拒绝与其匹配的设置标志同时使用),这不同于 --no-deliver,后者只会禁用运行器兜底投递。
模型覆盖说明:
  • openclaw cron add|edit --model ... 会更改任务选择的模型。
  • 如果模型被允许,该确切提供商/模型会进入隔离的智能体运行。
  • 如果不被允许或无法解析,cron 会以明确的验证错误使该运行失败。
  • API cron.update 载荷补丁可以设置 model: null 来清除已存储的任务模型覆盖。
  • openclaw cron edit <job-id> --clear-model 会从 CLI 清除该覆盖(效果与 model: null 补丁相同),且不能与 --model 组合使用。
  • 已配置的 fallback 链仍然适用,因为 cron --model 是任务主模型,而不是会话 /model 覆盖。
  • openclaw cron add|edit --fallbacks ... 会设置载荷 fallbacks,替换该任务的已配置 fallback;--fallbacks "" 会禁用 fallback 并使运行严格执行。openclaw cron edit <job-id> --clear-fallbacks 会清除每任务覆盖。
  • 没有显式或已配置 fallback 列表的普通 --model 不会静默落到智能体主模型作为额外重试目标。

Webhooks

Gateway 网关可以暴露 HTTP webhook 端点供外部触发器使用。在配置中启用:
{
  hooks: {
    enabled: true,
    token: "shared-secret",
    path: "/hooks",
  },
}

身份验证

每个请求都必须通过 header 包含 hook 令牌:
  • Authorization: Bearer <token>(推荐)
  • x-openclaw-token: <token>
查询字符串令牌会被拒绝。
为主会话将系统事件加入队列:
curl -X POST http://127.0.0.1:18789/hooks/wake \
  -H 'Authorization: Bearer SECRET' \
  -H 'Content-Type: application/json' \
  -d '{"text":"New email received","mode":"now"}'
text
string
必填
事件描述。
mode
string
默认值:"now"
nownext-heartbeat
运行隔离的智能体轮次:
curl -X POST http://127.0.0.1:18789/hooks/agent \
  -H 'Authorization: Bearer SECRET' \
  -H 'Content-Type: application/json' \
  -d '{"message":"Summarize inbox","name":"Email","model":"openai/gpt-5.5"}'
字段:message(必填)、nameagentIdsessionKey(需要 hooks.allowRequestSessionKey=true)、idempotencyKeywakeModedeliverchanneltomodelthinkingtimeoutSeconds
自定义 hook 名称通过配置中的 hooks.mappings 解析。映射可以使用模板或代码转换,将任意载荷转换为 wakeagent 操作。
将 hook 端点置于回环、tailnet 或受信任的反向代理之后。
  • 使用专用 hook 令牌;不要复用 Gateway 网关身份验证令牌。
  • hooks.path 保持在专用子路径上;/ 会被拒绝。
  • 设置 hooks.allowedAgentIds 以限制 hook 可以指向的有效智能体,包括省略 agentId 时的默认智能体。
  • 保持 hooks.allowRequestSessionKey=false,除非你需要调用方选择的会话。
  • 如果启用 hooks.allowRequestSessionKey,也要设置 hooks.allowedSessionKeyPrefixes 来约束允许的会话键形状。
  • 默认情况下,hook 载荷会用安全边界包装。

Gmail PubSub 集成

通过 Google PubSub 将 Gmail 收件箱触发器接入 OpenClaw。
前提条件: gcloud CLI、gog(gogcli)、已启用的 OpenClaw hooks、用于公共 HTTPS 端点的 Tailscale。

向导设置(推荐)

openclaw webhooks gmail setup --account openclaw@gmail.com
这会写入 hooks.gmail 配置,启用 Gmail 预设,并默认使用 Tailscale Funnel 作为 push 端点(--tailscale funnel|serve|off)。

Gateway 网关自动启动

hooks.enabled=true 且已设置 hooks.gmail.account 时,Gateway 网关会在启动时启动 gog gmail watch serve 并自动续订 watch。设置 OPENCLAW_SKIP_GMAIL_WATCHER=1 可选择退出。

手动一次性设置

1

Select the GCP project

选择拥有 gog 所用 OAuth 客户端的 GCP 项目:
gcloud auth login
gcloud config set project <project-id>
gcloud services enable gmail.googleapis.com pubsub.googleapis.com
2

Create topic and grant Gmail push access

gcloud pubsub topics create gog-gmail-watch
gcloud pubsub topics add-iam-policy-binding gog-gmail-watch \
  --member=serviceAccount:gmail-api-push@system.gserviceaccount.com \
  --role=roles/pubsub.publisher
3

Start the watch

gog gmail watch start \
  --account openclaw@gmail.com \
  --label INBOX \
  --topic projects/<project-id>/topics/gog-gmail-watch

Gmail 模型覆盖

{
  hooks: {
    gmail: {
      model: "openrouter/meta-llama/llama-3.3-70b-instruct:free",
      thinking: "off",
    },
  },
}

配置

{
  cron: {
    enabled: true,
    store: "~/.openclaw/cron/jobs.json",
    maxConcurrentRuns: 8,
    retry: {
      maxAttempts: 3,
      backoffMs: [30000, 60000, 300000],
      retryOn: ["rate_limit", "overloaded", "network", "timeout", "server_error"],
    },
    webhookToken: "replace-with-dedicated-webhook-token",
    sessionRetention: "24h",
    runLog: { maxBytes: "2mb", keepLines: 2000 },
  },
}
上面的 retry 值是默认值:最多 3 次重试,使用 30s/60s/5m 退避,并重试全部五类瞬态类别。webhookToken 会在 cron webhook POST 中作为 Authorization: Bearer <token> 发送。 maxConcurrentRuns 会同时限制计划 cron 调度和隔离的智能体轮次执行,默认值为 8。隔离的 cron 智能体轮次内部使用队列专用的 cron-nested 执行通道,因此提高此值可让独立的 cron LLM 运行并行推进,而不是只启动它们的外层 cron 包装器。共享的非 cron nested 通道不会被此设置拓宽。 cron.store 是逻辑存储键和 Doctor 迁移路径,而不是要手动编辑的实时 JSON 文件。任务数据存储在 SQLite 中;请使用 CLI 或 Gateway 网关 API 进行更改。 禁用 cron:cron.enabled: falseOPENCLAW_SKIP_CRON=1
一次性重试:瞬态错误(速率限制、过载、网络、超时、服务器错误)最多重试 retry.maxAttempts 次(默认 3),使用 retry.backoffMs(默认 30s、60s、5m)。永久错误会立即禁用任务。周期性重试:连续执行错误会按扩展计划退避(30s、60s、5m、15m、60m)。下一次成功运行后退避会重置。
cron.sessionRetention(默认 24hfalse 禁用)会修剪隔离运行会话条目。cron.runLog.keepLines 会限制每个任务保留的 SQLite 运行历史行数;maxBytes 为兼容较旧的文件后端运行日志而保留。
升级时,运行 openclaw doctor --fix,将旧版 ~/.openclaw/cron/jobs.jsonjobs-state.jsonruns/*.jsonl 文件导入 SQLite,并使用 .migrated 后缀重命名它们。格式错误的任务行会从运行时跳过,并复制到 jobs-quarantine.json 供后续修复或审查。

故障排查

命令阶梯

openclaw status
openclaw gateway status
openclaw cron status
openclaw cron list
openclaw cron runs --id <jobId> --limit 20
openclaw system heartbeat last
openclaw logs --follow
openclaw doctor
  • 检查 cron.enabledOPENCLAW_SKIP_CRON 环境变量。
  • 确认 Gateway 网关持续运行。
  • 对于 cron 计划,验证时区(--tz)与主机时区。
  • 运行输出中的 reason: not-due 表示手动运行是用 openclaw cron run <jobId> --due 检查的,并且该任务尚未到期。
  • 投递模式 none 表示不预期运行器兜底发送。当有聊天路由可用时,智能体仍可用 message 工具直接发送。
  • 缺少投递目标或投递目标无效(channel/to)表示出站已跳过。
  • 对于 Matrix,复制的或旧版任务如果带有小写的 delivery.to 房间 ID,可能会失败,因为 Matrix 房间 ID 区分大小写。将任务编辑为 Matrix 中精确的 !room:serverroom:!room:server 值。
  • 渠道身份验证错误(unauthorizedForbidden)表示投递被凭证阻止。
  • 如果隔离运行只返回静默令牌(NO_REPLY / no_reply),OpenClaw 会抑制直接出站投递和兜底队列摘要路径,因此不会向聊天发回任何内容。
  • 如果智能体应自行给用户发消息,请检查该任务是否有可用路由(channel: "last" 且有先前聊天,或显式渠道/目标)。
  • 每日重置和空闲重置的新鲜度不基于 updatedAt;请参阅 会话管理
  • Cron 唤醒、heartbeat 运行、exec 通知和 Gateway 网关记账可能会为路由/状态更新会话行,但它们不会延长 sessionStartedAtlastInteractionAt
  • 对于在这些字段存在之前创建的旧版行,如果文件仍然可用,OpenClaw 可以从转录 JSONL 会话 header 中恢复 sessionStartedAt。没有 lastInteractionAt 的旧版空闲行会使用该恢复的开始时间作为其空闲基线。
  • 不带 --tz 的 cron 使用 Gateway 网关主机时区。
  • 不带时区的 at 计划会被视为 UTC。
  • Heartbeat activeHours 使用已配置的时区解析。

相关