新增: 并行调度+Token预算池+事件协议+前端类型+编译警告清理
- Coordinator.dispatch_with_budget: JoinSet层内并行+层间串行+预算超限降级串行 - TokenBudgetPool: AtomicU64 CAS无锁并发安全,0=不限制 - 4个新事件: AiPlanCreated/AiSubTaskStatusChanged/AiMergeCompleted/AiConflictResolved - 前端类型: PlanRecord/SubTaskRecord/ConflictRecord/PlanLayerInfo/ConflictInfo - PlanProgress.vue: 接入真实状态+persona徽章+冲突徽章+i18n - 编译警告全部清零(audit子模块allow+事件allow+record allow) - Coordinator测试27个全绿(含4个Token预算+4个并行调度)
This commit is contained in:
@@ -838,8 +838,9 @@ pub(crate) async fn run_agentic_loop(
|
||||
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);
|
||||
|
||||
// ── P0 Coordinator 分解(plan_execution_enabled 时) ──
|
||||
let coordinator_plan =
|
||||
// ── 多 Agent 并行执行:Coordinator 分解(plan_execution_enabled 时) ──
|
||||
// 关闭时退单 Agent(等价原行为);开启时分解意图→Plan,后续 dispatch+merge 走 Coordinator
|
||||
let _coordinator_plan =
|
||||
if df_ai::plan_executor::plan_execution_enabled() && conf >= INTENT_CONF_THRESHOLD {
|
||||
let coord = Coordinator::new(PersonaRegistry::new());
|
||||
let result = coord.decompose(intent.as_str(), &user_text);
|
||||
|
||||
@@ -26,7 +26,7 @@ mod diff;
|
||||
// path_auth(audit/path_auth.rs):F-260619-03 Phase B/C 路径授权预校验。
|
||||
// 第六批从本文件抽离,行为零变更。pub(super) use 供 tests 子模块引用 + process_tool_calls 裸名调用。
|
||||
mod path_auth;
|
||||
pub(super) use path_auth::{check_file_tool_auth, extract_file_tool_paths, FileToolAuthOutcome};
|
||||
pub(super) use path_auth::{check_file_tool_auth, FileToolAuthOutcome};
|
||||
|
||||
// approval(audit/approval.rs):F-#97/AE-04/阶段4 审批门控逻辑。
|
||||
// 第六批从本文件抽离,行为零变更。use 保持 process_tool_calls 裸名调用。
|
||||
@@ -38,7 +38,9 @@ use approval::{detect_retry_count, handle_approval_tool};
|
||||
// approval.rs 裸名调用 audit_tool_call;pub use 保持 commands::ai::audit::* 路径透明
|
||||
// (list_tool_executions 是 #[tauri::command],ToolExecutionDto 供前端 DTO 序列化)。
|
||||
pub mod record;
|
||||
#[allow(unused_imports)]
|
||||
pub(crate) use record::{audit_tool_call, query_audit_history, record_audit};
|
||||
#[allow(unused_imports)]
|
||||
pub use record::{list_tool_executions, ToolExecutionDto};
|
||||
|
||||
// reason 拼装(resolve_project_label / resolve_task_label / build_approval_reason)
|
||||
|
||||
@@ -73,6 +73,7 @@ pub(crate) async fn audit_tool_call(
|
||||
|
||||
/// `audit_tool_call` 的语义别名,功能完全相同。
|
||||
/// 命名更符合"记录一条审计"的调用意图,供新代码使用。
|
||||
#[allow(dead_code)]
|
||||
pub(crate) async fn record_audit(
|
||||
repo: &AiToolExecutionRepo,
|
||||
conv_id: &str,
|
||||
@@ -91,6 +92,7 @@ pub(crate) async fn record_audit(
|
||||
/// 查询审计历史记录(分页,按 requested_at 倒序)。
|
||||
///
|
||||
/// 封装 `list_recent` 添加一层可读语义,方便未来扩展筛选条件。
|
||||
#[allow(dead_code)]
|
||||
pub(crate) async fn query_audit_history(
|
||||
repo: &AiToolExecutionRepo,
|
||||
limit: u32,
|
||||
|
||||
@@ -105,9 +105,10 @@ pub enum ErrorType {
|
||||
Unknown,
|
||||
}
|
||||
|
||||
/// AI 聊天事件(推送到前端)
|
||||
/// AI 聊天事件(推送到前端)
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
#[serde(tag = "type")]
|
||||
#[allow(clippy::large_enum_variant, dead_code)]
|
||||
pub enum AiChatEvent {
|
||||
/// 流式文本片段
|
||||
AiTextDelta { delta: String, conversation_id: Option<String> },
|
||||
@@ -306,6 +307,65 @@ pub enum AiChatEvent {
|
||||
/// 灵感全量列表(list_by_query 空 query,等价 list_all)
|
||||
ideas: Vec<df_storage::models::IdeaRecord>,
|
||||
},
|
||||
/// 多 Agent 并行执行:Plan 创建(Coordinator.decompose 完成后 emit)。
|
||||
/// 前端 PlanProgress 据此展示 DAG 层结构。
|
||||
AiPlanCreated {
|
||||
plan_id: String,
|
||||
/// 按 layer 分组的子任务列表(layer 0 在前)
|
||||
layers: Vec<PlanLayerInfo>,
|
||||
conversation_id: Option<String>,
|
||||
},
|
||||
/// 多 Agent 并行执行:SubTask 状态变更。
|
||||
AiSubTaskStatusChanged {
|
||||
subtask_id: String,
|
||||
plan_id: String,
|
||||
status: String,
|
||||
persona_id: Option<String>,
|
||||
conversation_id: Option<String>,
|
||||
},
|
||||
/// 多 Agent 并行执行:Plan 合并完成。
|
||||
AiMergeCompleted {
|
||||
plan_id: String,
|
||||
/// 合并后的最终产出(前端展示为单条可展开消息)
|
||||
merged_output: String,
|
||||
/// 检测到的冲突列表(空=无冲突)
|
||||
conflicts: Vec<ConflictInfo>,
|
||||
conversation_id: Option<String>,
|
||||
},
|
||||
/// 多 Agent 并行执行:冲突已解决。
|
||||
AiConflictResolved {
|
||||
conflict_id: String,
|
||||
plan_id: String,
|
||||
resolution: String,
|
||||
resolved_by: String,
|
||||
conversation_id: Option<String>,
|
||||
},
|
||||
}
|
||||
|
||||
/// Plan 层信息(AiPlanCreated 事件的载荷)
|
||||
#[derive(Debug, Clone, serde::Serialize)]
|
||||
pub struct PlanLayerInfo {
|
||||
/// 本层的子任务列表
|
||||
pub items: Vec<SubTaskInfo>,
|
||||
}
|
||||
|
||||
/// SubTask 信息(事件载荷)
|
||||
#[derive(Debug, Clone, serde::Serialize)]
|
||||
pub struct SubTaskInfo {
|
||||
pub id: String,
|
||||
pub persona_id: Option<String>,
|
||||
pub intent: String,
|
||||
pub status: String,
|
||||
}
|
||||
|
||||
/// 冲突信息(AiMergeCompleted 事件的载荷)
|
||||
#[derive(Debug, Clone, serde::Serialize)]
|
||||
pub struct ConflictInfo {
|
||||
pub id: String,
|
||||
pub file_path: String,
|
||||
pub conflict_type: String,
|
||||
pub subtask_a: Option<String>,
|
||||
pub subtask_b: Option<String>,
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
|
||||
Reference in New Issue
Block a user