- 看板: 907 补注/909~941 登记与销账(含 929 模型停用根因与 4 处次生缺口、931 队列丢失、933/935/937 新需求、939 上下文瓶颈清单、941 C-r0 行为变更待拍板) - 归档: 全量完成态条目/段落 + 只读核验销账 4 段迁 todo归档/2026-10-10.md(机械搬运零措辞改动,未完成项零丢失) - 设计档: 输入框列表预览与自动编号 / 定时消息与待发箱持久化(统一 ai_outbox 底座) / 对话内定时延时任务 / 消息渲染管线重构(P0-P2 分期) / 上下文分层组装器落地方案(记账基点单一真值,与并行写者职责划清) / FileTree 大目录方案(推荐后端分页,否决虚拟滚动) / u-relay 运维手册 - 索引与事实修正: docs/INDEX crate 数 8→13 + 四子树补录 25 条 + 专项设计补录 27 条;纠正「项目无独立 ARCHITECTURE.md」等过时声明;统一 bun 口径 - CLAUDE.md: 新增「命名与代码风格」节(变量/方法名精简+准确;DRY·简洁·扩展性·高内聚低耦合·单一真值来源)
24 KiB
对话内定时/延时任务 — 设计
日期: 2026-10-10 | 状态: 设计稿(待拍板) | 需求锚点:
docs/todo.md:703条目 937 | 勘察: 只读实测(文件:行已核) 目标一句话: 在对话里直接说「1 小时后跑 X / 明早 9 点把任务 A 推进到审查」,系统登记一条持久化的kind='task'待发箱项,到点自动执行(注入发起会话续跑),任务卡显示「定时中/已触发」,并可在统一「定时列表」里查看/改期/取消。 边界: 仅设计,不改码。 与 935 的关系(要害): 937 不新造调度底座。表 / 调度器 / IPC / 事件 / KV / 「定时列表」抽屉全部复用定时消息与待发箱持久化-设计-2026-10-10.md(该设计已覆盖 todo 935 定时消息 + 931 队列,并在其 §3.1 明确预留kind='task'给 937、§五 P2 交棒)。本设计只定义kind='task'这一分支的语义 + AI 工具面 + 触发执行 + 权限边界。 关联: 并行化与异步唤醒-设计(§二 wake delay 型 / §6.3 挂机)/无人值守长任务-设计(TaskBoundary 边界)。
一、现状勘察(锚点实测)
1.1 AI 工具面(新工具的正确落点)
| 件 | 锚点 | 现状 |
|---|---|---|
| 注册宏 | crates/df-ai/src/ai_tools_decl.rs declare_tool! |
纯 macro_rules!,零新依赖;新工具只加一个 tools/<域>.rs 文件 + 在对应 register_* 接一行 |
| 注册总入口 | src-tauri/src/commands/ai/tool_registry.rs:541 build_ai_tool_registry |
register_data_tools(:735) 内 register_task_tools(:737)/register_workflow_tools(:739);二者已 thin 委托 tools::task::register(:767)/tools::workflow::register(:813) |
| 任务工具 | src-tauri/src/commands/ai/tools/task.rs |
6 个:list_tasks(:40)/create_task(:72)/advance_task(:185,状态机推进唯一合法路径)/delete_task/get_task_count。无任何「延后」维度 |
| 工作流工具 | src-tauri/src/commands/ai/tools/workflow.rs:35 run_workflow |
High 风险;handler 是防御兜底(返 Err),真正执行经 ai_approve → execute_run_workflow_for_tool(src-tauri/src/commands/ai/mod.rs:1367)→ run_workflow_inner(src-tauri/src/commands/workflow.rs:127);空 dag + target_status 时按 template_for(crates/df-nodes/src/task_workflow_templates.rs:28)自动选模板 |
| conv_id 透传先例 | execute_run_workflow_for_tool(mod.rs:1367) |
AI 工具 handler 无 State,发起会话 id 经调用方(task-local/参数)注入——schedule_task 记录发起会话照此 |
| 基线守卫 | tool_registry.rs 测试 test_build_ai_tool_registry_baseline_tool_count |
钉死工具名集合;新增工具须同步该断言(+1) |
1.2 任务体系与推进链(被定时触发的目标能力,均已就位)
| 件 | 锚点 | 现状 |
|---|---|---|
| 状态机 | crates/df-nodes/src/task_state_machine.rs |
8 态合法转换纯函数;done 唯一终态 |
| 原子推进 | crates/df-nodes/src/task_advance_node.rs:50 advance_task_atomic / :335 advance_task_with_parent |
状态机校验 + CAS + review_rounds + 父聚合,已与 IPC/AI 工具三方同源 |
结论: 「到点后要做的事」(推进任务/跑工作流/执行指令)能力齐备,缺的只是外部时间驱动源与工具面的延时表达。
1.3 后端常驻调度器先例(unattended;935 已定 outbox 抄其形态)
| 件 | 锚点 | 现状 |
|---|---|---|
| 常驻轮询 | src-tauri/src/commands/ai/unattended.rs:508 start;lib.rs:84 挂载 |
async_runtime::spawn + interval.tick() / notify.notified() select! |
| 共享态/唤醒 | unattended.rs:459 EngineShared{notify: Notify, in_flight,…};:483 notify_batch_done |
单在途 + 完成钩子即时唤醒 |
| 开工链路 | unattended.rs:847 spawn_agentic_session(chat.rs:796,10 参,pin_active=false) |
后台会话派发正典入口 |
| 生命周期事实 | lib.rs:614 on_window_event prevent_close+hide 托盘化 |
关窗=进程仍在=调度器照跑;进程退出=停,重启补发 |
关键缺口(937 视角): 引擎作业源是看板文件,不落库、不看时间点;真正解决「持久化 + 到点」的是 935 设计的 ai_outbox(见下节),937 直接搭车。
1.4 存储 / 恢复 / 事件 / UI 样板(937 复用链)
| 件 | 锚点 | 现状 / 复用点 |
|---|---|---|
| 迁移框架 | crates/df-storage/src/migrations.rs:9 run;调度数组 :108-121(止于 (50, migrate_v50) @ :1483) |
追加 (N, migrate_vN) 即挂;935 占 V51(建 ai_outbox),937 用 V52 加列 |
| 加列样板 | migrations.rs:1366 migrate_v45 |
column_exists 守卫 + ALTER TABLE ADD COLUMN,幂等可重跑;可 DROP COLUMN 回退 |
| 启动恢复样板 | audit/restore.rs:26 restore_pending_approvals |
从表重建内存态;outbox 的 reset_stale_sending 同款 |
| 会话来源 | models.rs:389 AiConversationRecord.origin(现仅 "sub_agent") |
定时触发落后台会话时可用新值 "schedule" |
| 事件 | mod.rs:134 AiChatEvent(#[serde(tag="type")]) |
935 定的 ai-outbox-changed/sent/failed 直接复用 |
| 卡片范式 | src/components/ai/TaskParkedCard.vue |
「定时任务卡」可照此(状态徽标 + 行为后更新) |
1.5 缺口清单(937 专属,底座缺口由 935 覆盖)
- 工具面无延时维度:LLM 无法表达「1 小时后」(
advance_task/run_workflow/create_task均即时)。 - 无
kind='task'分支:935 的ai_outbox表/调度器只服务消息派发,kind='task'的载荷字段(结构化指令/任务关联/边界快照)与派发目标(注入会话 or 直推任务)尚未定义。 - 无触发执行的落点语义:到点「谁来跑、跑哪个会话、结果给谁看」未定。
- 无对话内定时卡片:工具卡如何呈现「定时中/已触发」未定。
二、目标与验收口径
| 目标 | 验收口径(可实测) |
|---|---|
| G1 对话内创建 | LLM 调 schedule_task(instruction, delay_secs),对话出现定时任务卡(指令摘要 + 触发时刻/倒计时 + 「定时中」徽标);ai_outbox 落一行 kind='task', status=pending |
| G2 到点触发 | 到 due_at → 调度器把指令注入发起会话续跑(等价一条 user 消息注入),卡片变「已触发」,新 assistant 回复出现在原会话 |
| G3 持久存活 | 应用关闭跨过 due_at:关窗托盘化期间照常触发;进程真退出则重启后按 935 追赶策略(§四)补触发或标过期;卡片状态经重启不丢 |
| G4 管理面 | 统一「定时列表」(935 抽屉,937 项并列显示,类型标「任务」)可查看/改期/取消;改期/取消即时写库刷新卡片 |
| G5 边界合规 | 创建 = Medium 风险(走既有审批);触发执行零旁路——写/High 风险仍在触发会话内走既有 audit/path_auth;黑名单永不放行 |
| G6 不打架 | 触发时发起会话正生成 → 轮界排队(不打断);会话已删/不可用 → 回落独立后台会话(origin=schedule) |
| G7 零回归 | 既有 advance_task/run_workflow/create_task 行为不变;无 task 作业时调度器空转零副作用;935 的 queue/scheduled 分支不受影响 |
三、设计方案
3.1 总体判断(先说结论)
- 新工具
schedule_task,不复用advance_task加调度字段。advance_task的契约是「此刻」推进状态机(CAS +applied.matched_target断言,tools/task.rs:185),loop 收敛判定依赖它;改成「可能延后」会污染该断言并让「任务状态」与「调度时点」耦合。调度是正交能力:指令里可以提到任务,但调度本身不是状态迁移。 - 底座全复用 935 的
ai_outbox+outbox.rs调度器,937 只加kind='task'分支。 不新造表/不新造 loop,与需求「与 935 共用调度器」一致;亦避免「双调度器」的草率聚合。 - 触发执行的通用形态 = 注入发起会话(把指令当一条用户消息续跑),由触发后的 agentic loop 统一消化(它本就会
advance_task/run_workflow);确定性「直推任务状态」作 P2 快路径(§3.6、拍板点 4)。
3.2 数据形态:复用 ai_outbox + 迁移 V52 增列
935 已定义 ai_outbox(定时消息…设计 §3.1,V51),其列 text / skill / model_override / parts_json / spans_json / due_at / status / attempts 面向消息。937 复用其 text(= 指令原文,供统一列表渲染摘要)、due_at(= 触发时刻)、status、attempts,并新增三列承载 task 专属载荷:
-- 迁移 V52(937):幂等 ALTER(照 migrate_v45 样板),可 DROP COLUMN 回退
ALTER TABLE ai_outbox ADD COLUMN title TEXT; -- 卡片/列表标题(缺省取指令前 N 字)
ALTER TABLE ai_outbox ADD COLUMN payload_json TEXT; -- 结构化载荷 {instruction, task_id?, target_status?}
ALTER TABLE ai_outbox ADD COLUMN boundary_json TEXT; -- 触发执行继承的边界快照(可空=审批模式)
kind='task'行:text=指令人读文本(列表摘要用);payload_json={instruction, task_id?, target_status?}(instruction 冗余存一份便于派发时直接取;task_id/target_status 供 P2 直推快路径)。- 不新增独立表。
AiOutboxRecord(定时消息…设计§3.1)对应加三个Option字段;outbox_repo.rs的 insert/读方法带这三列(其余复用)。 - 迁移编号:935 占 V51,937 占 V52;若两需求同批落地,可合入一个迁移函数一次到位(建表 + 增列),但保持「V51 建表 / V52 增列」两段亦可(幂等,顺序无关)。
3.3 工具面:新增 schedule_task(declare_tool!,Medium)
新文件 src-tauri/src/commands/ai/tools/schedule.rs,仅一个工具;tool_registry.rs:737 旁接线(register_schedule_tools),基线测试 +1。
declare_tool!(
registry, db: Arc<Database>,
"schedule_task",
"登记一个定时/延时执行的任务作业:到点后在发起会话里自动执行 instruction(等价到点时我把这句话重新对你说一遍)。\
用 delay_secs 表达相对延时(如「1 小时后」=3600),或用 at 表达绝对时刻(RFC3339 或 epoch ms)。二者至少给一个,同时给以 at 为准。\
到点执行受既有审批/路径授权约束,不绕过任何安全闸。返回 job_id 与触发时刻。",
RiskLevel::Medium, // 登记未来自动执行,须人工知情(对齐 advance_task 的 Medium)
meta: ToolMeta {
entity_action: Some(("schedule", "create")),
approval_hint: Some(("创建定时任务:{}", &["instruction"])),
display_verb: Some("创建定时任务"),
..Default::default()
},
schema: object_schema(vec![
("instruction", "string", true), // 到点要执行的自然语言任务(必填)
("delay_secs", "integer", false), // 相对延时(秒),与 at 至少一个
("at", "string", false), // 绝对时刻 RFC3339;优先于 delay_secs
("title", "string", false), // 卡片标题(缺省取 instruction 前 N 字)
]),
args => {
// 1. 解析 instruction(必填)/delay_secs/at/title → 折算 due_at(epoch ms)
// 2. 发起 conv_id:handler 无 State → 经调用方注入(task-local,对齐 execute_run_workflow_for_tool mod.rs:1367)
// 3. outbox_repo::insert(kind="task", text=instruction, payload_json={instruction}, title, due_at, status=pending)
// 4. 唤醒调度器 notify → emit("ai-outbox-changed") 前端插卡
// 5. 返回 { job_id, due_at }
}
);
- 相对
delay_secs为主(免时区/解析歧义);at为便利补充(LLM 依 system prompt 里的当前时间折算)。 - conv_id:AI 工具 handler 是无
State闭包;发起会话 id 沿用 workflow 工具先例经 task-local 注入(execute_run_workflow_for_tool由ai_approve带conv_id调,mod.rs:1367)。ai_outbox.conversation_id为NOT NULL,而 AI 工具场景必在会话内,故恒可填;极少数拿不到 conv_id 的路径退回「前端/列表入口创建」(935 §3.4 composer 入口)。
3.4 调度器:复用 935 outbox.rs,加 kind='task' 派发分支
935 的调度循环(定时消息…设计 §3.3)按 kind 分派。937 只加一个分支:
// outbox.rs list_due 取项后的派发(schema 由 935 定义,此处补 kind 分支)
match item.kind.as_str() {
"queue" | "scheduled" => { /* 935 既有:spawn_agentic_session(text,...) */ }
"task" => fire_task_job(app, state, &item), // ← 937 新增(§3.5)
other => { warn!(unknown kind); }
}
- CAS/并发/在途/唤醒钩子全部复用 935:同会话忙(
can_accept_request=false)→ 本轮跳过下次再取(不丢);notify_conv_idle完成钩子即时续发;claimCAS 防双取;reset_stale_sending启动复位。 df-outbox-enabled复用:关 = 所有 kind 冻结(937 的 task 也冻结),一致。
3.5 触发执行语义(fire_task_job,937 核心)
- 注入文本:
[定时任务触发] {instruction}(固定前缀族,便于前端识别 + 完成卡归属)。 - 落点选择:
- 发起会话存在且
can_accept_request→ 注入发起会话:走spawn_agentic_session(text=<前缀+instruction>, …, Some(conv), …, pin_active=false)(与 935 派发同源,chat.rs:796)。 - 发起会话正生成 → 轮界排队:
revert_pending(复用 935 的忙回退),下一 tick 重试(不打断流)。 - 发起会话已删/不存在 → 回落独立后台会话:
Some(new_id())+origin="schedule",不静默丢。
- 发起会话存在且
- 落库:
mark_sent(复用 935 语义:spawn返回 Ok 即受理成功)+emit("ai-outbox-sent", {id, conv})。 - 失败:spawn 前置失败(provider 未配/永久 4xx)→
mark_failed(permament(error)复用 935 判据)+ 通知;非永久 →revert_pending下轮重试。LLM 轮次内的失败不回流(与 935 同界定,交既有 loop 自愈)。
3.6 关闭/重启行为(复用 935 追赶策略,937 不另立规则)
- 迁移/恢复:复用 935 的
reset_stale_sending(启动把残留sending→pending);调度器只认due_at <= now,故进程退出期间到期的 task 项重启后立即命中。 - 迟到追赶策略 = 复用 935 拍板点 4(阈值 12h,建议值):迟到 ≤ 阈值 → 补触发;迟到 > 阈值 → 标过期(
status='expired'? 935 用failed/canceled,建议新增expired或用failed+last_error="missed")+ 通知,列表可见可手动重排。937 不引入 24h 另一套阈值,统一走df-outbox-*配置(如需 task 专属阈值,加 KVdf-outbox-task-missed-grace-secs,默认同 12h)。 - 有界性:任何 task 作业按
due_at + 宽限有界,不无限滞留。
3.7 权限与边界(与既有 audit/boundary 链的关系)
- 创建:
schedule_taskMedium → 走既有audit/approval(三档/边界会话按现行规则);创建 ≠ 授权执行。 - 触发执行:走同一 pipeline。
fire_task_job只把一句话送进会话,此后 agentic loop 里每个工具照常过audit(写/High 审批)、path_auth(路径授权)、黑名单拒绝。不新增任何旁路,不预授权(红线)。 - 边界快照
boundary_json(可选):若发起会话已声明TaskBoundary(boundary.rs,risk_ceiling≤Medium,落ai_conversations.boundary_jsonV45),创建时可快照;触发时注入触发会话 → 边界内自动放行、边界外照旧拒绝。未声明 → 不写快照 → 触发走普通审批(首个写操作停靠等人工 + 通知)。 - 黑名单/破坏性命令:永不放行(同 all 档/子代理先例)。
- MCP 面(独立表面,首期不接):
crates/df-mcp/src/tools.rs:101all_tools()是独立硬编码清单(非 AI registry 派生);首期不把schedule_task加入 MCP(定时依赖本机 GUI 进程 + 调度 loop,远程场景语义不闭合),MCP 侧零改动。
3.8 UI 形态(复用 935 抽屉,937 只加卡片)
- 对话内定时任务卡(工具卡变体):
useToolCard.ts:513登记schedule_taskformatter;卡面 = 标题 + 指令摘要 + 「⏰ 触发于 MM-DD HH:mm(还有 X 分钟)」+ 状态徽标(定时中/已触发/已取消/已过期/失败)。状态随ai-outbox-changed/sent/failed事件更新(到点晚于工具返回,不能靠静态 tool_result)。形态照TaskParkedCard.vue(per-conv 卡,行为后摘/更新)。 - 统一「定时列表」抽屉 = 复用 935(
定时消息…设计§3.4):937 的 task 项与 935 的 scheduled/queue 项同列同抽屉,仅多一列「类型=任务/消息」+ task 项显示关联任务(若有)。改期/取消复用 935 的ai_outbox_reschedule/cancelIPC。 - 可选 task 专属入口:ChatInput ⏰ 入口(935 已加,
ChatInput.vue:107)+ 若要在列表里「手动新增定时任务」,复用同一 IPC(ai_outbox_enqueue加kind='task'+payload,或 937 加ai_schedule_task薄封装,见拍板点)。 - 设置页/TopBar 徽标:复用 935 的
df-outbox-*区块与状态查询,不另开。
3.9 与既有链路的关系
- worktree / 评审:触发执行 = 一次普通 agentic run,worktree/review/run_workflow 全照旧;指令若含「推进任务/跑工作流」,由触发后的 loop 调
advance_task/run_workflow(工作流仍走 High 审批)。 - 无人值守引擎:两者独立 loop、独立作业源;挂机在途(
in_flight)与 outbox 派发各管各 conv,不冲突。 - P2 快路径(可选):确定性作业「到点直推任务状态」(
payload_json.task_id+target_status)可不起 LLM,直接advance_task_with_parent(task_advance_node.rs:335)——省 token、免 LLM(状态机推进本身非破坏);须在创建时校验状态机合法性。见拍板点 4。
四、分期与最小可用
| 期 | 范围 | 交付 | 依赖 |
|---|---|---|---|
| P1(最小可用) | 工具面 + task 分支闭环 | V52 增列 + AiOutboxRecord 三字段 + repo + schedule_task 工具 + fire_task_job 注入发起会话 + 启动追赶快照 + 工具卡徽标 |
935 P0 底座(ai_outbox 表 + outbox.rs 调度器 + 列表抽屉) |
| P2(管理/快路径) | 列表类型区分 + 直推 | 列表 task 项类型标 + 关联任务显示;可选确定性直推快路径 + KV 阈值 | P1 稳定 |
| P3 | 边界快照 / 与挂机联动 | boundary_json 快照注入触发执行;挂机自领定时任务(可选) |
P2 + 边界模型落地 |
最小可用定义: P1 完成即达标——「对话里说 1 小时后跑 X → 卡片定时中 → 到点(含重启补触发)在原会话自动执行」。
关键依赖: 937 的 kind='task' 分支不能脱离 935 的 ai_outbox 底座独立交付;两需求应同批或先后紧邻落地,先 935 P0(表+调度器)后接 937 分支。这是本设计对编排的硬约束。
五、影响面(新能力引入评估纪律 · 五维)
| 维度 | 判定 |
|---|---|
| 兼容性 | 复用 ai_outbox(V51)+ 937 加三列(V52,column_exists 幂等,可 DROP 回退);既有工具/任务/工作流零改动。基线测试 test_build_ai_tool_registry_baseline_tool_count 须 +1(schedule_task)。935 的 queue/scheduled 分支不受影响(仅多一个 match 分支)。PASS(带迁移) |
| 破坏性 | 无破坏性数据操作;不改 advance_task/run_workflow 语义;触发=发消息/起会话,可逆(取消/停止)。PASS(低) |
| 安全面 | 新攻击面 = 「未来自动执行 LLM/用户给定指令」。缓解:①创建 Medium 须知情审批 ②触发执行零旁路,写/High/路径/黑名单全走既有闸(G5/G6)③边界快照仅在会话已声明边界时生效(不放大权限)④可随时取消。红线:不得为「定时」开任何 approval/path 旁路。PASS(受控) |
| 资源面 | 复用 935 表与 10s tick loop;937 只多三列 + 一个 match 分支,资源增量≈0。task 项随 outbox 统一设上限(935 已定 sent/canceled 有界策略)。PASS |
| 回退开关 | 复用 df-outbox-enabled(置 false → task 项只入不发,冻结);V52 可 DROP COLUMN 回退。KV 热读免重启。PASS(带开关) |
六、拍板点(需人定,附建议)
- 触发执行落点:注入发起会话(结果可见、上下文连续,贴「对话内创建」语义)【建议默认】 vs 独立后台会话(不打扰但结果另起)。建议前者,发起会话忙则轮界排队、不可用则回落后台会话(§3.5 两全)。
- 与 935 的落地顺序:937 的
kind='task'分支依附 935 的ai_outbox底座——先 935 P0 后接 937【建议】 vs 937 自建一套表/调度器(违反「共用调度器」且制造双调度,否决) vs 两设计合并为一次实施(978/935/937 同批)。建议前者,把「共用底座」写死为编排约束。 - 触发执行授权:默认普通审批模式(未声明边界的发起会话 → 触发后首个写操作停靠等人工并通知)【建议,最安全】 vs 创建即固化「完全信任」(攻击面大) vs 仅当发起会话已声明
TaskBoundary时携带边界快照(边界内免打扰)。建议:默认普通审批 + 「有边界则快照」并存。 - 快路径:起步只做
instruction(通用,触发后 loop 消化一切)【建议】 vs 起步即带task_id+target_status确定性直推(省 LLM/免审批,但限死用途、需额外状态机校验)。建议 instruction 起步,直推作 P2(§3.9)。 - 迟到追赶阈值:复用 935 拍板点 4 的统一阈值(建议 12h)【建议】 vs 为 task 单设更短阈值(定时任务含副作用,可能希望更保守)。建议统一阈值起步,观测后如需再拆 KV。
七、明确不做
- 不做 cron 表达式/周期重复任务(首期只做一次性定时;周期任务=挂机模式职责,另议)。
- 不做跨设备/云端定时(复用 935 边界:关窗托盘化期间生效,进程退出期间不触发,重启补发)。
- 不做定时执行结果的独立推送通道(复用
notify_session_event+ 飞书,与 935 同出口)。 - 不为定时开任何 approval/path 旁路(红线)。
- 不新造调度底座(表/循环/IPC/事件/抽屉全复用 935)。
附:实施落点清单(供实施会话直接取用;底座项见 935 设计,此处只列 937 增量)
| 文件 | 改动 |
|---|---|
crates/df-storage/src/migrations.rs |
增 migrate_v52(3 个 ALTER TABLE ai_outbox ADD COLUMN,幂等);调度数组追加 (52, migrate_v52);补幂等单测。注意:V51 由 935 占,顺序不得换 |
crates/df-storage/src/models.rs |
AiOutboxRecord(935 已加)再补 title/payload_json/boundary_json: Option<String> |
crates/df-storage/src/crud/outbox_repo.rs(935 已建) |
insert/读方法带三新列;list_by_status/list_due 复用 |
src-tauri/src/commands/ai/tools/schedule.rs(新) |
schedule_task 工具(declare_tool!,Medium);tool_registry.rs:737 旁接线 + 基线测试 +1 |
src-tauri/src/commands/ai/outbox.rs(935 已建) |
调度派发 match kind 加 "task" => fire_task_job(...);fire_task_job(§3.5)+ 追赶快照 |
src-tauri/src/commands/ai/mod.rs |
事件复用 ai-outbox-changed/sent/failed(935 已定);如卡片需状态细分可加可选字段,不新事件名 |
src-tauri/src/lib.rs |
outbox::start 由 935 挂载;937 无需另挂 |
src/composables/ai/useToolCard.ts |
:513 映射增 schedule_task formatter(定时任务卡) |
src/components/ai/ |
定时任务卡(仿 TaskParkedCard.vue);列表抽屉 task 项类型标(复用 935 抽屉) |
src/api/ai.ts |
复用 935 ai_outbox_* 封装;若新增「手动建定时任务」入口再加薄封装 |
src/i18n/zh-CN/* + en/* |
卡片状态词(定时中/已触发/已过期…)/类型「任务」 |
参照档:
定时消息与待发箱持久化-设计-2026-10-10.md(935/931,共用底座,必读)·无人值守长任务-设计-2026-10-04.md(结构/详略)·并行化与异步唤醒-设计-2026-10-04.md(§二 wake delay 型/§6.3 挂机)·输入框列表预览与自动编号-设计-2026-10-10.md(同目录同日写法/五维自评)。