#[derive(Debug, Clone)]
pub struct AutoInsight {
pub content: String,
pub tags: Vec<String>,
pub importance: f64,
pub dedup_tag: String,
}
pub fn check_triggers(
storage: &dyn codemem_core::StorageBackend,
session_id: &str,
tool_name: &str,
file_path: Option<&str>,
pattern: Option<&str>,
) -> Vec<AutoInsight> {
let mut insights = Vec::new();
if tool_name == "Read" {
if let Some(fp) = file_path {
let directory = std::path::Path::new(fp)
.parent()
.map(|p| p.to_string_lossy().to_string())
.unwrap_or_default();
if !directory.is_empty() {
let dedup_tag = format!("dir_focus:{}", directory);
let already_exists = storage
.has_auto_insight(session_id, &dedup_tag)
.unwrap_or(true);
if !already_exists {
let count = storage
.count_directory_reads(session_id, &directory)
.unwrap_or(0);
if count >= 3 {
insights.push(AutoInsight {
content: format!(
"Deep exploration of directory '{}': {} files read in this session. \
This area may be a focus of the current task.",
directory, count
),
tags: vec![
"auto-insight".to_string(),
"directory-focus".to_string(),
format!("dir:{}", directory),
],
importance: 0.6,
dedup_tag,
});
}
}
}
}
}
if matches!(tool_name, "Edit" | "Write") {
if let Some(fp) = file_path {
let dedup_tag = format!("edit_after_read:{}", fp);
let already_exists = storage
.has_auto_insight(session_id, &dedup_tag)
.unwrap_or(true);
if !already_exists {
let was_read = storage
.was_file_read_in_session(session_id, fp)
.unwrap_or(false);
if was_read {
insights.push(AutoInsight {
content: format!(
"File '{}' was read and then modified in this session, \
indicating an informed change based on code review.",
fp
),
tags: vec![
"auto-insight".to_string(),
"edit-after-read".to_string(),
format!(
"file:{}",
std::path::Path::new(fp)
.file_name()
.and_then(|f| f.to_str())
.unwrap_or("unknown")
),
],
importance: 0.5,
dedup_tag,
});
}
}
}
}
if tool_name == "Read" {
if let Some(fp) = file_path {
let directory = std::path::Path::new(fp)
.parent()
.map(|p| p.to_string_lossy().to_string())
.unwrap_or_default();
if !directory.is_empty() {
let module_name = std::path::Path::new(&directory)
.file_name()
.and_then(|f| f.to_str())
.unwrap_or("unknown");
let dedup_tag = format!("exploring_module:{}", directory);
let already_exists = storage
.has_auto_insight(session_id, &dedup_tag)
.unwrap_or(true);
if !already_exists {
let count = storage
.count_directory_reads(session_id, &directory)
.unwrap_or(0);
if count >= 3 {
insights.push(AutoInsight {
content: format!(
"Exploring '{}' module: {} files read. Building understanding of this area.",
module_name, count
),
tags: vec![
"auto-insight".to_string(),
"exploring-module".to_string(),
format!("module:{}", module_name),
],
importance: 0.55,
dedup_tag,
});
}
}
}
}
}
if tool_name == "Bash" {
let has_error = storage
.count_search_pattern_in_session(session_id, "error")
.unwrap_or(0)
> 0;
if has_error {
let area = file_path
.and_then(|fp| {
std::path::Path::new(fp)
.parent()
.and_then(|p| p.file_name())
.and_then(|f| f.to_str())
})
.unwrap_or("project");
let dedup_tag = format!("debugging:{}", area);
let already_exists = storage
.has_auto_insight(session_id, &dedup_tag)
.unwrap_or(true);
if !already_exists {
insights.push(AutoInsight {
content: format!(
"Debugging in '{}': error output detected in bash commands during this session.",
area
),
tags: vec![
"auto-insight".to_string(),
"debugging".to_string(),
format!("area:{}", area),
],
importance: 0.6,
dedup_tag,
});
}
}
}
if matches!(tool_name, "Grep" | "Glob") {
if let Some(pat) = pattern {
let dedup_tag = format!("repeated_search:{}", pat);
let already_exists = storage
.has_auto_insight(session_id, &dedup_tag)
.unwrap_or(true);
if !already_exists {
let count = storage
.count_search_pattern_in_session(session_id, pat)
.unwrap_or(0);
if count >= 2 {
insights.push(AutoInsight {
content: format!(
"Search pattern '{}' used {} times in this session. \
Consider storing a permanent memory for this recurring lookup.",
pat, count
),
tags: vec![
"auto-insight".to_string(),
"repeated-search".to_string(),
format!("pattern:{}", pat),
],
importance: 0.5,
dedup_tag,
});
}
}
}
}
insights
}