feat: add stable scheduled tasks

Scheduled tasks previously created separate visible work for each run and lacked one conversation-backed product identity. Custom tasks now create or reuse one stable Task and Conversation, reuse that identity across triggers, and write text results back with Task provenance.

Tasks default to Execute while preserving the configured Runtime, tool authorization, and high-risk approval boundaries. Schema v22 backfills existing schedules to stable Task and Conversation links without deleting historical runs.

The conversation list, conversation Task strip, and Task Center now expose the same Task, with localized status metadata, overflow-aware titles, and shared schedule controls.

Release note: 现在可以创建关联当前或新会话的定制计划任务;重复执行会复用同一 Task 并将文本结果回写会话,左侧会话列表和 Task Center 可直接查看和管理。
This commit is contained in:
mesalogo
2026-08-19 15:37:01 +08:00
parent 43e1d162dc
commit 993c439228
38 changed files with 5339 additions and 773 deletions
+231 -102
View File
@@ -4,74 +4,177 @@
| 项目 | 内容 |
| --- | --- |
| 状态 | 当前基础能力已存在,扩展调度设计中 |
| 版本 | 0.4 |
| 状态 | 首期稳定 Task 生命周期与创建体验已实现;高级触发和执行治理待实施 |
| 版本 | 0.6 |
| 日期 | 2026-08-19 |
| 依赖 | [Task 与 Job 统一领域模型](./task-and-job-model.md) |
| 相关架构 | [自动化平台总体设计](../../architecture/automation-platform-architecture.md) |
## 1. 产品定义
Scheduled Task 是带时间或事件触发器的 Task。它不是 Schedule 定义与临时 Task 的松散组合,
也不创建第二条 Conversation。
Scheduled Task 是带时间或事件触发器的 Task。每个 Scheduled Task 关联一条 Conversation
条 Conversation 可以同时承载多个 Task
创建 Scheduled Task 时:
1. 创建一个 Task
2. 为该 Task 创建唯一 Conversation
3. 保存 Schedule/Trigger Binding
4. 每次触发在同一 Task 内创建新的 Job 和 Run
5. 将面向用户的进展和结果持续写回同一 Task Conversation
1. 用户选择关联当前 Conversation 或创建新 Conversation
2. 系统创建一个 Task,并保存稳定 `conversationId` 和 Schedule/Trigger Binding
3. 每次触发在同一 Task 内创建新的 Job 和 Run
4. 面向用户的文本进展和结果写回关联 Conversation,并标明 Task 来源
5. 独立交付物保存为 Artifact,并由结果消息引用
因此,一个每日任务在 Task Center 中始终是一条 Task,而不是每天新增一条 Task
因此,一个每日任务在 Task Center 中始终是一条 Task,而不是每天新增一条 Task;左侧会话
列表通过行首展开按钮和带任务图标的子项呈现其关联。
## 2. 当前能力
## 2. 当前能力与差距
GoodBuddy 当前支持单次、每日和每周触发固定 Ask 提示,并持久化计划、Task、运行状态和成果。
近期改进不得破坏现有数据、错过执行结算、暂停、立即运行和应用退出行为。
GoodBuddy 当前已实现首期统一生命周期:
- 创建 Modal 可以关联当前 Conversation 或原子创建新 Conversation,不修改当前
Conversation 的标题和既有消息。
- 每个 Schedule 绑定一个稳定产品级 Task 和 Conversation;重复触发复用同一身份,不再
为每次触发创建新的顶层 Task。
- 默认选择 Execute,并允许用户主动切换 Ask;不支持工具执行时明确禁用 Execute。
- 单次、每日和每周计划支持暂停、恢复、立即运行、应用重启恢复和最多 4 个独立计划并发。
- 文本结果和失败写回关联 Conversation 并带 Task 来源;独立文件和图片继续保存为 Artifact。
- 左侧 Conversation 列表、Conversation Task 区和 Task Center 使用同一产品 Task;普通
模型请求、Subagent、委派和 Smart Heartbeat 内部 Task 不进入产品索引。
- v22 迁移保留 Schedule 配置和历史运行,并为旧计划补齐稳定 Task 与 Conversation。
尚未实现的高级能力包括 IANA 时区与 DST 墙上时间、每月/工作日/受限 Cron、事件触发、
可配置错过执行策略、租约、重试与结果未知治理、完整预算和权限快照,以及面向内部
Job/Subjob/Run 的统一持久化抽象。当前每日和每周按既有 UTC 间隔递推。
## 3. 目标
- 支持单次、每日、每周、每月、工作日和受限 Cron。
- 支持 Task 完成、失败、Conversation 完成等内部事件触发。
- 允许自然语言生成结构化草稿,但必须由用户检查后启用
- 创建时明确选择当前或新 Conversation
- 默认使用 Execute,并允许用户主动切换到 Ask。
- 冻结 Project、Runtime、工作目录、工具、知识、记忆和审批范围。
- 提供时区、错过执行、幂等、租约、重试、恢复、取消、预算和审计。
- 让所有重复触发复用同一 Task Conversation。
- 让所有重复触发复用同一 Task Conversation 关联
- 为一次触发建立清晰 Job/Run,而不是创建新的顶层 Task。
## 4. 非目标
- 不提供任意脚本和循环的通用 DAG 编辑器。
- 不允许模型生成并直接执行任意 Shell、SQL 或无限频率 Cron。
- 不允许模型生成并直接启用任意 Shell、SQL 或无限频率 Cron。
- 不承诺应用退出后继续运行。
- 不允许计划静默扩大权限、目录、知识记忆范围。
- 不允许后台计划静默扩大权限、目录、知识记忆或网络范围。
- 不把 Smart Heartbeat 变成 Scheduled Task。
- 不把每次触发重试显示为新的 Task。
- 不把每次触发重试、Job 或 Run 显示为新的顶层 Task。
- 不在左侧会话列表继续展开 Job、Subjob 或 Run。
## 5. 创建与配置
## 5. 创建入口与 Modal
用户可以输入自然语言意图:
Task Center 和 Conversation 操作都可以提供“新建定制任务”,但共用同一个 Modal,不在
窄侧栏长期展开完整表单。
```text
每周五下午 5 点总结本项目本周完成和失败的工作,
列出下周三个优先事项,不要修改文件。
新建定制任务
创建一个可以按计划自动运行,并持续记录在会话中的任务
任务名称 *
[ 每周项目总结 ]
任务要求 *
[ 总结本周完成和失败的工作,并列出下周优先事项。 ]
关联会话
◉ 当前会话
产品发布讨论 · GoodBuddy Desktop · 已有 2 个任务
○ 新建会话
为任务创建一条新会话,默认标题为任务名称
执行模式
[ Execute ] [ Ask ]
运行频率
[ 单次 ] [ 每日 ] [ 每周 ] [ 每月 ] [ 工作日 ] [ Cron ]
首次运行 [ 2026-08-21 ] [ 17:00 ]
时区 [ Asia/Shanghai ▾ ]
执行范围
GoodBuddy Desktop · OpenCode · 项目工作目录
8 个工具可用 · 高风险操作需要审批 [编辑]
[取消] [创建任务]
```
模型只生成草稿:
### 5.1 Conversation 选择
- 名称和说明
- 时间或事件触发器
- 工作模式和 Runtime 建议
- Project、知识、记忆、目录和工具范围
- 输入、输出和通知
- 预算、并发和错过执行策略
- 从当前聊天发起时默认选择当前 Conversation
- 从 Task Center 发起时默认选择新 Conversation
- 当前选择必须持续可见,不能根据入口静默决定后隐藏
- 关联当前 Conversation 不修改其标题、既有消息和普通聊天能力
- 当前 Conversation 已有关联 Task 时,显示 Task 数量和共享上下文说明
- 新 Conversation 默认使用 Task 名称作为标题,用户可以单独修改
- 远程通道、归档、正在删除或 Project 不匹配的 Conversation 不可选择,并显示原因。
用户确认后,系统一次性创建 Task、Conversation 和 Schedule Binding。编辑计划只影响后续
Job;已启动 Run 使用冻结快照。
### 5.2 创建摘要
## 6. 触发器
提交前显示确定性摘要:
### 6.1 时间触发
```text
✓ 为当前 Conversation 新增一个 Task
✓ 在左侧会话列表显示“任务 3”
✓ 默认以 Execute 模式运行
✓ 每周五 17:00 自动执行此 Task
✓ 文本结果写入当前 Conversation
✓ 独立交付物保存到成果
```
创建 Task、可选新 Conversation、关联关系和 Schedule Binding 必须在 Main 中原子提交。
失败时保持 Modal 和用户输入,不只显示短暂通知。提交期间锁定重复操作。
### 5.3 Modal 行为与无障碍
- 使用 `role="dialog"``aria-modal="true"`、稳定标题和说明关联。
- 打开后聚焦首个必填字段,Tab 焦点限制在 Modal 内。
- Escape 在未提交时关闭并恢复触发按钮焦点。
- 窄窗口使用接近全宽布局,保留 `16px` 外边距。
- 字段错误靠近字段;非字段异步错误保留在 Modal 内并提供重试。
## 6. 工作模式、Runtime 与工具
### 6.1 默认 Execute
创建 Modal 默认选择 Execute
- Execute 可以调用当前 Runtime 与 Project 已启用、且被 Task 快照允许的工具。
- Ask 保持 Runtime 边界只读,只能调用允许的只读能力。
- 所选 Runtime 不支持工具执行时,不能静默降级为 Ask;用户必须更换 Runtime 或主动选择
Ask。
- Modal 持续显示实际 Runtime、Project、工作目录和权限摘要。
### 6.2 权限快照
Task 创建时冻结:
- Project 和工作目录。
- Runtime 与模型选择。
- 工作模式。
- Skills、MCP、知识库、记忆和上下文范围。
- 可用工具与审批策略。
- 预算、并发和输出限制。
后续设置变化不修改已启动 Run。编辑 Task 配置只影响后续 Job。
### 6.3 审批
- Execute 继续遵守当前 Runtime、GoodBuddy 原生能力和工具审批控制。
- 已启用且按现有策略允许自动执行的工具可以在后台运行。
- 需要额外确认的动作进入 `waiting_approval`,暂停所属 Job 并发送应用内及桌面通知。
- 用户批准后继续同一个 Job/Run;拒绝后按协议失败、跳过或请求调整。
- 定时触发不能把高风险、越界或未授权动作转换成自动批准。
- 结果未知的外部副作用进入 `outcome_unknown`,不得自动重试。
## 7. 触发器
### 7.1 时间触发
```ts
type TimeTrigger =
@@ -96,10 +199,12 @@ type TimeTrigger =
}
```
“工作日”是 `weekly` 的周一至周五预设,不增加新的持久化触发类型。
受限 Cron 使用五字段,不支持秒、年份、宏、`L``W``#` 或供应商扩展。Main 负责解析,
默认最小间隔为 15 分钟,并展示未来五次触发时间。
### 6.2 事件触发
### 7.2 事件触发
后续支持:
@@ -112,27 +217,80 @@ type TimeTrigger =
事件触发配置来源范围、确定性过滤、去重窗口、冷却时间和并发上限。基础匹配不调用模型。
### 6.3 手动触发
### 7.3 手动触发
“立即运行”在当前 Task 内创建独立 Job 和 Run,不改变下一次计划时间,不创建新 Task。
重复点击使用调用级幂等键去重。
## 7. 一次触发的对象关系
## 8. 一次触发的对象关系
```text
Scheduled Task
Conversation(持续复用)
├─ Schedule Binding
└─ Job: scheduled_occurrence
└─ Run
Conversation
Scheduled Task
├─ Schedule Binding
└─ Job: scheduled_occurrence
└─ Run
```
- `scheduledFor` 和计划版本形成幂等键。
- 同一 Scheduled Task 默认最多一个活动 occurrence Job。
- 若允许并行 occurrence,它们仍属于同一 Task Conversation,并由协调器有序汇总
- 重试产生新 Run,不产生新 Task 或新 Job。
- 若允许并行 occurrence,它们仍属于同一 Task,并由协调器有序写回关联 Conversation。
- 重试产生新 Run,不产生新 Task 或新 occurrence Job。
## 8. 错过执行
## 9. 左侧会话列表
普通 Conversation 保持单行。包含 Task 的 Conversation 显示行首展开按钮:
```text
▾ 产品发布讨论 10:24
▣ 每周进度总结
每周五 17:00 · Execute · 下次 8 月 21 日
▣ 发布前检查
单次 · Execute · 等待确认
```
- 父会话行不重复显示任务标签或数量;Task 身份只在展开后的子项中使用稳定任务图标表达。
- 点击 Conversation 标题打开聊天;点击 Task 子项打开同一 Conversation 并定位到该 Task。
- 新建 Task 成功后首次自动展开。用户手动折叠后持久化其选择,后台运行不强制展开。
- 默认最多直接显示 3 个 Task;“查看全部 N 个任务”打开该 Conversation 的完整 Task 区。
- Task 子项显示本地化的模式、计划和状态文字;状态不能只靠任务图标颜色表达。
- 左侧只展开 Task;当前产品 UI 的其他区域也不提供 Job/Run 树或独立导航。
## 10. Conversation 内呈现
打开包含 Task 的 Conversation 后,顶部提供可折叠 Task 条:
```text
本会话有 2 个任务
[每周进度总结] [发布前检查] [管理任务]
```
选中 Task 后显示:
- 名称、状态和模式。
- 计划、下次执行和未来预览。
- 最近一次执行结果。
- “立即运行”“暂停”“编辑计划”等操作。
- 需要审批时的明确恢复入口。
每条自动结果消息显示 Task 名称、触发来源和时间。普通文本作为消息保存;文件、图片、PDF 和
其他独立交付物保存为 Artifact,并从消息引用。多个 Task 并发时,最终文本以完整消息写入,
不能把流式 Token 无序混入同一消息时间线。
## 11. Task Center
Task Center 显示 Scheduled Task 的范围、关联 Conversation、状态、模式、最近进展、需要
关注和下次触发时间:
- 点击条目打开关联 Conversation,并定位到该 Task。
- “立即运行”在内部创建 Job/Run,但 UI 仍只呈现 Task,不改变计划时间。
- 暂停只阻止新 Job,不取消已经完成的外部副作用。
- Task Center 是完整索引;左侧展开列表只是最近 Conversation 下的轻量入口。
- 不新增平行 Automation Center。
## 12. 错过执行
| 策略 | 行为 |
| --- | --- |
@@ -142,85 +300,56 @@ Scheduled Task
默认补跑最多 3 次、最多回溯 7 天。补跑同样受 Task 的并发、权限和预算控制。
## 9. 时区和夏令时
## 13. 时区和夏令时
- 保存 IANA 时区,不保存固定 UTC 偏移。
- 春季不存在的本地时间在当日第一个有效分钟触发。
- 秋季重复时间只触发一次。
- 系统时区变化不自动修改计划时区。
- UI 显示计划时区、本机时区差异和未来触发时间。
- UI 显示计划时区、本机时区差异和未来五次触发时间。
## 10. Ask、Execute 与审批
## 14. 预算、恢复和删除
第一阶段保持 Ask
每个 Scheduled Task 配置最大 Job 耗时、模型/Token/工具调用、成果大小、活动 Job 数和后台
优先级。前台请求优先,后台达到上限时记录 `deferred`
- 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。
- 删除 Schedule 只停止后续触发,不删除 Task、Conversation 或历史。
- 删除 Task 停止其计划并移除关联,默认保留 Conversation 和既有消息。
- 删除 Conversation 前显示关联 Task 数量,并先处理活动 Job。
## 13. 界面
Task Center 显示 Scheduled Task 的范围、状态、最近进展、需要关注和下次触发时间。点击条目
打开同一 Task Conversation。
Task 内可查看:
- 计划和触发器。
- 下次执行和未来预览。
- 每次 occurrence Job。
- Run、审批、活动和成果。
不新增平行 Automation Center。
## 14. 兼容迁移
## 15. 兼容迁移
现有 Schedule、Schedule Run、Task 和 Conversation 数据渐进关联:
- 保留现有计划 ID、启停状态、下次时间和历史。
- 为每个现有计划建立或绑定一个持续 Task Conversation
- 为每个现有 Schedule 创建一个稳定产品级 Task
- 旧 Schedule 不猜测绑定已有用户 Conversation;为其创建新的关联 Conversation。
- 历史每次执行映射为该 Task 下的 occurrence Job/Run。
- 迁移不得复制消息、成果或顶层 Task。
- 旧执行产生的 Task 行在映射成功后不再作为产品级 Task 索引,但其状态、活动和成果继续
通过迁移后的 Job/Run 归属保留。
- 旧文本 Artifact 可以保留,但迁移不得把它们重复写成新消息。
- 迁移不得复制用户消息、独立成果或顶层 Task。
## 15. 验收标准
## 16. 验收标准
- [ ] 创建 Scheduled Task 只创建一个 Task 和一个 Conversation。
- [ ] 重复触发始终复用该 Task Conversation
- [ ] 每次触发创建 Job/Run,不创建新的顶层 Task。
- [x] 创建 Scheduled Task 可以选择当前或新 Conversation。
- [x] 关联当前 Conversation 不修改其标题、类型或既有消息
- [x] 一条 Conversation 可以在左侧展开一个或多个 Task。
- [x] 默认工作模式为 Execute,且用户可以主动选择 Ask。
- [ ] Execute 能调用快照允许的工具,但不能绕过 Runtime 和审批控制。
- [x] 不支持工具的 Runtime 不会让 Execute 静默降级。
- [x] 重复触发始终复用同一 Task 和 Conversation 关联。
- [x] 每次触发创建内部运行记录,不创建新的顶层 Task。
- [x] 内部运行记录只用于执行和审计,不在 UI 中显示为独立层级。
- [ ] 支持单次、每日、每周、每月、工作日和受限 Cron。
- [ ] UI 显示计划时区和未来五次触发时间。
- [ ] 夏令时不会造成漂移或双跑。
- [ ] 错过执行按配置跳过、补一次或有界补跑。
- [ ] 手动运行不改变下次计划时间。
- [ ] Ask 在 Runtime 边界拒绝写操作和外部副作用
- [x] 手动运行不改变下次计划时间。
- [x] 文本结果只写入 Conversation,独立交付物才进入成果
- [ ] Task Center 和桌面通知可以打开正确 Conversation 并定位 Task。
- [ ] 应用重启不自动重放结果未知的副作用。
- [ ] Task Center 不因重复触发新增条目。
+150 -59
View File
@@ -4,8 +4,8 @@
| 项目 | 内容 |
| --- | --- |
| 状态 | 产品边界已确认,部分能力待实施 |
| 版本 | 0.1 |
| 状态 | 产品边界与 Scheduled Task 首期已实现;通用 Job/Run 能力待实施 |
| 版本 | 0.3 |
| 日期 | 2026-08-19 |
| 适用产品 | GoodBuddy 桌面端 |
| 文档角色 | Task、Conversation、Job、Run 与 Subagent 的权威定义 |
@@ -14,25 +14,34 @@
### 1.1 Task
Task 是用户明确创建或由已启用计划创建的工作单位,也是 Task Center 的顶层对象。
Task 是用户明确创建或确认的工作单位,也是 Task Center 的顶层对象。
- 创建 Task 就创建一条新的 Conversation。
- Task 的内容载体是这条 Conversation不再维护第二份任务正文或消息时间线
- 打开 Task 就打开其 Conversation
- Task 的目标、状态、范围、计划、Job、审批、活动和成果都围绕同一 Conversation 组织
- 一个 Task 在生命周期内保持同一个 `taskId``conversationId` 绑定
- 每个 Task 必须关联且只关联一条 Conversation。
- 创建 Task 时,用户可以关联当前 Conversation也可以同时创建一条新 Conversation
- 关联当前 Conversation 不改变其对象类型、标题、既有消息或普通聊天能力,只增加 Task
关联及其可见入口
- Task 的目标、状态、范围、计划、Job、审批、活动和成果使用独立 Task 身份保存
- 打开 Task 会打开关联的 Conversation,并定位或展开对应 Task。
- 一个 Task 在生命周期内保持稳定的 `taskId``conversationId` 关联。
- 删除 Task 默认停止其计划并移除关联,不删除 Conversation 或既有消息。
普通 Conversation 不自动成为 Task。用户只是聊天时,不应因为存在模型调用或工具步骤就
产生顶层 Task。
普通模型请求、工具调用或 Runtime Run 不自动成为产品级 Task。只有用户明确创建、确认或
由已启用产品流程创建的工作,才进入 Task Center 和 Conversation 的 Task 列表
### 1.2 Conversation
Conversation 是 Task 的交互和内容载体:
Conversation 是用户消息、助手消息和面向用户结果的内容容器,不因为关联 Task 而变成另一
种 Conversation
- 保存用户消息、助手消息和面向用户的进展
- 承载同一 Task 内多个 Job 的可理解汇总。
- 不让并行 Job 直接无序写入同一消息流;由 Task 协调器合并进展和结果
- 删除、归档和切换范围时遵循 Task 的生命周期规则
- 一条 Conversation 可以不关联 Task,也可以关联一个或多个 Task
- 多个 Task 可以共享同一 Conversation 的可见上下文,但各自拥有独立配置、计划、权限
快照、状态、Job、Run 和成果引用
- Conversation 标题与 Task 名称相互独立。创建或重命名 Task 不静默修改现有会话标题
- 左侧会话列表根据显式 Task 关联显示行首展开按钮;父会话行不重复任务标签,展开后的
Task 子项使用任务图标,并只展开到 Task 层。
- 并行 Job 不直接无序写入消息流;进度留在各自 Task/Job 状态中,最终文本以带来源元数据
的完整消息写入 Conversation。
- 删除 Conversation 前必须说明关联 Task 数量,并先停止或结算仍活动的 Job。
### 1.3 Job
@@ -40,9 +49,10 @@ Job 是 Task 内部的执行单位,不是新的顶层 Task:
- 一次计划触发、一个执行步骤、一项专家委派或一组并行工作都可以是 Job。
- 一个 Task 可以串行或并行运行多个 Job。
- 所有 Job 仍属于同一个 Task 和同一条 Conversation。
- 所有 Job 仍属于同一个 Task,并通过该 Task 关联的 Conversation 呈现用户可见结果
- Job 可以有自己的状态、预算、Runtime、执行者、输入快照和成果引用。
- Job 不进入 Task Center;它显示在 Task 的时间线、活动或 Runtime 视图中。
- Job 不进入 Task Center、左侧会话列表或独立详情页。当前产品 UI 的对象层级止于 Task;
活动和 Runtime 只按 Task 展示有界执行事件、工具、审批与错误,不呈现 Job 树。
### 1.4 Subjob
@@ -50,16 +60,17 @@ Subjob 是 Job 的子执行单元。它用于分解和并发,不创建新的 T
- 父 Job 负责合并 Subjob 结果。
- 取消父 Job 必须传播到仍活动的 Subjob。
- Subjob 不能扩大父 Job 的项目、目录、工具、知识、记忆或审批范围。
- Subjob 不能扩大父 Job 的 Project、目录、工具、知识、记忆或审批范围。
- 深度、数量、并发、时间、Token 和输出大小必须有界。
### 1.5 Run
Run 是 Task 或 Job 的一次执行尝试和审计记录,不是用户工作对象:
Run 是 Job 或 Subjob 的一次执行尝试和审计记录,不是用户工作对象:
- 重试、恢复或手动重新运行可以产生新的 Run。
- Run 冻结当次配置、范围、预算Runtime。
- Run 进入活动记录和审计,不进入 Task Center。
- Run 冻结当次配置、范围、预算Runtime 和权限策略
- Run 进入内部审计;当前 UI 可以显示某次 Task 执行的时间、状态和活动,但不把 Run 呈现为
可导航的产品对象。
- `completed` 只表示该次执行按协议结束,不必然表示 Task 目标达成。
### 1.6 Subagent
@@ -68,84 +79,164 @@ Subagent 是执行 Job 或 Subjob 的受限执行者,不是对象层级:
- 专家、Agent Runtime 或其他执行器可以承担 Job。
- Subagent 不自动拥有独立 Task 或 Conversation。
- Subagent 输出先回到所属 Job,再由 Task 协调器写入同一 Conversation。
- Subagent 输出先回到所属 Job,再由 Task 协调器写入关联 Conversation。
## 2. 对象关系
```text
Task 1 ── 1 Conversation
├─ Schedule / Trigger Binding(可选)
├─ Job 1
│ ├─ Run 1..N
│ └─ Subjob 0..N
├─ Job 2(可与 Job 1 并行)
└─ Artifact / Approval / Activity / Notification
Conversation 1 ── 0..N Task
├─ Schedule / Trigger Binding(可选)
├─ Job 1
│ ├─ Run 0..N
│ └─ Subjob 0..N
│ └─ Run 0..N
├─ Job 2(可与 Job 1 并行)
└─ Artifact / Approval / Activity / Notification
```
从 Task 方向看:
```text
Task N ── 1 Conversation
```
不允许:
```text
Task → 第二条 Conversation
Task → 没有关联 Conversation
Task → 同时关联多条 Conversation
Job → 新建顶层 Task
Subagent → 自动新建 Conversation
Run → 出现在 Task Center
Job / Run → 成为可独立导航的 UI 对象
```
## 3. Scheduled Task
## 3. 创建 Task
Scheduled Task 仍然是 Task,而不是独立的自动化对象
创建定制 Task 时必须明确选择 Conversation
1. 用户创建 Scheduled Task。
2. 系统创建一个 Task 和一个 Conversation,并保存 Schedule/Trigger Binding。
```text
关联当前 Conversation
创建新 Conversation
```
- 从当前聊天发起时,默认选择当前 Conversation。
- 从 Task Center 发起时,默认选择新 Conversation。
- 选择当前 Conversation 时持续显示会话标题、Project 和已有 Task 数量。
- 选择新 Conversation 时,默认使用 Task 名称作为会话标题,但允许用户修改。
- Task、Conversation 关联和可选 Schedule Binding 必须在 Main 中原子创建或回滚。
## 4. Scheduled Task
Scheduled Task 仍然是 Task,而不是 Schedule 定义和临时 Task 的松散组合:
1. 用户选择当前或新 Conversation。
2. 系统创建一个 Task,建立稳定 `conversationId` 关联,并保存 Schedule/Trigger Binding。
3. 到期时在该 Task 内创建新的 Job 和 Run。
4. 每次触发的进展和结果入同一个 Task Conversation。
5. 编辑计划影响后续 Job,不修改已经启动的 Run
4. 每次触发的进展和文本结果入同一关联 Conversation。
5. 独立文件、图片和其他交付物保存为 Artifact,并从结果消息引用
6. 编辑计划影响后续 Job,不修改已经启动的 Run。
同一 Scheduled Task 默认串行触发。需要并行时,应显式允许多个 Job 并发,并继续使用同一
Conversation,而不是复制 Task。
Task 和 Conversation 关联,而不是复制顶层 Task。
## 4. 状态分层
## 5. 消息归属
Task 产生的用户可见消息至少记录:
```ts
type TaskMessageMetadata = {
taskId: string
jobId: string
runId: string
trigger: 'manual' | 'scheduled' | 'event' | 'goal'
}
```
同一 Conversation 关联多个 Task 时:
- 消息持续显示来源 Task 名称。
- 点击左侧展开项或 Task Center 条目可以定位对应 Task 和近期消息。
- 任务筛选只改变定位和高亮,不隐藏用户未主动筛选的普通消息。
- 多个活动 Job 的流式细节进入各自活动记录,最终文本有界持久化后再写入 Conversation。
## 6. 状态分层
| 层级 | 典型状态 | 用户在哪里看到 |
| --- | --- | --- |
| Task | queued、running、waiting_approval、paused、completed、failed、cancelled、interrupted | Task Center、Task Conversation |
| Job | queued、running、waiting、completed、failed、cancelled | Task 时间线、活动、Runtime |
| Run | claimed、running、completed、failed、cancelled、interrupted、budget_exceeded | 活动与审计 |
| Task | idle、queued、running、waiting_approval、paused、completed、failed、cancelled、interrupted | Task Center、左侧会话展开项、Conversation |
| Job | queued、running、waiting_approval、completed、failed、cancelled | 内部协调与审计,不作为 UI 对象 |
| Run | claimed、running、completed、failed、cancelled、interrupted、budget_exceeded、outcome_unknown | 内部执行与审计,不作为 UI 对象 |
Task 状态由当前目标和所属 Job 聚合得出,但不能用“任一 Job 完成”直接推断 Task 完成。
Conversation 折叠行只显示其关联 Task 中最高优先级的关注状态:
## 5. 兼容映射
```text
waiting_approval > failed > running > paused > idle
```
## 7. UI 展示边界
当前产品 UI 的对象层级统一止于 Task:
- 左侧会话列表展开到 Task。
- Task Center 只索引 Task。
- Conversation 顶部任务区只选择和管理 Task。
- 活动与 Runtime 可以展示 Task 的执行时间、工具、审批、错误、成果和状态事件,但不显示
Job/Subjob 树,不提供 Job/Run 路由、列表或独立操作菜单。
- “立即运行”“重试”和“恢复”在 UI 上都是 Task 操作;Job/Run 只在内部创建和审计。
## 8. 左侧 Conversation Task 列表
左侧最近会话列表是轻量发现入口,不替代 Task Center
- 无 Task 的 Conversation 保持现有单行样式。
- 有 Task 的 Conversation 显示行首展开按钮,父会话行不重复任务标签或数量。
- 展开后只显示带任务图标和本地化摘要的 Task,不继续显示 Job、Subjob 或 Run。
- 新建 Task 成功后首次自动展开;用户手动折叠后保持选择,后台状态变化不强制展开。
- 默认最多直接显示 3 个 Task;“查看全部 N 个任务”打开该 Conversation 的完整 Task 区。
- Task 子项的任务图标表示身份;运行、审批、失败和暂停同时使用本地化状态文字。
- 删除最后一个关联 Task 后,Conversation 的展开按钮自动消失。
## 9. 兼容映射
当前代码和旧文档中的对象按以下方式收敛:
| 旧概念 | 目标概念 |
| --- | --- |
| 自动任务 | Scheduled Task、Event Task 或 Goal Task |
| 自动会话 | 删除该独立概念,使用 Task Conversation |
| 自动会话 | 删除该独立概念,使用关联 Conversation |
| 子任务、Child Task | Job 或 Subjob |
| 专家子任务 | 由专家 Subagent 执行的 Job/Subjob |
| 多任务并行 | 一个 Task 内多个并行 Job确实独立的用户目标才创建多个 Task |
| 多任务并行 | 一个或多个 Task 下的并行 Job根据用户目标和 Conversation 归属明确建模 |
| Schedule Run | Scheduled Task 内的 Job Run |
| Automation Run | Task 或 Job 的 Run |
| Automation Run | Task 所属 Job 或 Subjob 的 Run |
| 普通请求 Task 行 | 内部执行/审计记录,不自动成为产品级 Task |
数据库字段可以在兼容期保留旧名称,但新产品文案、PRD 和新增契约必须使用本模型。
## 6. 安全和数据要求
## 10. 安全和数据要求
- Main 验证 Task、Conversation、Job、Run 和 Project 的归属链。
- Renderer 不能把任意 Job 绑定到其他 Task 或 Conversation。
- Job/Subjob 继承父级能力上限,只能缩小,不能扩大
- Main 验证 Conversation、Task、Job、Run 和 Project 的完整归属链。
- Task 只能关联同一 Project 范围内允许使用的 Conversation。
- Renderer 不能把任意 Task 或 Job 绑定到其他 Project 的 Conversation
- Job/Subjob 继承 Task 的能力上限,只能缩小,不能扩大。
- Execute Task 冻结 Runtime、工作目录、工具和审批策略;后台触发不能扩大权限。
- 并行输出先有界持久化,再按确定顺序汇总到 Conversation。
- 取消、超时、审批和应用退出必须沿 Task → Job Subjob → Runtime 传播。
- 用户删除 Task 时,先处理活动 Job,再按数据保留规则清理关联对象
- 取消、超时、审批和应用退出必须沿 Task → Job / Subjob → Run → Runtime 传播。
- 删除 Task 默认保留 Conversation 和消息;删除 Conversation 必须处理其全部关联 Task
## 7. 验收原则
## 11. 验收原则
- [ ] 创建 Task 时只创建一条对应 Conversation。
- [ ] Scheduled Task 的重复触发复用同一 Task Conversation
- [ ] 一个 Task 可以在同一 Conversation 下运行多个并行 Job
- [ ] Job、Subjob、Run 和 Subagent 不进入 Task Center
- [ ] 每个 Task 只关联一条 Conversation。
- [ ] 一条 Conversation 可以关联零个、一个或多个 Task
- [ ] 创建 Task 可以选择当前 Conversation 或新 Conversation,且不会改变当前会话类型
- [ ] 左侧会话列表通过行首按钮展开带任务图标和本地化摘要的 Task,但不展开 Job/Run
- [ ] 当前 UI 不提供 Job、Subjob 或 Run 的独立列表、树、路由或操作菜单。
- [ ] Scheduled Task 的重复触发复用同一 Task 和 Conversation 关联。
- [ ] 一个 Task 可以运行多个串行或并行 Job。
- [ ] Job、Subjob、Run 和 Subagent 不进入 Task Center,也不成为其他可导航 UI 对象。
- [ ] Task 消息可以通过 `taskId``jobId``runId` 追溯来源。
- [ ] 并行 Job 不直接无序写入 Conversation。
- [ ] 取消和权限范围能够沿层级正确传播。
- [ ] 新文档不再把 Job/Subjob 定义为新的顶层 Task。
+77 -16
View File
@@ -4,56 +4,117 @@
| 项目 | 内容 |
| --- | --- |
| 状态 | 设计中 |
| 版本 | 0.1 |
| 状态 | Scheduled Task 首期已实现;Goal/Event Task 与完整操作待实施 |
| 版本 | 0.3 |
| 日期 | 2026-08-19 |
| 依赖 | [Task 与 Job 统一领域模型](./task-and-job-model.md) |
| 界面归属 | [通用助手工作栏与执行空间](../assistant-experience/assistant-workbar-and-execution-spaces-prd.md) |
## 1. 产品定义
Task Center 是所有 Task 的应用级单例索引。它不是第二份任务数据,也不是 Automation
Center。点击条目直接打开 Task 自身的 Conversation
Task Center 是所有产品级 Task 的应用级单例索引不是 Automation Center,也不复制
Conversation 内容。点击条目打开其关联 Conversation,并定位或展开对应 Task
每个 Task 只关联一条 Conversation;一条 Conversation 可以关联零个、一个或多个 Task。
Conversation 不因为关联 Task 而改变对象类型。
## 2. 收录边界
收录:
- 用户明确创建的 Task。
- 用户明确创建或确认的 Task。
- Scheduled Task、Event Task 和 Goal Task。
- 未来由用户确认创建的其他顶层 Task。
不收录:
- 普通 Conversation。
- 没有显式 Task 关联的普通 Conversation。
- 普通模型请求或工具调用产生的内部执行记录。
- Job、Subjob、Run、工具步骤或 Subagent。
- Smart Heartbeat 配置、报告和建议。
- 仅用于审计的活动记录。
当前产品 UI 的对象层级止于 Task。Task Center、左侧会话列表和 Conversation 任务区都不显示
Job/Subjob/Run 树、独立详情或路由。
## 3. 列表信息
每条 Task 至少显示:
- 名称和 Global / Project 范围。
- 关联 Conversation 标题。
- Task 类型和触发来源。
- Ask / Execute 模式。
- 当前聚合状态。
- 最近一次面向用户的进展。
- 最近活动时间。
- 等待审批、失败或需要关注数量
- 等待审批、失败或需要关注状态
- 下次计划时间(如适用)。
Task 行只显示聚合后的用户状态,不要求用户理解内部 Job/Run。
## 4. 交互
- 点击条目打开 Task Conversation。
- 点击条目打开关联 Conversation,并定位到该 Task
- 支持按需要关注、进行中、已暂停、已结束筛选。
- 支持暂停、恢复、取消和打开详情,但不在窄栏复制完整 Job 时间线
- 支持立即运行、暂停、恢复、取消、编辑和删除
- 后台变化更新状态和徽标,不自动抢占当前页面。
- Task 的计划、JobRun、审批和成果在 Task 自身或对应活动视图管理
- 立即运行、重试和恢复在 UI 上都是 Task 操作,内部 Job/Run 不单独显示
- 完整消息留在 Conversation;工具、审批和错误可以在活动或 Runtime 中按 Task 查看;
独立交付物在成果中查看。
## 5. 验收标准
## 5. 左侧 Conversation Task 列表
- [ ] Task Center 只展示 Task。
- [ ] 点击 Task 不会跳转到另一条内容相同的附属 Conversation。
- [ ] Job/Subjob/Run 不会重复成为顶层条目。
- [ ] Scheduled Task 显示下次时间,但每次触发不新增 Task 条目。
- [ ] Smart Heartbeat 不进入 Task Center。
左侧最近会话列表承担轻量 Task 发现,不替代 Task Center
```text
▾ 产品发布讨论 10:24
▣ 每周进度总结
每周五 17:00 · Execute · 下次 8 月 21 日
▣ 发布前检查
单次 · Execute · 等待确认
```
- 无 Task 的 Conversation 保持现有单行样式。
- 有 Task 时在行最左侧显示独立展开按钮;父会话行不重复显示任务标签或数量。
- 会话标题溢出时保持时间和操作区固定;悬停会话行后,标题在自身裁切区域内横向滑动展示
完整名称。未溢出标题不滑动,减少动态效果偏好下使用完整标题提示而不产生位移。
- 展开后每个 Task 子项使用任务图标,并显示本地化的模式、计划和状态;不显示 Job、
Subjob、Run 或工具步骤。
- 点击 Conversation 标题打开聊天;点击 Task 打开同一 Conversation 并定位该 Task。
- 新建 Task 后首次自动展开;用户手动折叠后保持选择。
- 后台状态变化不强制展开;Task 状态持续显示在展开后的子项和 Task Center 中。
- 默认最多显示 3 个 Task;“查看全部 N 个任务”打开该 Conversation 的完整任务区。
## 6. Conversation 任务区
包含 Task 的 Conversation 顶部显示可折叠任务区:
```text
本会话有 2 个任务
[每周进度总结] [发布前检查] [管理任务]
```
选择 Task 后显示名称、模式、聚合状态、计划、下次执行、最近结果和 Task 级操作。工具、审批、
错误和成果通过 Task 关联显示,但不暴露 Job/Run 层级。
## 7. 删除关系
- 删除 Schedule 只停止后续触发,不删除 Task、Conversation 或历史。
- 删除 Task 停止其计划并移除关联,默认保留 Conversation 和既有消息。
- 删除最后一个 Task 后,左侧 Conversation 的展开按钮消失。
- 删除 Conversation 前必须显示关联 Task 数量,并先停止或结算活动执行。
## 8. 验收标准
- [x] Task Center 只展示产品级 Task。
- [x] 一条 Conversation 可以关联并展开多个 Task。
- [x] 点击 Task 打开正确 Conversation 并定位到对应 Task。
- [x] 左侧会话列表通过独立展开按钮显示带任务图标和本地化摘要的 Task 子项。
- [x] 当前 UI 不显示 Job/Subjob/Run 树或独立页面。
- [x] Scheduled Task 显示下次时间,但每次触发不新增 Task 条目。
- [x] 普通模型请求和工具调用不会误显示为 Task。
- [ ] 删除 Task 默认保留 Conversation 和既有消息。
- [x] Smart Heartbeat 不进入 Task Center。