新增: 审批超时后端兜底,覆盖重启恢复场景
前端已有审批超时定时器(设置页可选 0/5/15/30/60 分钟),负责会话 内运行的审批超时检测。但应用重启后前端定时器丢失,从数据库恢复 的待审批无人计时,会永久卡死会话。 本次补充后端兜底机制: - 待审批记录创建时刻,用于超时判定 - 在审批恢复入口检测超时,超时自动取消并写入审计 - 应用启动时从设置恢复超时配置(默认 15 分钟,0 为禁用) - 新增读写超时配置的接口,设置页可改 - 与前端共用同一个配置项,保证单一真相源 同时更新待办文档,把已实现项标记为完成。
This commit is contained in:
@@ -245,6 +245,9 @@ pub const CIRCUIT_BREAKER_HELP_EVENT: bool = true;
|
||||
mod guard;
|
||||
use guard::GeneratingGuard;
|
||||
|
||||
/// 审批超时取消(由 try_continue_agent_loop 入口调用)
|
||||
mod approval_timeout;
|
||||
|
||||
// ============================================================
|
||||
// L2 统一状态机(ConvState enum + 转换守卫,单一真相源)。
|
||||
// 设计:generating状态机加固-2026-06-15.md §3 + aichat体验与agent能力系统化重构-2026-06-21.md §3。
|
||||
@@ -830,7 +833,7 @@ pub(crate) async fn run_agentic_loop(
|
||||
// 输出平台一致性。detect() 是 OnceLock 全局缓存(启动时探一次,后续零开销),与 G1 一样
|
||||
// 是 loop 不变量(整个会话不重探),与目标钉扎拼接次序无强约束(放其后,语义自然)。
|
||||
let env_prompt = df_execute::EnvSnapshot::detect().await.to_prompt();
|
||||
let behavior_prompt = "\n## 行为准则\n- 使用工具指令(create_project/write_file/grep/read_file/run_command 等)直接完成任务,不要让用户去终端执行命令\n- 优先使用开发工具 IPC,非必要不写独立脚本(write_file + run_command = 两次审批,拖慢工作流)\n- 已有 40+ 工具覆盖绝大多数场景,先查工具列表再决定";
|
||||
let behavior_prompt = "\n## AI 定位\n你是 DevFlow 的 AI 助手,拥有完整的工具链。用户只负责提需求和审批,所有执行由你完成——读写文件、运行命令、创建项目、搜索代码等都是你直接调用工具完成的。**绝不输出“请在终端执行以下命令”这类指令——你自己用 run_command 工具执行即可。**\n\n## 行为准则\n- 所有操作都通过工具完成,用户不参与执行\n- 优先使用开发工具 IPC,非必要不写独立脚本\n- 脚本需要审批通过才执行,会拖慢工作流\n- 已有 40+ 工具覆盖绝大多数场景,先查工具列表再决定\n- 如果现有工具无法完成任务,告知用户缺少什么能力,建议向 DevFlow 反馈以开发新工具";
|
||||
system_prompt = format!("{}\n\n{}\n\n{}", system_prompt, env_prompt, behavior_prompt);
|
||||
|
||||
// 对话透明化 L1:拍快照供 AiCompleted 事件携带,前端直接读取 pinned_goals 无需等 loadConversations
|
||||
@@ -1929,6 +1932,12 @@ pub(crate) async fn try_continue_agent_loop(
|
||||
conv_id: &str,
|
||||
start_iteration: usize,
|
||||
) {
|
||||
// 审批超时检测:超时取消在本函数入口进行(本函数是所有审批恢复路径的入口——
|
||||
// ai_approve / ai_authorize_dir / ai_continue_loop / ai_chat_stop 都调它)。
|
||||
// 这里检测后把超时审批转为拒绝状态,避免用户离开后 pending 永久挂起死锁会话。
|
||||
// 0 表示禁用超时(不推荐,但保留用户选择权)。检测失败(如锁中毒)不阻断续跑。
|
||||
approval_timeout::cleanup_expired_approvals(app, state, conv_id).await;
|
||||
|
||||
// BUG-260617-05: 原 5 次独立 lock().await 造成 TOCTOU 竞态——should_continue=true 判出后、
|
||||
// spawn 前用户点 stop(ai_chat_stop 复位 generating=false),续跑仍按过时快照继续 spawn。
|
||||
// 修复:单次 lock 取结构化快照(所有续跑判定所需字段),无锁态判定;spawn 前单次 lock 原子
|
||||
|
||||
Reference in New Issue
Block a user