新增: 初始化 DevFlow 项目仓库

Tauri 2 + Vue 3 + Vite 6 桌面应用,Rust workspace 含 13 个 crate
(df-ai / df-storage / df-workflow / df-core / df-execute 等)。
核心能力:AI 聊天 agentic 循环(工具调用+人工审批)、工作流引擎、
任务/想法/项目/阶段管理、可追溯性,及配套前端组件。
This commit is contained in:
2026-06-12 01:31:05 +08:00
commit 98393b4908
178 changed files with 27859 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
[package]
name = "df-ideas"
version = "0.1.0"
edition = "2021"
[dependencies]
df-core = { path = "../df-core" }
serde = { workspace = true }
serde_json = { workspace = true }
tokio = { workspace = true }
anyhow = { workspace = true }
chrono = { workspace = true }
tracing = { workspace = true }

View File

@@ -0,0 +1,308 @@
//! 对抗式评估系统 — 正反方辩论 + AI 分析师
use anyhow::Result;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use df_core::types::IdeaId;
use crate::capture::Idea;
/// 对抗评估结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AdversarialEval {
pub idea_id: IdeaId,
pub positive: Argument,
pub negative: Argument,
pub analyst: AnalystAnalysis,
pub final_score: f64,
pub recommendation: Recommendation,
}
/// 正方论点
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Argument {
pub thesis: String, // 核心观点
pub evidence: Vec<String>, // 证据支持
pub reasoning: Vec<String>, // 推理过程
pub confidence: f64, // 置信度 0-1
}
/// 反方论点
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CounterArgument {
pub thesis: String, // 反对观点
pub evidence: Vec<String>, // 反对证据
pub reasoning: Vec<String>, // 反驳推理
pub confidence: f64, // 置信度 0-1
}
/// AI 分析师综合分析
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AnalystAnalysis {
pub summary: String, // 综合总结
pub strengths: Vec<String>, // 主要优势
pub weaknesses: Vec<String>, // 主要劣势
pub risks: Vec<String>, // 潜在风险
pub opportunities: Vec<String>, // 机会点
pub final_assessment: AssessmentLevel, // 最终评估
}
/// 评估等级
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum AssessmentLevel {
StrongGo, // 强烈推荐执行
Recommended, // 推荐执行
Conditional, // 有条件执行
Revised, // 需要修改后执行
Defer, // 推迟执行
Reject, // 不推荐执行
}
/// 最终建议
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum Recommendation {
ImmediateAction, // 立即行动
Soon, // 尽快行动
WithResources, // 配置资源后行动
ResearchMore, // 需要更多研究
Monitor, // 持续监控
Cancel, // 取消想法
}
/// 对抗评估引擎
pub struct AdversarialEngine;
impl AdversarialEngine {
/// 执行完整的对抗评估
pub async fn evaluate(idea: &Idea) -> Result<AdversarialEval> {
// 1. 生成正方观点
let positive = Self::generate_positive_argument(idea).await?;
// 2. 生成反方观点
let negative = Self::generate_negative_argument(idea, &positive).await?;
// 3. AI 分析师综合分析
let analyst = Self::analyst_analysis(idea, &positive, &negative).await?;
// 4. 计算最终分数和建议
let (final_score, recommendation) = Self::compute_final_assessment(&analyst);
Ok(AdversarialEval {
idea_id: idea.id.clone(),
positive,
negative,
analyst,
final_score,
recommendation,
})
}
/// 生成正方观点(支持执行)
async fn generate_positive_argument(idea: &Idea) -> Result<Argument> {
// TODO: 接入 AI 生成正方观点
// 当前使用启发式模板
let title = &idea.title;
let desc = &idea.description;
Ok(Argument {
thesis: format!("{} 具有很高的价值和可行性,应该优先执行", title),
evidence: vec![
format!("满足业务需求:{}", desc),
"投入产出比高".to_string(),
"技术实现可行".to_string(),
"时间窗口合适".to_string(),
],
reasoning: vec![
"能够解决现有痛点".to_string(),
"竞争优势明显".to_string(),
"风险可控".to_string(),
],
confidence: 0.75,
})
}
/// 生成反方观点(反对或谨慎)
async fn generate_negative_argument(idea: &Idea, positive: &Argument) -> Result<CounterArgument> {
// TODO: 接入 AI 生成反方观点,考虑正方观点
let title = &idea.title;
Ok(CounterArgument {
thesis: format!("{} 需要谨慎评估,存在一定风险", title),
evidence: vec![
"资源投入较大".to_string(),
"市场不确定性高".to_string(),
"技术挑战存在".to_string(),
"机会成本高".to_string(),
],
reasoning: vec![
"ROI 需要进一步验证".to_string(),
"优先级可能过高".to_string(),
"存在更优替代方案".to_string(),
],
confidence: 0.65,
})
}
/// AI 分析师综合分析
async fn analyst_analysis(
idea: &Idea,
positive: &Argument,
negative: &CounterArgument,
) -> Result<AnalystAnalysis> {
// TODO: 接入 AI 进行深度分析
let positive_strengths = vec![
"方向正确,符合业务战略".to_string(),
"技术创新性较强".to_string(),
"用户价值明确".to_string(),
];
let weaknesses = vec![
"资源需求评估不足".to_string(),
"风险控制需要加强".to_string(),
"时间规划可能过于乐观".to_string(),
];
let risks = vec![
"技术实现难度超出预期".to_string(),
"市场竞争加剧".to_string(),
"用户接受度不确定".to_string(),
];
let opportunities = vec![
"可能形成新的竞争优势".to_string(),
"技术积累价值显著".to_string(),
"市场机会窗口良好".to_string(),
];
// 基于正反方观点的强度计算
let positive_strength = positive.confidence;
let negative_strength = negative.confidence;
let net_positive = (positive_strength - negative_strength + 1.0) / 2.0;
let final_assessment = if net_positive > 0.7 {
AssessmentLevel::StrongGo
} else if net_positive > 0.5 {
AssessmentLevel::Recommended
} else if net_positive > 0.3 {
AssessmentLevel::Conditional
} else if net_positive > 0.1 {
AssessmentLevel::Revised
} else {
AssessmentLevel::Defer
};
Ok(AnalystAnalysis {
summary: format!(
"该想法整体价值评估中等偏上,建议在有条件的情况下执行。主要价值在于{},需要关注{}。",
idea.title,
if net_positive > 0.5 { "风险控制" } else { "价值验证" }
),
strengths: positive_strengths,
weaknesses,
risks,
opportunities,
final_assessment,
})
}
/// 计算最终评估分数和建议
fn compute_final_assessment(analyst: &AnalystAnalysis) -> (f64, Recommendation) {
// 基于评估等级映射分数
let base_score = match analyst.final_assessment {
AssessmentLevel::StrongGo => 8.5,
AssessmentLevel::Recommended => 7.0,
AssessmentLevel::Conditional => 5.5,
AssessmentLevel::Revised => 4.0,
AssessmentLevel::Defer => 2.5,
AssessmentLevel::Reject => 1.0,
};
// 根据优劣势微调分数
let strength_count = analyst.strengths.len() as f64;
let weakness_count = analyst.weaknesses.len() as f64;
let score_adjustment = (strength_count - weakness_count) * 0.3;
let final_score = (base_score + score_adjustment).clamp(0.0, 10.0);
let recommendation = match analyst.final_assessment {
AssessmentLevel::StrongGo => Recommendation::ImmediateAction,
AssessmentLevel::Recommended => Recommendation::Soon,
AssessmentLevel::Conditional => Recommendation::WithResources,
AssessmentLevel::Revised => Recommendation::ResearchMore,
AssessmentLevel::Defer => Recommendation::Monitor,
AssessmentLevel::Reject => Recommendation::Cancel,
};
(final_score, recommendation)
}
}
/// 评估结果展示格式
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EvalDisplay {
pub idea_title: String,
pub positive_strength: f64,
pub negative_strength: f64,
pub net_sentiment: f64, // -1 到 1正为正面
pub assessment_level: String,
pub key_takeaways: Vec<String>,
pub action_items: Vec<String>,
}
impl From<AdversarialEval> for EvalDisplay {
fn from(eval: AdversarialEval) -> Self {
let net_sentiment = (eval.positive.confidence - eval.negative.confidence) as f64;
let key_takeaways = vec![
format!("优势:{}", eval.analyst.strengths.join("")),
format!("风险:{}", eval.analyst.risks.join("")),
format!("建议:{:?}", eval.recommendation),
];
let action_items = match eval.recommendation {
Recommendation::ImmediateAction => vec![
"立即组建项目团队".to_string(),
"制定详细执行计划".to_string(),
"分配必要资源".to_string(),
],
Recommendation::Soon => vec![
"下周启动项目".to_string(),
"准备资源需求".to_string(),
"制定时间表".to_string(),
],
Recommendation::WithResources => vec![
"确认资源预算".to_string(),
"评估ROI".to_string(),
"制定风险预案".to_string(),
],
Recommendation::ResearchMore => vec![
"进行市场调研".to_string(),
"收集用户反馈".to_string(),
"验证技术可行性".to_string(),
],
Recommendation::Monitor => vec![
"持续跟踪相关指标".to_string(),
"定期评估进展".to_string(),
"等待更好的时机".to_string(),
],
Recommendation::Cancel => vec![
"记录归档原因".to_string(),
"释放相关资源".to_string(),
"提取经验教训".to_string(),
],
};
EvalDisplay {
idea_title: eval.positive.thesis.split(' ').take(3).collect::<Vec<_>>().join(" "),
positive_strength: eval.positive.confidence,
negative_strength: eval.negative.confidence,
net_sentiment,
assessment_level: format!("{:?}", eval.analyst.final_assessment),
key_takeaways,
action_items,
}
}
}

View File

@@ -0,0 +1,98 @@
//! 想法捕获 — 快速记录与管理
use serde::{Deserialize, Serialize};
use df_core::types::{IdeaId, Priority};
/// 捕获一个新想法的输入
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CaptureInput {
/// 标题
pub title: String,
/// 详细描述
pub description: String,
/// 优先级
#[serde(default)]
pub priority: Priority,
/// 标签
#[serde(default)]
pub tags: Vec<String>,
/// 来源(如 "用户输入"、"AI 生成"、"会议记录"
pub source: Option<String>,
}
/// 想法实体
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Idea {
/// 唯一 ID
pub id: IdeaId,
/// 标题
pub title: String,
/// 详细描述
pub description: String,
/// 当前状态
pub status: df_core::types::IdeaStatus,
/// 优先级
pub priority: Priority,
/// 评分
pub scores: Option<IdeaScores>,
/// 标签
pub tags: Vec<String>,
/// 来源
pub source: Option<String>,
/// 关联的想法 ID
pub related_ids: Vec<IdeaId>,
/// 创建时间
pub created_at: chrono::DateTime<chrono::Utc>,
/// 更新时间
pub updated_at: chrono::DateTime<chrono::Utc>,
}
/// 想法评分详情
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IdeaScores {
/// 可行性评分 (0-10)
pub feasibility: f64,
/// 影响力评分 (0-10)
pub impact: f64,
/// 紧急度评分 (0-10)
pub urgency: f64,
/// 综合评分 (加权平均)
pub overall: f64,
}
/// 想法捕获器
pub struct IdeaCapture;
impl IdeaCapture {
/// 捕获一个新想法
///
/// TODO: 接入存储层持久化
pub fn capture(input: CaptureInput) -> Idea {
let now = chrono::Utc::now();
Idea {
id: df_core::types::new_id(),
title: input.title,
description: input.description,
status: df_core::types::IdeaStatus::Draft,
priority: input.priority,
scores: None,
tags: input.tags,
source: input.source,
related_ids: Vec::new(),
created_at: now,
updated_at: now,
}
}
/// 快速捕获(仅标题)
pub fn quick_capture(title: String) -> Idea {
Self::capture(CaptureInput {
title,
description: String::new(),
priority: Priority::default(),
tags: Vec::new(),
source: None,
})
}
}

View File

@@ -0,0 +1,79 @@
//! 想法评估器 — 对想法进行多维度评估
use anyhow::Result;
use df_core::types::IdeaId;
use crate::adversarial::{AdversarialEngine, AdversarialEval};
use crate::capture::Idea;
use crate::scoring::IdeaScores;
/// 评估维度
#[derive(Debug, Clone, Copy)]
pub enum EvalDimension {
/// 可行性
Feasibility,
/// 影响力
Impact,
/// 紧急度
Urgency,
}
/// 评估结果
#[derive(Debug, Clone)]
pub struct EvalResult {
pub idea_id: IdeaId,
pub scores: IdeaScores,
pub recommendation: Recommendation,
pub comments: Vec<String>,
}
/// 评估建议
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Recommendation {
/// 强烈推荐立即执行
StrongApprove,
/// 推荐执行
Approve,
/// 需要更多信息
NeedsInfo,
/// 建议推迟
Defer,
/// 不推荐
Reject,
}
/// 想法评估器
pub struct IdeaEvaluator;
impl IdeaEvaluator {
/// 评估一个想法 - 使用对抗式评估
pub async fn evaluate_adversarial(idea: &Idea) -> Result<AdversarialEval> {
AdversarialEngine::evaluate(idea).await
}
/// 评估一个想法 - 保持向后兼容
pub fn evaluate(idea: &Idea) -> Result<EvalResult> {
// 使用简单评分作为后备
let scores = crate::scoring::ScoringEngine::compute_default(idea);
let recommendation = if scores.overall >= 8.0 {
Recommendation::StrongApprove
} else if scores.overall >= 6.0 {
Recommendation::Approve
} else if scores.overall >= 4.0 {
Recommendation::NeedsInfo
} else if scores.overall >= 2.0 {
Recommendation::Defer
} else {
Recommendation::Reject
};
Ok(EvalResult {
idea_id: idea.id.clone(),
scores,
recommendation,
comments: Vec::new(),
})
}
}

View File

@@ -0,0 +1,76 @@
//! 想法关联图 — 管理想法之间的关系
use std::collections::HashMap;
use df_core::types::IdeaId;
/// 想法之间的关系类型
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RelationKind {
/// 相似(语义相近)
Similar,
/// 依赖A 依赖 B
DependsOn,
/// 衍生A 衍生自 B
DerivedFrom,
/// 互补A 和 B 可以互补)
Complementary,
}
/// 想法关系边
#[derive(Debug, Clone)]
pub struct Relation {
pub source_id: IdeaId,
pub target_id: IdeaId,
pub kind: RelationKind,
pub strength: f64, // 0.0 ~ 1.0
}
/// 想法关联图
pub struct IdeaGraph {
/// 邻接表idea_id -> 相关关系列表)
edges: HashMap<IdeaId, Vec<Relation>>,
}
impl IdeaGraph {
/// 创建空图
pub fn new() -> Self {
Self {
edges: HashMap::new(),
}
}
/// 添加关系
pub fn add_relation(&mut self, source_id: IdeaId, target_id: IdeaId, kind: RelationKind, strength: f64) {
let relation = Relation {
source_id: source_id.clone(),
target_id: target_id.clone(),
kind,
strength,
};
self.edges.entry(source_id).or_default().push(relation.clone());
self.edges.entry(target_id).or_default().push(relation);
}
/// 获取与指定想法相关的所有关系
pub fn get_relations(&self, idea_id: &IdeaId) -> Vec<&Relation> {
self.edges.get(idea_id).map(|r| r.iter().collect()).unwrap_or_default()
}
/// 查找相似想法
pub fn find_similar(&self, idea_id: &IdeaId) -> Vec<&Relation> {
self.get_relations(idea_id)
.into_iter()
.filter(|r| r.kind == RelationKind::Similar)
.collect()
}
// TODO: 基于向量相似度的自动关联发现
// TODO: 图遍历、聚类算法
}
impl Default for IdeaGraph {
fn default() -> Self {
Self::new()
}
}

View File

@@ -0,0 +1,8 @@
//! df-ideas: 想法池 — 捕获、评估、评分、关联图、晋升
pub mod adversarial;
pub mod capture;
pub mod evaluator;
pub mod graph;
pub mod promotion;
pub mod scoring;

View File

@@ -0,0 +1,91 @@
//! 想法晋升 — 将想法转为项目
use anyhow::Result;
use df_core::types::{IdeaId, ProjectId};
use crate::capture::Idea;
use crate::evaluator::Recommendation;
/// 晋升结果
#[derive(Debug, Clone)]
pub struct PromotionResult {
pub idea_id: IdeaId,
pub project_id: ProjectId,
pub promoted: bool,
pub reason: String,
}
/// 晋升策略
#[derive(Debug, Clone, Copy)]
pub enum PromotionPolicy {
/// 自动晋升(评分达标时自动转为项目)
Auto,
/// 手动确认(需要人工审批)
Manual,
/// 半自动AI 评估 + 人工确认)
SemiAuto,
}
/// 想法晋升器
pub struct IdeaPromoter {
policy: PromotionPolicy,
}
impl IdeaPromoter {
/// 创建晋升器
pub fn new(policy: PromotionPolicy) -> Self {
Self { policy }
}
/// 评估并尝试晋升想法
///
/// TODO: 接入 df-project 创建项目
pub fn try_promote(&self, idea: &Idea, recommendation: &Recommendation) -> Result<PromotionResult> {
match self.policy {
PromotionPolicy::Auto => {
if matches!(recommendation, Recommendation::StrongApprove | Recommendation::Approve) {
self.do_promote(idea)
} else {
Ok(PromotionResult {
idea_id: idea.id.clone(),
project_id: String::new(),
promoted: false,
reason: format!("评估建议 {:?},未达到自动晋升标准", recommendation),
})
}
}
PromotionPolicy::Manual => {
Ok(PromotionResult {
idea_id: idea.id.clone(),
project_id: String::new(),
promoted: false,
reason: "手动模式,等待人工审批".to_string(),
})
}
PromotionPolicy::SemiAuto => {
// TODO: AI 评估 + 人工确认流程
Ok(PromotionResult {
idea_id: idea.id.clone(),
project_id: String::new(),
promoted: false,
reason: "半自动模式,等待确认".to_string(),
})
}
}
}
/// 执行晋升操作
fn do_promote(&self, idea: &Idea) -> Result<PromotionResult> {
let project_id = df_core::types::new_id();
// TODO: 调用 df-project 创建项目
tracing::info!("想法 {} 晋升为项目 {}", idea.id, project_id);
Ok(PromotionResult {
idea_id: idea.id.clone(),
project_id,
promoted: true,
reason: "评估达标,自动晋升".to_string(),
})
}
}

View File

@@ -0,0 +1,75 @@
//! 评分引擎 — 多维度加权评分
use crate::capture::Idea;
/// 想法评分详情(重新导出 capture 模块中的定义)
pub use crate::capture::IdeaScores;
/// 评分权重配置
#[derive(Debug, Clone)]
pub struct ScoringWeights {
pub feasibility: f64,
pub impact: f64,
pub urgency: f64,
}
impl Default for ScoringWeights {
fn default() -> Self {
Self {
feasibility: 0.4,
impact: 0.4,
urgency: 0.2,
}
}
}
/// 评分引擎
pub struct ScoringEngine;
impl ScoringEngine {
/// 使用默认权重计算评分
///
/// TODO: 接入 AI 进行深度评分,当前返回基于启发式的分数
pub fn compute_default(idea: &Idea) -> IdeaScores {
let weights = ScoringWeights::default();
Self::compute(idea, &weights)
}
/// 使用指定权重计算评分
pub fn compute(idea: &Idea, weights: &ScoringWeights) -> IdeaScores {
// TODO: 基于想法内容、历史数据、AI 分析等多维度评分
// 当前使用基于启发式的占位评分
let feasibility = Self::heuristic_feasibility(idea);
let impact = Self::heuristic_impact(idea);
let urgency = Self::heuristic_urgency(idea);
let overall = feasibility * weights.feasibility
+ impact * weights.impact
+ urgency * weights.urgency;
IdeaScores {
feasibility,
impact,
urgency,
overall,
}
}
/// 启发式可行性评分
fn heuristic_feasibility(_idea: &Idea) -> f64 {
// TODO: 基于描述复杂度、资源需求等评估
5.0
}
/// 启发式影响力评分
fn heuristic_impact(_idea: &Idea) -> f64 {
// TODO: 基于业务价值、用户影响等评估
5.0
}
/// 启发式紧急度评分
fn heuristic_urgency(_idea: &Idea) -> f64 {
// TODO: 基于优先级、时间窗口等评估
5.0
}
}