Skip to main content
自动化(automations)让 agent 定时干活:每天早上跑一次日报、每周清理一次会话、 到点跑一个检查脚本。调度核心用 croner 驱动, 带文件锁与崩溃恢复。
调度器源码 vendored 自 @amaster.ai/pi-task-scheduler(Apache-2.0)。 本地有意改动过几处,其中影响行为的是:调度器生命周期由 sidecar 自持, 以及调度工具的作用域从「当前会话」放宽到 app 级——自动化是应用级资产, 跨会话可见。

执行形态

几个关键决定,都围绕「不打断你正在干的事」:

每次触发新建独立会话

结果留在那个会话里,可以回看,不打断当前对话。 会话物化后侧边栏自动出现,带 ⚡ 徽标。

错过补偿是合并补跑

App 重开后,错过的触发合并补跑一次,而不是逐次补—— 停了三天的日报任务不需要跑三遍。

系统通知点击直达会话

任务完成的通知点进去直接落到那次运行的会话, 失败自动回落到 JS 插件路径。

并发与数量上限

同时最多 2 个任务在跑,最多 30 个任务;排队中的触发会出现在运行历史里。

「独立会话」具体意味着什么

每次运行是一个全新的会话,标识形如 automation:<任务id>:<历史条目id>。 所以:
  • 它走的是建会话分支而不是续流分支(显式 id 会被当成续流会话去校验存在性)
  • 会话随转录 JSONL 持久化,事后可完整回溯
  • 真实 sessionId 记进任务的运行记录,供通知跳转用
投递的 prompt 就是你写的那段正文,不加任何前后缀。 无人值守的约束不靠 prompt 包装实现,靠的是权限档—— 包装反而会让模型在一个它本不该操心的框架里工作。

三种创建方式

  1. 表单界面——侧边栏「自动化」→ 整页管理视图:任务卡片列表、新建弹窗、运行历史;
  2. 对话里让 agent 帮建——sidecar 注册了调度工具,agent 可以直接创建;
  3. 预置任务模板——从模板选择器挑一个改改就能用。
编辑器里「执行指令」下方是三枚 composer 同款胶囊: 工作目录、权限档、模型——新任务的目录默认预填当前工作区。

内置模板

无人值守审批档

没人可问的时候,「问一下」这个选项不存在,审批必须一刀切。 定时任务用独立的权限档(toolPolicyProfile),三档,默认收紧到 read-only: 显式记过的授权不会被档位推翻:allowCommands(命令词前缀)与 allowMcpTools (工具全名逐字)是常驻授权,判在各档之前——同一个 allow-list 不该在”你手动跑”和 “定时跑”两条路径上语义相反。

被拒绝时会发生什么

工具被拒不会让任务卡死或反复重试。调度器会告诉模型:
不要重试这个工具;用允许的只读操作把任务收尾。
所以一个 read-only 的日报任务撞上 bash 时,模型会改用读文件的方式把日报做出来, 而不是原地重试到超时。
与「权限档位」同名,判定口径已对齐:
  • 「工作区内自动」(权限档位)按路径判:能判断目标文件在不在工作区/清单里, 判不了就弹确认
  • 「可写工作区」(自动化档)同样按路径判:write/edit 只放行工作区内或 可写根清单内,越界、bash、MCP、配置类工具一律拒绝
差别只在没人可问——“要问的”变成”直接拒绝”。两者外观是同一套胶囊(自动化编辑器 特意复用了 ModePicker 的形态),所以看名字几乎必错。详见模式总览。

Webhook 与通知

任务事件(触发、完成、失败)可以推到任意服务——事件注册表里的 automation.* 会自动出现在 Webhook 设置的下拉里。 任务完成也可以走系统通知,点击直达那次运行的会话。 maxConcurrentRuns(默认 2)与 maxTasks(默认 30)是本地扩展的护栏, 防止调度器失控。

运行历史

双 Tab 里的「运行记录」跨任务聚合、按天分组、可搜索。排队中的触发也会出现在这里—— 所以「任务没跑」这个问题,第一反应应该是先看运行记录而不是任务卡片。

管理界面

任务卡

头部直排「立即运行 / 编辑 / 历史」,⋯ 只留删除

双 Tab

「定时任务 | 运行记录」;运行记录跨任务聚合、按天分组、可搜索

批量管理

卡片勾选 / 全选、批量启用 / 暂停 / 删除(删除两段式确认)

下一步

模式总览

两套「档位」的区别与各自语义。

远程与移动端

这些任务跑着的时候,人在外面也能看。