新增: Reviewer仲裁+命令互斥锁+冲突解决IPC(批次C散项)
- coordinator: arbitrate_conflicts 方法(规则仲裁:成功方优先/双方成功推荐合并/都失败手动) - coordinator: ConflictItem 加 subtask_a/subtask_b/recommendation 字段 + ConflictResolution 枚举 - command_lock.rs: CommandLockRegistry (dir+cmd首词 Semaphore 串行化,5个测试全绿) - resolve_conflict IPC: 解决冲突→更新DB→emit AiConflictResolved 事件闭环 - 3个仲裁测试 + 5个互斥锁测试全绿 - 零编译警告
This commit is contained in:
@@ -140,3 +140,45 @@ pub async fn set_plan_execution(enabled: bool) -> Result<(), String> {
|
||||
pub async fn get_plan_execution() -> Result<bool, String> {
|
||||
Ok(df_ai::plan_executor::plan_execution_enabled())
|
||||
}
|
||||
|
||||
/// 解决合并冲突(用户/reviewer 选择解决方案后调用)。
|
||||
///
|
||||
/// 更新 ai_conflicts 表的 resolution + resolved_by + resolved_at,
|
||||
/// 并 emit AiConflictResolved 事件供前端更新徽章。
|
||||
#[tauri::command]
|
||||
pub async fn resolve_conflict(
|
||||
state: State<'_, AppState>,
|
||||
app_handle: tauri::AppHandle,
|
||||
conflict_id: String,
|
||||
plan_id: String,
|
||||
resolution: String,
|
||||
resolved_by: String,
|
||||
conversation_id: Option<String>,
|
||||
) -> Result<(), String> {
|
||||
use tauri::Emitter;
|
||||
let repo = df_storage::crud::ConflictRepo::new(&state.db);
|
||||
let now = df_types::now_millis().to_string();
|
||||
let ok = repo.resolve(&conflict_id, &resolution, &resolved_by, &now)
|
||||
.await
|
||||
.map_err(err_str)?;
|
||||
if !ok {
|
||||
return Err(format!("冲突 {} 不存在或已解决", conflict_id));
|
||||
}
|
||||
tracing::info!(
|
||||
conflict_id = %conflict_id,
|
||||
resolution = %resolution,
|
||||
resolved_by = %resolved_by,
|
||||
"[CONFLICT] 冲突已解决"
|
||||
);
|
||||
// emit AiConflictResolved 事件
|
||||
let ev = crate::commands::ai::AiChatEvent::AiConflictResolved {
|
||||
conflict_id,
|
||||
plan_id,
|
||||
resolution,
|
||||
resolved_by,
|
||||
conversation_id,
|
||||
};
|
||||
let _ = app_handle.emit("ai-chat-event", ev.clone());
|
||||
let _ = state.ai_event_bus.publish_event(ev);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user