use car_memgine::graph::{SkillScope, SkillTrigger};
use car_memgine::MemgineEngine;
use crate::types::*;
pub fn seed_defaults(engine: &mut MemgineEngine) {
for config in default_action_configs() {
let name = config.kind.skill_name();
let existing = engine.find_skill("", "", &name, 1);
if existing.iter().any(|(m, _)| m.name == name) {
continue;
}
let keywords: Vec<String> = config
.applicable_to
.iter()
.flat_map(|pc| pc.keywords())
.collect();
let keyword_str = keywords.join(" ");
let code = serde_json::to_string(&config).unwrap();
let description = match config.kind {
ActionKind::Classify => "Classify the problem type (bug, refactor, feature, etc.)",
ActionKind::Locate => "Find relevant code and files in the codebase",
ActionKind::RetrievePatterns => "Retrieve similar past fixes and patterns from memory",
ActionKind::Diagnose => "Analyze root cause of the problem",
ActionKind::GenerateFix => "Generate a code fix or implementation",
ActionKind::VerifyFix => "Verify the generated fix via static analysis",
ActionKind::Explain => "Explain what was wrong and how the fix works",
};
let when = match config.kind {
ActionKind::Classify => "Always runs first to determine problem type",
ActionKind::Locate => "When the problem involves specific code that needs to be found",
ActionKind::RetrievePatterns => "When graph memory has relevant past patterns",
ActionKind::Diagnose => "After locating code, to identify root cause",
ActionKind::GenerateFix => "After diagnosis, to produce a code solution",
ActionKind::VerifyFix => "After generating a fix, to check correctness",
ActionKind::Explain => "At the end, to provide human-readable explanation",
};
engine.ingest_skill_full(
&name,
&code,
"car-reason",
SkillTrigger {
persona: String::new(),
url_pattern: String::new(),
task_keywords: keyword_str.split_whitespace().map(String::from).collect(),
structured: None,
},
description,
SkillScope::Domain("reasoning".into()),
when,
None,
vec![],
vec![],
);
}
}
fn default_action_configs() -> Vec<ActionConfig> {
use ActionKind::*;
use ProblemClass::*;
vec![
ActionConfig {
kind: Classify,
applicable_to: vec![BugFix, Refactor, Architecture, NewFeature, Performance, TestWriting, Explanation, Unknown],
prerequisites: vec![],
prompt_template: "Classify this code problem into exactly one category: bug_fix, refactor, architecture, new_feature, performance, test_writing, or explanation.\n\nProblem: {problem}\n\nCategory:".into(),
priority: 0,
},
ActionConfig {
kind: Locate,
applicable_to: vec![BugFix, Refactor, NewFeature, Performance, TestWriting],
prerequisites: vec![Classify],
prompt_template: "Given this {problem_class} problem, identify the relevant files, functions, and code sections.\n\nProblem: {problem}\n\nContext from memory:\n{context}\n\nRelevant locations:".into(),
priority: 10,
},
ActionConfig {
kind: RetrievePatterns,
applicable_to: vec![BugFix, Refactor, NewFeature, Performance, TestWriting],
prerequisites: vec![Classify],
prompt_template: String::new(), priority: 10,
},
ActionConfig {
kind: Diagnose,
applicable_to: vec![BugFix, Refactor, Performance],
prerequisites: vec![Locate, RetrievePatterns],
prompt_template: "Analyze the root cause of this {problem_class} problem.\n\nProblem: {problem}\n\nRelevant code locations:\n{locations}\n\nSimilar past patterns:\n{patterns}\n\nContext from memory:\n{context}\n\nRoot cause analysis:".into(),
priority: 20,
},
ActionConfig {
kind: GenerateFix,
applicable_to: vec![BugFix, Refactor, NewFeature, Performance, TestWriting],
prerequisites: vec![Diagnose],
prompt_template: "Generate a code fix for this {problem_class} problem.\n\nProblem: {problem}\n\nDiagnosis: {diagnosis}\n\nContext from memory:\n{context}\n\nProvide the fix as a code block. Include the file path if known.\n\nFix:".into(),
priority: 30,
},
ActionConfig {
kind: VerifyFix,
applicable_to: vec![BugFix, Performance],
prerequisites: vec![GenerateFix],
prompt_template: "Review this code fix for correctness. Check for: off-by-one errors, null/None handling, type mismatches, missing edge cases.\n\nOriginal problem: {problem}\n\nDiagnosis: {diagnosis}\n\nProposed fix:\n{code}\n\nVerification result (PASS/FAIL with explanation):".into(),
priority: 40,
},
ActionConfig {
kind: Explain,
applicable_to: vec![BugFix, Refactor, Architecture, NewFeature, Performance, TestWriting, Explanation],
prerequisites: vec![Classify], prompt_template: "Explain this clearly and concisely for a developer.\n\nProblem: {problem}\n\n{diagnosis_section}{fix_section}\n\nExplanation:".into(),
priority: 50,
},
]
}
pub fn learn_from_session(engine: &mut MemgineEngine, result: &ReasoningResult, accepted: bool) {
if !accepted {
return;
}
let sequence: Vec<ActionKind> = result
.actions_taken
.iter()
.filter(|a| a.success)
.map(|a| a.action)
.collect();
if sequence.is_empty() {
return;
}
let strategy_name = format!(
"strategy:{}:{:.4}",
result.problem_class, result.overall_confidence,
);
let config = serde_json::json!({
"problem_class": result.problem_class,
"action_sequence": sequence,
"avg_confidence": result.overall_confidence,
"learned_from": result.session_id,
});
engine.ingest_skill_full(
&strategy_name,
&config.to_string(),
"car-reason",
SkillTrigger {
persona: String::new(),
url_pattern: String::new(),
task_keywords: result
.problem_class
.keywords()
.iter()
.map(|s| s.to_string())
.collect(),
structured: None,
},
&format!(
"Learned strategy for {} problems (confidence: {:.0}%)",
result.problem_class,
result.overall_confidence * 100.0
),
SkillScope::Domain("reasoning".into()),
&format!(
"Apply when solving {} problems with similar context",
result.problem_class
),
None,
vec![],
vec![],
);
}