oclaw/skills/_workspace/public/scheduled-workflows/SKILL.md
oliver 30202dd291 feat(scheduler): confirm before deleting scheduled jobs
Require preview confirmation for schedule_delete, extra confirm_foreign for others' jobs in groups, and mirror the same flow in chat slash commands.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-14 10:11:04 +08:00

6.6 KiB
Raw Blame History

name description
scheduled-workflows 把复杂/多步工作固化成定时 Workflow Recipe:先 schedule_propose 确认再创建;删除须先预览再确认(群聊他人任务另需 confirm_foreign)。Recipe 必须自包含。

定时工作流 — Scheduled Workflows

何时使用

用户想把刚才引导完成的多步任务做成周期执行(例如「做成每周一 9 点的定时」「按刚才那套流程每天跑」),或创建会产出文件/报告的定时任务。

简单一句提醒(「每三小时提醒我喝水」)不要用本流程,直接 schedule_create + 短 prompt_text 即可。

最重要:自包含(无上下文仍可执行)

到点触发时,worker 不会把「当时那通聊天」当成任务说明。LLM 几乎只看到 recipe 编译出的内部指令(外加可能截断的会话噪声)。

因此写入的 recipe / 步骤文案必须满足:

一个陌生的 LLM 在没有原对话、没有「刚才」「那个」指代的情况下,仍能正确理解并完成任务。

禁止写入(指代 / 依赖上文)

  • 「继续刚才那个」「按上面流程」「和上次一样」
  • 「用用户给的那个文件」「那个模板」——却不写清路径/文件名/字段
  • 「参考本会话里刚生成的报告」——却不把关键结论、参数、路径抄进 recipe
  • 步骤短到只有动词:「处理数据」「发一下」

必须写入(自包含要素)

  • 做什么:具体目标与交付物(文件类型、发给谁、消息长什么样)
  • 怎么做:可逐步执行的步骤(工具/命令/数据源/命名规则)
  • 用什么:路径、URL、表名、模板内容或固定参数 → 放进 inputs.constants
  • 边界:不要动什么、失败怎么处理 → constraints
  • 怎样算完成:可检查的成功标准 → success_criteria

写完后自检一句:「若只有这份 recipe、清空聊天记录,新模型能否一次做对?」 不能则补字段,禁止提交。

任务模板(标准样例,照此展开)

新建复杂定时任务时,按下面模板填满再 schedule_propose。括号内是说明,写入时换成真实内容。

{
  "version": 1,
  "goal": "【一句话完整目标】例如:每周一 09:00 汇总上一自然周值班告警,生成 PDF 发到当前 WhatsApp 群并 @值班人",
  "steps": [
    "【步骤1·取数】说明数据从哪来:接口/命令/文件路径、时间范围如何算(上周一 00:00 至周日 23:59,时区 Asia/Shanghai)",
    "【步骤2·处理】说明过滤规则、分组字段、统计口径;需要生成的中间文件路径(如 data/workspace/tmp/duty_weekly.csv)",
    "【步骤3·产出】说明最终交付物格式与路径(如 data/workspace/tmp/duty_weekly_YYYYMMDD.pdf);标题/章节结构写清",
    "【步骤4·投递】调用 save_deliverable_attachment 发送 PDF;渠道消息须含:周期范围、总数、Top3 风险、是否需人工跟进;若需 @人写清展示名与用途"
  ],
  "constraints": [
    "【边界】只读该数据源,不修改生产配置/历史文件",
    "【失败】取数失败则渠道只发失败原因摘要,不假装成功、不发空 PDF"
  ],
  "success_criteria": [
    "群内收到本周 PDF 附件",
    "消息正文含统计周期与至少一条结论或风险点",
    "无未说明的错误/半成品路径糊弄用户"
  ],
  "inputs": {
    "constants": {
      "timezone": "Asia/Shanghai",
      "data_source": "【写死:命令、API、或 workspace 固定路径】",
      "output_dir": "data/workspace/tmp",
      "report_title_template": "值班周报 {week_range}"
    },
    "from_context": []
  },
  "output": {
    "style": "channel_update",
    "need_attachments": true
  }
}

说明:

  • from_context 默认保持 []。凡是执行要用的信息,尽量写进 constants 或 steps 正文,不要指望「到点还能翻到建任务时那通聊天」。
  • goal 也可作为 prompt_text 短摘要,但不能只有 goal、steps 仍含糊。

反例 → 正例

反例(依赖上下文) 正例(自包含)
步骤:生成报告并发群 用 data/workspace/templates/duty.md 模板,把上周告警按 NE 聚合,写 PDF 到 data/workspace/tmp/duty_weekly.pdf,再 save_deliverable_attachment 发当前渠道
constants: {},口头说「用刚才那个 CSV」 "source_csv": "data/workspace/uploads/alarms_export.csv"(或写入导出口径与再拉取命令)
success: 搞定 渠道出现 PDF;正文含「告警总数 / 严重占比」

标准流程(必须遵守)

  1. schedule_propose(只草稿,不落库)
    按上方任务模板从对话整理自包含 recipe(禁止原样塞「继续刚才」)。
  2. 把 preview_markdown 发给用户,并口头强调:到点不会带着本次聊天,请核对步骤是否自包含。
  3. 用户确认后 schedule_create,带上同一份 recipe + 时间字段。
    prompt_text = recipe.goal(完整句,不要用「同上」)。

禁止:复杂任务直接 schedule_create(prompt_text="继续刚才那个")。

与渠道附件

若周期任务会生成文件,设 "output": {"need_attachments": true},步骤里写明 save_deliverable_attachment(见 channel-file-delivery)。

简单 vs 复杂

类型 做法
喝水/开会提醒 schedule_create,仅短 prompt_text(本身已自包含)
多步流程 /「刚才那件事」 套用任务模板 → schedule_propose → 确认 → schedule_create(recipe=...)

删除定时任务(必须确认)

多任务 / 群聊多人创建时,禁止直接删除。

  1. 先 schedule_list 或让用户说清目标;schedule_delete(job_id=…) 不要先带 confirmed=true。
  2. 把返回的 preview_markdown 发给用户(含名称、时间、创建者)。
  3. 用户明确确认「删这个」后,再 schedule_delete(job_id=完整id, confirmed=true)。
  4. 若 foreign_job=true(他人创建):还须用户明确同意删他人的,并设 confirm_foreign=true。
  5. 前缀匹配到多个任务 → 展示候选,不要猜。
  6. 仅想暂时停跑时优先 schedule_pause,不要删。

聊天快捷指令:

  • 删除定时 <id> → 只预览,不删
  • 确认删除定时 <id> → 删除自己的
  • 确认删除他人定时 <完整id> → 删除他人的(需更明确)

修改已有任务

用 schedule_update 更新 recipe。改完仍做自检:无上下文能否执行;必要时 schedule_run_now 验一次。