修复: 代码审查发现的安全与兼容性问题
- git_worktree: commit config 改用 --local 避免污染全局 git config - git_worktree: merge-tree 改用旧版兼容语法(三参数替代 --write-tree) - coordinator: executor 'static 约束加注释说明(JoinSet spawn 要求) - coordinator: Token reserve 按层 SubTask 数累加(原固定 10k 不准确) - coordinator: 更新结构体注释(反映当前并行实现而非 Phase 1 串行) - 39 个测试全绿,行为零回归
This commit is contained in:
@@ -129,16 +129,15 @@ pub struct ConflictItem {
|
|||||||
|
|
||||||
/// 多 Agent 协作调度器
|
/// 多 Agent 协作调度器
|
||||||
///
|
///
|
||||||
/// # Phase 1(当前)
|
/// 当前实现:
|
||||||
|
/// - 规则驱动 decompose(关键词匹配)
|
||||||
|
/// - dispatch_with_budget: JoinSet 层内并行 + token 预算管控
|
||||||
|
/// - dispatch_serial: 串行降级路径(无 'static 约束)
|
||||||
|
/// - merge: 拼接产出 + 同文件冲突检测
|
||||||
///
|
///
|
||||||
/// 规则驱动 decompose + 串行 dispatch + 简单拼接 merge。
|
/// Phase 2 预留:
|
||||||
/// 适用于「读后写」「搜索后分析」等可预测的意图组合。
|
/// - LLM 驱动 decompose
|
||||||
///
|
/// - Reviewer Agent 仲裁
|
||||||
/// # Phase 2(预留)
|
|
||||||
///
|
|
||||||
/// - LLM 驱动 decompose(LLM 生成 Plan 结构)
|
|
||||||
/// - JoinSet 并行 dispatch(层内并行)
|
|
||||||
/// - Reviewer Agent 仲裁 merge(冲突检测 + 自动解决)
|
|
||||||
pub struct Coordinator {
|
pub struct Coordinator {
|
||||||
/// 人设注册表(内置 5 人设 + 自定义)
|
/// 人设注册表(内置 5 人设 + 自定义)
|
||||||
registry: PersonaRegistry,
|
registry: PersonaRegistry,
|
||||||
@@ -268,6 +267,9 @@ impl Coordinator {
|
|||||||
budget: Option<&Arc<TokenBudgetPool>>,
|
budget: Option<&Arc<TokenBudgetPool>>,
|
||||||
) -> Vec<ExecutionResult>
|
) -> Vec<ExecutionResult>
|
||||||
where
|
where
|
||||||
|
// 'static + Clone 要求:JoinSet::spawn 需要 owned 闭包(不能借用 self/db)。
|
||||||
|
// 调用方需用 Arc 包裹共享状态(db/session)传入闭包。
|
||||||
|
// 不需要并行时用 dispatch_serial(无 'static 约束)。
|
||||||
F: Fn(SubTask, String) -> Fut + Clone + Send + Sync + 'static,
|
F: Fn(SubTask, String) -> Fut + Clone + Send + Sync + 'static,
|
||||||
Fut: std::future::Future<Output = ExecutionResult> + Send,
|
Fut: std::future::Future<Output = ExecutionResult> + Send,
|
||||||
{
|
{
|
||||||
@@ -308,7 +310,7 @@ impl Coordinator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let can_parallel = budget
|
let can_parallel = budget
|
||||||
.map(|b| b.try_reserve(10_000))
|
.map(|b| b.try_reserve(layer.len() as u64 * 10_000)) // 每层按 SubTask 数累加
|
||||||
.unwrap_or(true);
|
.unwrap_or(true);
|
||||||
|
|
||||||
if can_parallel {
|
if can_parallel {
|
||||||
|
|||||||
@@ -129,14 +129,14 @@ pub fn commit_worktree(wt_path: &Path, message: &str) -> Result<(), WorktreeErro
|
|||||||
// commit 失败可能因无 user.email 配置(测试环境),尝试自动配
|
// commit 失败可能因无 user.email 配置(测试环境),尝试自动配
|
||||||
let stderr = String::from_utf8_lossy(&commit.stderr);
|
let stderr = String::from_utf8_lossy(&commit.stderr);
|
||||||
if stderr.contains("user.email") || stderr.contains("user.name") {
|
if stderr.contains("user.email") || stderr.contains("user.name") {
|
||||||
// 降级:设置临时配置后重试
|
// 降级:设置 worktree 局部配置(--local 不污染全局 git config)后重试
|
||||||
Command::new("git")
|
Command::new("git")
|
||||||
.args(["config", "user.email", "devflow@ai.local"])
|
.args(["config", "--local", "user.email", "devflow@ai.local"])
|
||||||
.current_dir(wt_path)
|
.current_dir(wt_path)
|
||||||
.output()
|
.output()
|
||||||
.ok();
|
.ok();
|
||||||
Command::new("git")
|
Command::new("git")
|
||||||
.args(["config", "user.name", "DevFlow Agent"])
|
.args(["config", "--local", "user.name", "DevFlow Agent"])
|
||||||
.current_dir(wt_path)
|
.current_dir(wt_path)
|
||||||
.output()
|
.output()
|
||||||
.ok();
|
.ok();
|
||||||
@@ -167,23 +167,23 @@ pub fn merge_branch(
|
|||||||
plan_wt_path: &Path,
|
plan_wt_path: &Path,
|
||||||
subtask_branch: &str,
|
subtask_branch: &str,
|
||||||
) -> Result<MergeResult, WorktreeError> {
|
) -> Result<MergeResult, WorktreeError> {
|
||||||
// 先用 merge-tree 预检
|
// 用旧版兼容的 merge-tree(base branch → 输出冲突树)
|
||||||
|
// --write-tree 需 Git 2.38+,改用三参数 merge-tree <base> <branch1> <branch2>
|
||||||
|
// 成功(exit 0)= 无冲突可自动合并;非0且有输出 = 冲突
|
||||||
|
let base = "HEAD";
|
||||||
let precheck = Command::new("git")
|
let precheck = Command::new("git")
|
||||||
.args(["merge-tree", "--write-tree", "--messages", "HEAD", subtask_branch])
|
.args(["merge-tree", base, subtask_branch, base])
|
||||||
.current_dir(plan_wt_path)
|
.current_dir(plan_wt_path)
|
||||||
.output()
|
.output()
|
||||||
.map_err(|e| WorktreeError::GitFailed(format!("git merge-tree 失败: {}", e)))?;
|
.map_err(|e| WorktreeError::GitFailed(format!("git merge-tree 失败: {}", e)))?;
|
||||||
|
|
||||||
// merge-tree --write-tree 成功(exit 0)= 无冲突可自动合并;
|
// merge-tree 输出含 conflict marker(<<<<<<<)时表示有冲突
|
||||||
// 非0(冲突)且 stdout 非空 = 有冲突
|
let precheck_stdout = String::from_utf8_lossy(&precheck.stdout);
|
||||||
if !precheck.status.success() {
|
if precheck_stdout.contains("<<<<<<<") || precheck_stdout.contains("=======") {
|
||||||
let stdout = String::from_utf8_lossy(&precheck.stdout);
|
return Ok(MergeResult::Conflict {
|
||||||
if !stdout.is_empty() {
|
branch: subtask_branch.to_string(),
|
||||||
return Ok(MergeResult::Conflict {
|
details: precheck_stdout.to_string(),
|
||||||
branch: subtask_branch.to_string(),
|
});
|
||||||
details: stdout.to_string(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 无冲突,执行实际 merge
|
// 无冲突,执行实际 merge
|
||||||
|
|||||||
Reference in New Issue
Block a user