diff --git a/crates/zclaw-growth/src/experience_extractor.rs b/crates/zclaw-growth/src/experience_extractor.rs index aa277a0..332becd 100644 --- a/crates/zclaw-growth/src/experience_extractor.rs +++ b/crates/zclaw-growth/src/experience_extractor.rs @@ -45,13 +45,16 @@ impl ExperienceExtractor { Outcome::Partial => "partial", Outcome::Failed => "failed", }; - let exp = crate::experience_store::Experience::new( + let mut exp = crate::experience_store::Experience::new( agent_id, &candidate.pain_pattern, &candidate.context, candidate.solution_steps.clone(), outcome_str, ); + // 填充 tool_used:取 tools_used 中的第一个作为主要工具 + exp.tool_used = candidate.tools_used.first().cloned(); + exp.industry_context = candidate.industry_context.clone(); store.store_experience(&exp).await?; count += 1; } diff --git a/crates/zclaw-growth/src/experience_store.rs b/crates/zclaw-growth/src/experience_store.rs index ca0310c..ec6f8fe 100644 --- a/crates/zclaw-growth/src/experience_store.rs +++ b/crates/zclaw-growth/src/experience_store.rs @@ -48,6 +48,9 @@ pub struct Experience { /// Which trigger signal produced this experience. #[serde(default)] pub source_trigger: Option, + /// Primary tool/skill used to resolve this pain point. + #[serde(default)] + pub tool_used: Option, } impl Experience { @@ -72,6 +75,7 @@ impl Experience { updated_at: now, industry_context: None, source_trigger: None, + tool_used: None, } } @@ -124,6 +128,9 @@ impl ExperienceStore { if let Some(ref industry) = exp.industry_context { keywords.push(industry.clone()); } + if let Some(ref tool) = exp.tool_used { + keywords.push(tool.clone()); + } let entry = MemoryEntry { uri, diff --git a/crates/zclaw-growth/src/pattern_aggregator.rs b/crates/zclaw-growth/src/pattern_aggregator.rs index eb28c4f..4c2cd90 100644 --- a/crates/zclaw-growth/src/pattern_aggregator.rs +++ b/crates/zclaw-growth/src/pattern_aggregator.rs @@ -52,11 +52,10 @@ impl PatternAggregator { let total_reuse: u32 = experiences.iter().map(|e| e.reuse_count).sum(); let common_steps = Self::find_common_steps(&experiences); - // 从 context 字段提取工具名(context 存储的是触发工具/来源标识) - // Experience 结构没有独立的 tools 字段,context 作为来源标识使用 + // 从 tool_used 字段提取工具名 let tools: Vec = experiences .iter() - .map(|e| e.context.clone()) + .filter_map(|e| e.tool_used.clone()) .filter(|s| !s.is_empty()) .collect::>() .into_iter()