mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-08 23:33:16 +08:00
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>
6.6 KiB
6.6 KiB
| 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;正文含「告警总数 / 严重占比」 |
标准流程(必须遵守)
schedule_propose(只草稿,不落库)
按上方任务模板从对话整理自包含recipe(禁止原样塞「继续刚才」)。- 把
preview_markdown发给用户,并口头强调:到点不会带着本次聊天,请核对步骤是否自包含。 - 用户确认后
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=...) |
删除定时任务(必须确认)
多任务 / 群聊多人创建时,禁止直接删除。
- 先
schedule_list或让用户说清目标;schedule_delete(job_id=…)不要先带confirmed=true。 - 把返回的
preview_markdown发给用户(含名称、时间、创建者)。 - 用户明确确认「删这个」后,再
schedule_delete(job_id=完整id, confirmed=true)。 - 若
foreign_job=true(他人创建):还须用户明确同意删他人的,并设confirm_foreign=true。 - 前缀匹配到多个任务 → 展示候选,不要猜。
- 仅想暂时停跑时优先
schedule_pause,不要删。
聊天快捷指令:
删除定时 <id>→ 只预览,不删确认删除定时 <id>→ 删除自己的确认删除他人定时 <完整id>→ 删除他人的(需更明确)
修改已有任务
用 schedule_update 更新 recipe。改完仍做自检:无上下文能否执行;必要时 schedule_run_now 验一次。