计划
当任务触发时:五种调度类型、cron 表达式规则、动态节奏和条件监视器。属于 Automations 指南的一部分。
调度类型¶
| 类型 | CLI 标志 | 描述 |
|---|---|---|
at |
--at |
一次性时间戳(ISO 8601 或相对时间,如 20m) |
every |
--every |
固定间隔(10m、1h、1d) |
cron |
--cron |
5 字段或 6 字段 cron 表达式,可选 --tz |
on-exit |
--on-exit |
当被监视命令退出时触发一次(事件触发;在回合拆除后仍保留;可选 --on-exit-cwd) |
stream |
--stream-command |
由受监督的长驻命令产生的批量行触发 |
这些调度标志同时适用于 openclaw automations add 和 openclaw automations edit <job-id>。例如,openclaw automations edit <job-id> --on-exit "./watch.sh" --on-exit-cwd /srv/app 会将现有任务转换为退出触发调度。
不带时区的时间戳按 UTC 处理。添加 --tz America/New_York 可在该 IANA 时区中解释不带偏移的 --at 日期时间,或评估 cron 表达式。不带 --tz 的 cron 表达式使用 Gateway 主机时区。--tz 不能与 --every 或 --on-exit 一起使用。
整点重复表达式(分钟为 0 且小时字段为通配符)会自动错开最多 5 分钟,以减少负载尖峰。使用 --exact 强制精确计时,或使用 --stagger 30s 指定显式窗口(仅限 cron 调度)。
在 Control UI 中,启用 精确计时 可禁用错开。对于整点重复表达式,关闭它并清除 错开窗口,以恢复最多 5 分钟的默认窗口。对于其他表达式,在不更改表达式的状态下清除已保存的窗口,会禁用错开,并重新打开时启用 精确计时。窗口为空的新调度在其表达式更改时保持默认计时。
当 on-exit 任务的负载被排队执行时,该任务会禁用自身。重新启用任务即可再次监视;即使前一个负载仍在完成,这也有效。如果新命令在该负载完成前退出,其退出会等待前一次运行稳定,然后再禁用任务并启动下一个负载。这包括超时响应后仍在运行的清理。禁用或更改监视会取消其待处理的退出。重新启用时,可以更改被监视的命令或工作目录。
心跳任务迁移¶
在 v2026.8.1 之前,Heartbeat scratch 支持结构化的 tasks: 块。如果你正在从更早版本升级,请运行 openclaw doctor --fix,将每个条目转换为普通可编辑的主会话自动化任务。Doctor 会保留间隔和上次运行时间,在移除该块之前创建任务,并在重新运行时安全地收敛相同的声明键。
这些迁移后的任务携带公开的 systemEvent 负载,因此 openclaw automations list、get、edit 和 remove 以及 automations 代理工具会像管理其他任务一样管理它们(该工具仍接受其旧版 cron 名称作为兼容性别名)。它们的执行使用受保护的心跳任务唤醒:活跃时段、最小间隔、洪泛控制和繁忙重试仍然适用,而调度器拥有每个任务的独立节奏。在同一合并窗口内到期的任务可以共享一个心跳回合。在心跳活跃时段之外的计划触发会被跳过,并在任务的下次触发时重试。
Heartbeat scratch 仅包含监视文本。运行时心跳不会将 tasks: 文本解析为调度;请将新的重复工作创建为自动化。
流数据源¶
流调度会在 Gateway 下保持运行由操作员编写的 argv 命令,并根据其 stdout 和 stderr 行触发任务。流调度是事件驱动的,从不按时间到期,并且默认可用。设置 cron.triggers.enabled: false 可将其与条件触发脚本和脚本负载一起禁用。禁用或移除任务会停止进程;Gateway 关闭会等待进程树拆除。快速失败会使用调度器内置的错误退避重启。连续五次运行时间短于 60 秒会使任务处于错误状态,并使用正常的失败告警路径;手动重新启用任务以清除重启上限。
openclaw automations add \
--name "Build event stream" \
--stream-command '["node","scripts/build-events.mjs"]' \
--stream-mode match \
--stream-match '^(failed|recovered):' \
--stream-batch-ms 250 \
--session isolated \
--message "Investigate these build events."
mode: "line"(默认值)接受每一行。mode: "match" 仅接受匹配编译后的 match 正则表达式的行。在 batchMs 的静默期(默认 250 ms,限制在 50–5000)或达到 maxBatchBytes(默认 16384,限制在 1024–65536)后,批次关闭。达到字节上限时,批次以 [truncated] 结尾。匹配模式始终针对完整文本评估完整行,即使超过 maxBatchBytes(只有交付的批次被截断);在受限原始接收限制处被截断的行只是前缀,因此它被视为不匹配,而不是让结尾锚定模式在截断处触发。该批次会追加到系统事件文本或代理回合消息中。流调度会拒绝命令负载,因为源命令和负载命令会导致进程所有权不明确。
匹配具有有界的处理预算和队列。如果任一限制被超过,源会停止并记录错误;请检查匹配表达式和 Gateway 负载,然后手动重新启用任务。
每个作业仅保留一次 payload 触发和一个有界待处理批次。在 payload 运行期间,或在内置 30 秒触发间隔结束之前到达的行,会合并到该待处理批次中,而不是构建无界队列。一个串行化所有者会在 streamDroppedBatches 中记录 gate 丢弃、payload 错误和未运行调度;有界合并会增加 streamCoalescedBatches。由于 payload 可能不具有幂等性,失败的 payload 不会被重试。逻辑源标识在受监督子进程重启之间保持稳定,但当源被禁用、移除或替换时会轮换,因此来自已退役源的排队批次即使经过 A-to-B-to-A 编辑也无法触发。停止完成后,来自旧子进程的迟到回调无效。没有原生 WebSocket 源;可以使用 argv 命令桥接一个,例如 websocat wss://example.invalid/events。
动态节奏(pacing)¶
周期性作业可以将 pacing.min 和/或 pacing.max 设置为持续时间字符串,例如 15m 或 4h;至少需要设置一个边界。在 automations add|edit 中使用 --pacing-min 和 --pacing-max(--clear-pacing 会移除两个边界)。
Control UI 在复制周期性作业时保留 pacing 边界。将带 pacing 的作业或其副本更改为 Once 会移除 pacing;其他编辑会保留现有边界。
在 agent-turn 运行期间,带 pacing 的作业可以调用 automations 工具,并传入 action: "next_check" 和 in: "30m"。该提案仅适用于当前正在运行的作业,并从成功运行完成时开始计算。OpenClaw 会静默地将其限制在已配置的边界内。未来的 pacing 截止时间在 Gateway 重启后仍保持为下一次计划检查。
没有提案的 pacing 会保持正常调度不变。失败、超时和跳过的运行会丢弃提案,因此现有的重试和错误退避行为优先。手动强制周期性作业属于带外操作,并保留其待处理的自然或 pacing 槽位。对于条件触发作业,即使提案请求更早检查,内置最小间隔仍保持为下限。
/loop 聊天快捷方式¶
在聊天中,仅限所有者的 /loop [interval] <prompt> 命令会创建一个绑定到该对话的周期性 agent-turn 作业。提供诸如 5m 的间隔以固定节奏,或省略它,让循环使用 next_check 在 1 分钟到 1 小时之间自我配速。使用 /loop status 列出绑定到对话的循环,使用 /loop stop [name] 移除它们。
每月日期和星期几使用 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),或者在一个字段上调度,并在作业的 prompt 或命令中保护另一个字段。
事件触发器(条件监视器)¶
事件触发器会为 every、cron 或 stream 调度添加一个无头条件脚本。时间调度在到期时评估它;流调度会为每个已关闭批次评估它。调度器仅在脚本返回 fire: true 时运行正常 payload:
{
schedule: { kind: "every", everyMs: 30000 },
trigger: {
// Fires only when the observed status differs from the last evaluation.
script: "const res = await exec({ command: 'gh pr checks 123 --json state -q \\'.[].state\\' | sort -u' }); const status = String(res?.aggregated ?? '').trim(); json({ fire: status !== trigger.state?.status, message: `PR 123 CI: ${trigger.state?.status ?? 'unknown'} -> ${status}`, state: { status } });",
once: false,
},
payload: { kind: "agentTurn", message: "Investigate the CI status change." },
}
openclaw doctor --fix 会转换调用 tools.call('exec', args) 并读取 .result.details 信封的已持久化触发脚本。Doctor 会保留自定义或模糊脚本不变,并识别每个受影响的作业以进行手动转换;独立脚本 payload 不会被转换。
脚本必须返回 { fire, message?, state? }。之前的 JSON 状态可作为深度冻结的 trigger.state 使用;流 gate 还会将当前批次作为 trigger.streamBatch 接收。返回新的 state 值以持久化它。状态上限为 16 KB。当触发结果包含 message 时,调度器会在执行前将其追加到系统事件文本或 agent-turn 消息中。once: true 会在其首次成功触发 payload 后禁用该作业。
更改正在运行的监视器的条件或已保存状态会保护该编辑,使其不受旧评估的状态更新和 once 完成的影响,包括在 Gateway 重启后。已完成的 payload 仍保留其运行历史。未更改的监视器保持其通常的 once 行为;重命名它不会重置其条件。
fire: false 会持久化评估状态和计数器,然后重新调度而不创建运行历史。这些静默评估在重启追赶期间计为已完成的出现次数。如果触发 payload 运行失败,返回的 state 不会被持久化——下一次评估会看到之前的状态并可以再次触发,因此请将脚本编写为只读检查,并将操作保留在 payload 中。触发调度具有内置的 30 秒最小间隔,并在维护和 Gateway 重启期间保留。每次评估有 30 秒的墙钟预算和最多 5 次工具调用。
在条件评估期间移除或禁用任务会取消该评估,使其负载无法开始。主会话负载将工作交给 heartbeat 后,该共享 heartbeat 会保留自己的生命周期。
围绕可操作状态编写 watcher,而不仅仅是成功:当检查失败或超时时保持静默的 watcher 在损坏时看起来仍然健康。将观察结果与 trigger.state 进行比较,并返回最新状态以去重;不要依赖模型或进程内存。触发时,确保 message 自包含,因为它会成为被触发运行的完整事件上下文。
Warning
条件触发脚本和 script 负载默认无人值守运行,并拥有所属 agent 的完整工具策略,包括 exec。Stream 计划也会让操作员编写的命令持续无人值守运行。将这些表面视为以该 agent 权限进行的无人值守代码执行。需要硬性停止的操作员可以设置 cron.triggers.enabled: false;删除该设置或将其设置为 true 以重新启用它们。
从本地脚本文件创建 watcher(- 从 stdin 读取脚本)。CLI 会保留文件路径中的前导和尾随空格;请将路径作为单个 shell 参数加引号:
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw