feat(embedding,vision): candle embeddings with offline fallback, on-demand clipboard vision capture, and concurrency audit

This commit is contained in:
Riz Ashraf committed 2026-10-07 06:36:09 +01:00
1 parent 5bd8b1587a
commit e4a0fe72df
47 files changed
+6292 -3503

No files matched your search

+32 -16
View File
@@ -34,28 +34,44 @@ pub fn spawn_watcher(state: Arc<MemoryState>) {
let mut last_processed: std::collections::HashMap<std::path::PathBuf, std::time::Instant> =
std::collections::HashMap::new();
while let Some(res) = rx.recv().await {
match res {
Ok(event) => {
if event.kind.is_modify() {
let now = std::time::Instant::now();
for path in event.paths {
if should_review(&path) {
// 250ms debouncing window per file path
if let Some(last) = last_processed.get(&path) {
if now.duration_since(*last) < std::time::Duration::from_millis(250) {
continue;
loop {
tokio::select! {
_ = state.shutdown_notify.notified() => {
info!("File watcher received shutdown notification; terminating cleanly.");
break;
}
res = rx.recv() => {
let Some(res) = res else {
break;
};
match res {
Ok(event) => {
if event.kind.is_modify() {
let now = std::time::Instant::now();
if last_processed.len() > 1000 {
let ten_mins = std::time::Duration::from_secs(600);
last_processed.retain(|_, last_time| now.duration_since(*last_time) < ten_mins);
}
for path in event.paths {
if should_review(&path) {
// 250ms debouncing window per file path
if let Some(last) = last_processed.get(&path) {
if now.duration_since(*last) < std::time::Duration::from_millis(250) {
continue;
}
}
last_processed.insert(path.clone(), now);
info!("Proactive Daemon Hooks: File modified: {:?}", path);
trigger_autonomous_review(&path, Arc::clone(&state)).await;
}
}
last_processed.insert(path.clone(), now);
info!("Proactive Daemon Hooks: File modified: {:?}", path);
trigger_autonomous_review(&path, Arc::clone(&state)).await;
}
}
Err(e) => error!("Watch error: {}", e),
}
}
Err(e) => error!("Watch error: {}", e),
}
}
});