Replace the flat features directory with document-type and functional-domain navigation, update repository-wide links, and add a top-level documentation index. Define Task, Conversation, Job, Subjob, Run, Scheduled Task, Goal Task, and Task Center in one canonical document set. Keep Smart Heartbeat ownership separate and leave future partitioned memory explicitly undesigned.
227 lines
7.4 KiB
Markdown
227 lines
7.4 KiB
Markdown
# Scheduled Task PRD
|
||
|
||
## 文档信息
|
||
|
||
| 项目 | 内容 |
|
||
| --- | --- |
|
||
| 状态 | 当前基础能力已存在,扩展调度设计中 |
|
||
| 版本 | 0.4 |
|
||
| 日期 | 2026-08-19 |
|
||
| 依赖 | [Task 与 Job 统一领域模型](./task-and-job-model.md) |
|
||
| 相关架构 | [自动化平台总体设计](../../architecture/automation-platform-architecture.md) |
|
||
|
||
## 1. 产品定义
|
||
|
||
Scheduled Task 是带时间或事件触发器的 Task。它不是 Schedule 定义与临时 Task 的松散组合,
|
||
也不创建第二条 Conversation。
|
||
|
||
创建 Scheduled Task 时:
|
||
|
||
1. 创建一个 Task。
|
||
2. 为该 Task 创建唯一 Conversation。
|
||
3. 保存 Schedule/Trigger Binding。
|
||
4. 每次触发在同一 Task 内创建新的 Job 和 Run。
|
||
5. 将面向用户的进展和结果持续写回同一 Task Conversation。
|
||
|
||
因此,一个每日任务在 Task Center 中始终是一条 Task,而不是每天新增一条 Task。
|
||
|
||
## 2. 当前能力
|
||
|
||
GoodBuddy 当前支持单次、每日和每周触发固定 Ask 提示,并持久化计划、Task、运行状态和成果。
|
||
近期改进不得破坏现有数据、错过执行结算、暂停、立即运行和应用退出行为。
|
||
|
||
## 3. 目标
|
||
|
||
- 支持单次、每日、每周、每月、工作日和受限 Cron。
|
||
- 支持 Task 完成、失败、Conversation 完成等内部事件触发。
|
||
- 允许自然语言生成结构化草稿,但必须由用户检查后启用。
|
||
- 提供时区、错过执行、幂等、租约、重试、恢复、取消、预算和审计。
|
||
- 让所有重复触发复用同一 Task Conversation。
|
||
- 为一次触发建立清晰 Job/Run,而不是创建新的顶层 Task。
|
||
|
||
## 4. 非目标
|
||
|
||
- 不提供任意脚本和循环的通用 DAG 编辑器。
|
||
- 不允许模型生成并直接执行任意 Shell、SQL 或无限频率 Cron。
|
||
- 不承诺应用退出后继续运行。
|
||
- 不允许计划静默扩大权限、目录、知识或记忆范围。
|
||
- 不把 Smart Heartbeat 变成 Scheduled Task。
|
||
- 不把每次触发或重试显示为新的 Task。
|
||
|
||
## 5. 创建与配置
|
||
|
||
用户可以输入自然语言意图:
|
||
|
||
```text
|
||
每周五下午 5 点总结本项目本周完成和失败的工作,
|
||
列出下周三个优先事项,不要修改文件。
|
||
```
|
||
|
||
模型只生成草稿:
|
||
|
||
- 名称和说明。
|
||
- 时间或事件触发器。
|
||
- 工作模式和 Runtime 建议。
|
||
- Project、知识、记忆、目录和工具范围。
|
||
- 输入、输出和通知。
|
||
- 预算、并发和错过执行策略。
|
||
|
||
用户确认后,系统一次性创建 Task、Conversation 和 Schedule Binding。编辑计划只影响后续
|
||
Job;已启动 Run 使用冻结快照。
|
||
|
||
## 6. 触发器
|
||
|
||
### 6.1 时间触发
|
||
|
||
```ts
|
||
type TimeTrigger =
|
||
| { type: 'once'; at: string; timezone: string }
|
||
| { type: 'daily'; localTime: string; timezone: string }
|
||
| {
|
||
type: 'weekly'
|
||
weekdays: number[]
|
||
localTime: string
|
||
timezone: string
|
||
}
|
||
| {
|
||
type: 'monthly'
|
||
day: number | 'last'
|
||
localTime: string
|
||
timezone: string
|
||
}
|
||
| {
|
||
type: 'cron'
|
||
expression: string
|
||
timezone: string
|
||
}
|
||
```
|
||
|
||
受限 Cron 使用五字段,不支持秒、年份、宏、`L`、`W`、`#` 或供应商扩展。Main 负责解析,
|
||
默认最小间隔为 15 分钟,并展示未来五次触发时间。
|
||
|
||
### 6.2 事件触发
|
||
|
||
后续支持:
|
||
|
||
- `conversation.completed`
|
||
- `task.completed`
|
||
- `task.failed`
|
||
- `artifact.created`
|
||
- `knowledge.sync.completed`
|
||
- `magic_note.updated`
|
||
|
||
事件触发配置来源范围、确定性过滤、去重窗口、冷却时间和并发上限。基础匹配不调用模型。
|
||
|
||
### 6.3 手动触发
|
||
|
||
“立即运行”在当前 Task 内创建独立 Job 和 Run,不改变下一次计划时间,不创建新 Task。
|
||
重复点击使用调用级幂等键去重。
|
||
|
||
## 7. 一次触发的对象关系
|
||
|
||
```text
|
||
Scheduled Task
|
||
├─ Conversation(持续复用)
|
||
├─ Schedule Binding
|
||
└─ Job: scheduled_occurrence
|
||
└─ Run
|
||
```
|
||
|
||
- `scheduledFor` 和计划版本形成幂等键。
|
||
- 同一 Scheduled Task 默认最多一个活动 occurrence Job。
|
||
- 若允许并行 occurrence,它们仍属于同一 Task Conversation,并由协调器有序汇总。
|
||
- 重试产生新 Run,不产生新 Task 或新 Job。
|
||
|
||
## 8. 错过执行
|
||
|
||
| 策略 | 行为 |
|
||
| --- | --- |
|
||
| `skip` | 记录跳过,不补跑 |
|
||
| `run_once` | 无论错过多少次,只在当前 Task 内补一个 Job |
|
||
| `catch_up_bounded` | 在数量和时间窗口上限内创建多个有界 Job |
|
||
|
||
默认补跑最多 3 次、最多回溯 7 天。补跑同样受 Task 的并发、权限和预算控制。
|
||
|
||
## 9. 时区和夏令时
|
||
|
||
- 保存 IANA 时区,不保存固定 UTC 偏移。
|
||
- 春季不存在的本地时间在当日第一个有效分钟触发。
|
||
- 秋季重复时间只触发一次。
|
||
- 系统时区变化不自动修改计划时区。
|
||
- UI 显示计划时区、本机时区差异和未来触发时间。
|
||
|
||
## 10. Ask、Execute 与审批
|
||
|
||
第一阶段保持 Ask:
|
||
|
||
- Runtime 边界只读。
|
||
- 不写文件、不执行命令、不发送消息、不修改远程数据。
|
||
- 输出写回 Task Conversation;独立交付物才进入成果。
|
||
|
||
Execute 按顺序开放:
|
||
|
||
1. 有人值守,沿用逐工具审批。
|
||
2. 预批准低风险工具和参数范围。
|
||
3. 经过专项验证的内置无人值守模板。
|
||
|
||
高风险、越界或未预授权动作进入 `waiting_approval`,不能因定时触发而绕过策略。
|
||
|
||
## 11. 预算与背压
|
||
|
||
每个 Scheduled Task 配置:
|
||
|
||
- 最大 Job 耗时。
|
||
- 最大模型、Token 和工具调用。
|
||
- 最大成果大小。
|
||
- 最大活动 Job 数。
|
||
- 后台优先级。
|
||
|
||
前台请求优先。后台达到上限时延后并记录 `deferred`,不能挤占用户正在等待的请求,也不能
|
||
在恢复空闲时一次释放全部积压。
|
||
|
||
## 12. 重试、恢复和取消
|
||
|
||
- 瞬时、无副作用失败可以有界重试。
|
||
- 配置、权限和范围错误不重试。
|
||
- 外部副作用结果未知时进入 `outcome_unknown`,不自动重试。
|
||
- 应用退出将活动 Job/Run 标记为 `interrupted`。
|
||
- 暂停计划只阻止新 Job,不假装取消已发生的外部操作。
|
||
- 取消 Task 必须传播到活动 Job、Subjob 和 Runtime。
|
||
|
||
## 13. 界面
|
||
|
||
Task Center 显示 Scheduled Task 的范围、状态、最近进展、需要关注和下次触发时间。点击条目
|
||
打开同一 Task Conversation。
|
||
|
||
Task 内可查看:
|
||
|
||
- 计划和触发器。
|
||
- 下次执行和未来预览。
|
||
- 每次 occurrence Job。
|
||
- Run、审批、活动和成果。
|
||
|
||
不新增平行 Automation Center。
|
||
|
||
## 14. 兼容迁移
|
||
|
||
现有 Schedule、Schedule Run、Task 和 Conversation 数据渐进关联:
|
||
|
||
- 保留现有计划 ID、启停状态、下次时间和历史。
|
||
- 为每个现有计划建立或绑定一个持续 Task Conversation。
|
||
- 历史每次执行映射为该 Task 下的 occurrence Job/Run。
|
||
- 迁移不得复制消息、成果或顶层 Task。
|
||
|
||
## 15. 验收标准
|
||
|
||
- [ ] 创建 Scheduled Task 只创建一个 Task 和一个 Conversation。
|
||
- [ ] 重复触发始终复用该 Task Conversation。
|
||
- [ ] 每次触发创建 Job/Run,不创建新的顶层 Task。
|
||
- [ ] 支持单次、每日、每周、每月、工作日和受限 Cron。
|
||
- [ ] UI 显示计划时区和未来五次触发时间。
|
||
- [ ] 夏令时不会造成漂移或双跑。
|
||
- [ ] 错过执行按配置跳过、补一次或有界补跑。
|
||
- [ ] 手动运行不改变下次计划时间。
|
||
- [ ] Ask 在 Runtime 边界拒绝写操作和外部副作用。
|
||
- [ ] 应用重启不自动重放结果未知的副作用。
|
||
- [ ] Task Center 不因重复触发新增条目。
|