From e8d0f946b5b4bd9077323dce164e58eed580e800 Mon Sep 17 00:00:00 2001 From: Santhosh Janardhanan Date: Mon, 13 Apr 2026 14:37:12 -0400 Subject: [PATCH] fix: improve watcher with per-file debounce, logging, and validation --- src/companion/indexer_daemon/watcher.py | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/companion/indexer_daemon/watcher.py b/src/companion/indexer_daemon/watcher.py index bfd0516..8e631df 100644 --- a/src/companion/indexer_daemon/watcher.py +++ b/src/companion/indexer_daemon/watcher.py @@ -1,5 +1,6 @@ from __future__ import annotations +import logging import time from pathlib import Path @@ -10,39 +11,49 @@ from companion.config import load_config from companion.rag.indexer import Indexer from companion.rag.vector_store import VectorStore +logger = logging.getLogger(__name__) + class VaultEventHandler(FileSystemEventHandler): + """Handles file system events in the vault directory and triggers indexing.""" + def __init__(self, indexer: Indexer, debounce_seconds: float = 5.0): self.indexer = indexer self.debounce_seconds = debounce_seconds - self._last_sync = 0.0 + self._last_sync: dict[str, float] = {} def on_any_event(self, event): + """Process a file system event and debounce per file path.""" if event.is_directory: return if not event.src_path.endswith(".md"): return + path = event.src_path now = time.time() - if now - self._last_sync < self.debounce_seconds: + if now - self._last_sync.get(path, 0) < self.debounce_seconds: return - self._last_sync = now + self._last_sync[path] = now try: self.indexer.sync() - except Exception as exc: - print(f"Sync failed: {exc}") + except (OSError, RuntimeError) as exc: + logger.error("Sync failed: %s", exc) def start_watcher(config_path: str = "config.json") -> None: + """Load configuration and start watching the vault directory for changes.""" config = load_config(config_path) + vault_path = Path(config.vault.path) + if not vault_path.exists(): + raise FileNotFoundError(f"Vault path does not exist: {vault_path}") store = VectorStore( uri=config.rag.vector_store.path, dimensions=config.rag.embedding.dimensions ) indexer = Indexer(config, store) handler = VaultEventHandler(indexer) observer = Observer() - observer.schedule(handler, str(config.vault.path), recursive=True) + observer.schedule(handler, str(vault_path), recursive=True) observer.start() - print(f"Watching {config.vault.path} for changes...") + logger.info("Watching %s for changes...", vault_path) try: while True: time.sleep(1)