Qclaw Cron Skill

[MANDATORY - MUST LOAD] 凡是涉及定时/提醒/闹钟/周期执行/打卡/签到/cron/schedule/remind 等需求,以及修改/编辑/更新/暂停/恢复/删除/取消推送/改推送目标/改推送渠道等已有定时任务的操作,必须读取本 skill,严禁凭记忆猜测参数。

Audits

Pass

Install

openclaw skills install qclaw-cron-skill

cron — 定时任务

🚨 [MANDATORY] 用户提到「提醒/定时/每天X点/X分钟后/周期/重复/打卡/签到」等时,必须创建 cron 任务,口头承诺无效。

第一步:判断「推送目标」

🚨 [MANDATORY] 默认就在用户当前所处渠道提醒,禁止主动反问"推送到哪里"。 用户说「提醒我 / 叫我 / 告诉我 / 让我」等自指代表达 → 推送目标 = 当前会话渠道,不要追问。 仅当用户显式说"推到企微/飞书/微信群/告诉张三"等他指代时,才使用外部渠道。

当前会话 sender / channel推送目标mode
openclaw-control-ui(本地 UI / webchat)本地(不投递,直接渲染回复)none
wechat-access / dingtalk-connector当前外部渠道announce
wecom / feishu / openclaw-weixin / qqbot当前外部渠道announce
本地 UI + 用户显式说"推送到 X"外部渠道 Xannounce必须先读 ~/.qclaw/channel-defaults.json

第二步:判断创建方式

场景方式
sender=openclaw-control-ui(本地) / channel=wechat-access / dingtalk-connectorA:内置 cron 工具, 不需要再读取channel-defaults.json(toolCall,JSON 参数)
channel=wecom/feishu/openclaw-weixin/qqbotB:openclaw cron add CLI(通过 exec
sender=openclaw-control-ui 但推送到外部渠道B:CLI必须先读 ~/.qclaw/channel-defaults.json

外部渠道 session 中内置 cron 工具被 ownerOnly 策略过滤,LLM 不可见,必须走 CLI。dingtalk-connector可以使用内置cron工具。

渠道识别:显式 channel 字段 → 直接使用;无 channelmessage_idopenclaw-weixin: / wechat-access: 开头 → 对应渠道。

🚨 [MANDATORY] 外部渠道 to 获取规则: 当需要创建推送到外部渠道(wecom/feishu/openclaw-weixin/qqbot/dingtalk-connector/wechat-access)的定时任务时:

  1. 当前会话有 sender_id → 直接用作 to
  2. 当前会话无 sender_id(如本地 UI 创建推送到外部渠道)→ 必须先读 ~/.qclaw/channel-defaults.json,用当前 agentId + 目标 channel 查找 to
  3. channel-defaults.json 不存在 / 无对应渠道条目 / 无 to严禁创建任务,必须告知用户:「请先通过该渠道给机器人发送一条消息,系统会自动记录投递目标,之后再来创建定时任务」

绝对禁止创建 delivery 中没有 to 字段的外部渠道定时任务——这类任务会投递失败,浪费用户的期望。

第三步:时间类型

  • 具体时刻 / X分钟后 / 无周期词 → 一次性deleteAfterRun:true / --delete-after-run
  • 每天/每小时/每X分钟 → 周期任务
  • 绝对时间必须先 date +%z 获取时区+0800+08:00),禁止硬编码

第四步:时间参数速查

用户说法schedule(JSON)CLI 参数
每30分钟{"kind":"every","everyMs":1800000}--every 30m
每2小时{"kind":"every","everyMs":7200000}--every 2h
每天早上9点{"kind":"cron","cron":"0 9 * * *"}--cron "0 9 * * *"
每周一10点{"kind":"cron","cron":"0 10 * * 1"}--cron "0 10 * * 1"
工作日18点{"kind":"cron","cron":"0 18 * * 1-5"}--cron "0 18 * * 1-5"
今天下午3点{"kind":"at","at":"2026-04-09T15:00:00+08:00"}--at "..." --delete-after-run
10分钟后{"kind":"at","at":"<now+10min ISO>"}--at "..." --delete-after-run

cron 表达式:分 时 日 月 星期,0=周日,1-5=周一至五。

公共规则(方式 A/B 通用)

🚨 [MANDATORY] message 行为约束payload.message(方式A)/ --message(方式B)末尾必须加: 要求:(1) 不要回复 HEARTBEAT_OK (2) 不要调用 message 工具 (3) 直接输出提醒文字 (4) 控制在 2-3 句话以内

🚨 [MANDATORY] agentId 必传,禁止省略,禁止默认填 "main"

  • sessionKey agent:【agentId】:session-xxx → 取第二段
  • 无 sessionKey 但有 cwd /path/workspace-agent-xxx → 取最后一段去掉 workspace- 前缀(即 agent-xxx),禁止再去 agent-
  • 以上均无才传 "main";从当前对话上下文提取,禁止复用历史

🚨 [MANDATORY] delivery 参数获取优先级

  1. 优先从当前会话上下文channelsender_id(→to
  2. 其次读 ~/.qclaw/channel-defaults.json(本地→外部渠道时)— 用当前 agentId + 目标 channel 查找
  3. to 则中止 — ⛔ 严禁创建没有 to 的外部渠道任务,必须告知用户:「请先通过该渠道(如企微/飞书)给机器人发送一条消息,之后再来创建定时任务」

插件辅助处理:本地渠道/无 to 时自动注入 bestEffort:true(无须手写);外部渠道自动写入 channel-defaults.json;delivery 缺 channel/to 时插件从 sessionKey 自动补全(硬保底,仅 tool 路径)。 ⚠️ 插件保底 ≠ 可以不传 to:插件的 sessionKey 补全仅适用于外部渠道 session 内(sessionKey 包含渠道信息),本地 UI 发起时 sessionKey 无渠道信息,补全不会生效;CLI 路径完全无 sessionKey 补全。

🚨 [MANDATORY] mode 必须显式传入(插件不再自动推断 mode,按下表选择):

场景mode说明
推送到任何渠道(外部)"announce"创建/修改推送任务必传
不推送或本地渠道(仅本地静默执行)"none"取消推送时必传

💡 mode 是必填项,不要省略

  • 想推送 → mode:"announce",同时给 channel/to
  • 不想推送 → mode:"none",同时显式清空 channel/to(传空字符串)

delivery 值速查(mode 必传):

场景delivery
本地{"mode":"none"}
wechat-access{"mode":"announce","channel":"wechat-access","to":"<sender_id>"}
wecom/feishu/dingtalk{"mode":"announce","channel":"<渠道>","to":"<sender_id>"}
openclaw-weixin{"mode":"announce","channel":"openclaw-weixin","to":"<openid>@im.wechat"}

方式 A:内置 cron 工具模板

🚨 调用 toolName=cron不是 exec,参数为 JSON 对象。 ⚠️ 模板中的 delivery 默认是本地场景(mode:"none",对应 webchat/本地 UI 自指代提醒)。 推送到外部渠道时按上方"delivery 值速查"替换为 {"mode":"announce","channel":"...","to":"..."}

周期任务

{
  "action": "add",
  "job": {
    "name": "<任务名>", "agentId": "<agentId>",
    "schedule": {"kind":"every","everyMs":1800000},
    "sessionTarget": "isolated",
    "payload": {"kind":"agentTurn","message":"你是一个暖心的提醒助手。请用温暖、有趣的方式提醒用户:{内容}。要求:(1) 不要回复 HEARTBEAT_OK (2) 不要调用 message 工具 (3) 直接输出提醒文字 (4) 控制在 2-3 句话以内"},
    "delivery": {"mode":"none"}
  }
}

一次性:schedule→{"kind":"at","at":"<ISO+时区>"},加 "deleteAfterRun":true

方式 B:openclaw cron add CLI 模板

⚠️ 末尾的投递参数按场景选择:

  • 本地(webchat 自指代提醒) → --no-deliver
  • 外部渠道 → --announce --channel <渠道> --to <sender_id>
openclaw cron add \
  --name "<任务名>" --every 30m --session isolated --agent <agentId> \
  --message "你是一个暖心的提醒助手。请用温暖、有趣的方式提醒用户:{内容}。要求:(1) 不要回复 HEARTBEAT_OK (2) 不要调用 message 工具 (3) 直接输出提醒文字 (4) 控制在 2-3 句话以内" \
  --announce --channel <渠道> --to <sender_id>

一次性--every 30m--at "<ISO+时区>" --delete-after-run

🚨 命令失败最多重试一次,仍失败直接告知用户。

管理命令

暂停/停止 ≠ 删除。"暂停/禁用"→disable,"删除"→remove。

内置工具:列表 {"action":"list"} / 暂停 {"action":"update","jobId":"<id>","patch":{"enabled":false}} / 恢复 …{"enabled":true} / 删除 {"action":"remove","jobId":"<id>"} / 执行 {"action":"run","jobId":"<id>"}

CLIopenclaw cron list / edit <id> --enabled false/true / remove <id> / run <id>

🚨 修改任务专用规则(仅适用于 update / cron edit)

修改任务的 delivery 配置有独特的语义陷阱,必须严格遵守以下规则。

规则 1:patch 是增量覆盖,不是整体替换

🚨 [MANDATORY] patch.delivery 仅覆盖显式传入的字段

  • patch.delivery = {"mode":"announce"}只改 mode,原有的 channel/to 全部保留 ⚠️
  • 想清掉某字段必须显式传空串{"channel":"","to":""}
  • 不传 ≠ 清除! 这是 LLM 最常踩的坑。

规则 2:取消推送的唯一正确方式

"不再推送到 X" / "改回本地提醒" / "取消推送" 等用户表达,统一识别为「取消推送」意图,不要误解为"切换到本地 announce"。

  • tool 路径patch.delivery = {"mode":"none","channel":"","to":""}(mode 显式 none + 空串清掉 channel/to,三字段缺一不可)
  • CLI 路径openclaw cron edit <id> --no-deliver(一键搞定,等价于上面整套清空)

修改投递配置速查表(mode 必须显式传):

用户表达修改意图内置工具(patch.delivery)CLI
"不再推送到微信" / "取消推送" / "改回本地提醒"取消推送{"mode":"none","channel":"","to":""}--no-deliver
"改成推送到飞书 / 企微"改推送渠道{"mode":"announce","channel":"<新渠道>","to":"<新to>"}--announce --channel <新渠道> --to <新to>

回复模板

一次性:⏰ 好的,{时间}提醒你{内容}~ | 周期:⏰ 收到,{周期}提醒你{内容}~ | 取消:✅ 已取消"{名称}"

外部渠道只输出确认话术,严禁输出推理过程。