调度器源码 vendored 自
@amaster.ai/pi-task-scheduler(Apache-2.0)。
本地有意改动过几处,其中影响行为的是:调度器生命周期由 sidecar 自持,
以及调度工具的作用域从「当前会话」放宽到 app 级——自动化是应用级资产,
跨会话可见。执行形态
几个关键决定,都围绕「不打断你正在干的事」:每次触发新建独立会话
结果留在那个会话里,可以回看,不打断当前对话。
会话物化后侧边栏自动出现,带 ⚡ 徽标。
错过补偿是合并补跑
App 重开后,错过的触发合并补跑一次,而不是逐次补——
停了三天的日报任务不需要跑三遍。
系统通知点击直达会话
任务完成的通知点进去直接落到那次运行的会话,
失败自动回落到 JS 插件路径。
并发与数量上限
同时最多 2 个任务在跑,最多 30 个任务;排队中的触发会出现在运行历史里。
「独立会话」具体意味着什么
每次运行是一个全新的会话,标识形如automation:<任务id>:<历史条目id>。
所以:
- 它走的是建会话分支而不是续流分支(显式 id 会被当成续流会话去校验存在性)
- 会话随转录 JSONL 持久化,事后可完整回溯
- 真实 sessionId 记进任务的运行记录,供通知跳转用
投递的 prompt 就是你写的那段正文,不加任何前后缀。
无人值守的约束不靠 prompt 包装实现,靠的是权限档——
包装反而会让模型在一个它本不该操心的框架里工作。
三种创建方式
- 表单界面——侧边栏「自动化」→ 整页管理视图:任务卡片列表、新建弹窗、运行历史;
- 对话里让 agent 帮建——sidecar 注册了调度工具,agent 可以直接创建;
- 预置任务模板——从模板选择器挑一个改改就能用。
内置模板
无人值守审批档
没人可问的时候,「问一下」这个选项不存在,审批必须一刀切。 定时任务用独立的权限档(toolPolicyProfile),三档,默认收紧到 read-only:
显式记过的授权不会被档位推翻:
allowCommands(命令词前缀)与 allowMcpTools
(工具全名逐字)是常驻授权,判在各档之前——同一个 allow-list 不该在”你手动跑”和
“定时跑”两条路径上语义相反。
被拒绝时会发生什么
工具被拒不会让任务卡死或反复重试。调度器会告诉模型:不要重试这个工具;用允许的只读操作把任务收尾。所以一个
read-only 的日报任务撞上 bash 时,模型会改用读文件的方式把日报做出来,
而不是原地重试到超时。
Webhook 与通知
任务事件(触发、完成、失败)可以推到任意服务——事件注册表里的automation.* 会自动出现在 Webhook 设置的下拉里。
任务完成也可以走系统通知,点击直达那次运行的会话。
maxConcurrentRuns(默认 2)与 maxTasks(默认 30)是本地扩展的护栏,
防止调度器失控。
运行历史
双 Tab 里的「运行记录」跨任务聚合、按天分组、可搜索。排队中的触发也会出现在这里—— 所以「任务没跑」这个问题,第一反应应该是先看运行记录而不是任务卡片。管理界面
任务卡
头部直排「立即运行 / 编辑 / 历史」,⋯ 只留删除
双 Tab
「定时任务 | 运行记录」;运行记录跨任务聚合、按天分组、可搜索
批量管理
卡片勾选 / 全选、批量启用 / 暂停 / 删除(删除两段式确认)
下一步
模式总览
两套「档位」的区别与各自语义。
远程与移动端
这些任务跑着的时候,人在外面也能看。
