use car_inference::InferenceEngine;
use crate::types::ProblemClass;
use crate::ReasonError;
pub async fn classify_problem(
_engine: &InferenceEngine,
problem: &str,
) -> Result<ProblemClass, ReasonError> {
let result = classify_by_keywords(problem);
Ok(result)
}
pub fn classify_by_keywords(problem: &str) -> ProblemClass {
let lower = problem.to_lowercase();
let question_starters = ["why ", "why does", "how does", "what is", "what are",
"what's the", "can you explain", "describe how",
"trade-off", "tradeoff", "pros and cons",
"compared to", "versus", "vs "];
let is_question = question_starters.iter().any(|q| lower.contains(q));
let is_how_would = lower.contains("how would") || lower.contains("how to add")
|| lower.contains("how can we") || lower.contains("how do you");
if is_question && !is_how_would {
let arch_terms = ["architecture", "design", "trade-off", "tradeoff", "pattern",
"approach", "decision", "structure", "versus", "vs "];
if arch_terms.iter().any(|t| lower.contains(t)) {
return ProblemClass::Architecture;
}
return ProblemClass::Explanation;
}
let scores = [
(ProblemClass::BugFix, &["bug", "fix", "broken", "error", "crash", "wrong", "fail", "issue", "debug"][..]),
(ProblemClass::Refactor, &["refactor", "clean", "simplify", "restructure", "rename", "extract"]),
(ProblemClass::Performance, &["slow", "optimize", "performance", "latency", "throughput", "bottleneck"]),
(ProblemClass::TestWriting, &["test", "coverage", "assert", "spec", "unit test", "integration test"]),
(ProblemClass::Architecture, &["architecture", "design", "pattern", "structure", "approach", "trade-off"]),
(ProblemClass::NewFeature, &["implement", "create", "feature", "endpoint", "module", "component"]),
(ProblemClass::Explanation, &["explain", "understand", "describe", "clarify", "meaning"]),
];
let mut best = ProblemClass::Unknown;
let mut best_score = 0usize;
for (class, keywords) in &scores {
let score = keywords.iter().filter(|kw| lower.contains(*kw)).count();
if score > best_score {
best_score = score;
best = *class;
}
}
if best == ProblemClass::Unknown && is_how_would {
best = ProblemClass::NewFeature;
}
best
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn keyword_classification() {
assert_eq!(classify_by_keywords("fix this broken test"), ProblemClass::BugFix);
assert_eq!(classify_by_keywords("refactor the authentication module"), ProblemClass::Refactor);
assert_eq!(classify_by_keywords("optimize the database query performance"), ProblemClass::Performance);
assert_eq!(classify_by_keywords("implement a new endpoint for user profiles"), ProblemClass::NewFeature);
assert_eq!(classify_by_keywords("explain how the routing works"), ProblemClass::Explanation);
assert_eq!(classify_by_keywords("write unit tests for the parser"), ProblemClass::TestWriting);
assert_eq!(classify_by_keywords("design the architecture for the new service"), ProblemClass::Architecture);
}
#[test]
fn ambiguous_defaults_to_strongest() {
assert_eq!(classify_by_keywords("fix this error in the code"), ProblemClass::BugFix);
}
#[test]
fn question_patterns_classify_correctly() {
assert_eq!(
classify_by_keywords("Why does car-reason use memgine skills for reasoning actions instead of a hardcoded pipeline?"),
ProblemClass::Explanation,
);
assert_eq!(
classify_by_keywords("What are the trade-offs of this design?"),
ProblemClass::Architecture,
);
assert_eq!(
classify_by_keywords("How would you add action-aware routing so simple actions use small models?"),
ProblemClass::NewFeature,
);
}
}