feat: add 19 fast commands (no-LLM) + incremental embeddings indexing

Fast commands for git, email, calendar, notes, search, reminders, and
diagnostics — all execute instantly without Claude CLI. Incremental
embeddings indexing in heartbeat (1h cooldown) + inline indexing after
/note, /jurnal, /email save. Fix Ollama URL (localhost → 10.0.20.161),
fix email_process.py KB path (kb/ → memory/kb/).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
MoltBot Service
2026-02-15 15:10:44 +00:00
parent 8b76a2dbf7
commit c8ce94611b
7 changed files with 1300 additions and 3 deletions

View File

@@ -222,6 +222,48 @@ def reindex() -> dict:
return {"files": files_count, "chunks": chunks_count}
def incremental_index() -> dict:
"""Index only new or modified .md files. Returns {"indexed": N, "chunks": M}."""
conn = get_db()
try:
# Get latest updated_at per file from DB
rows = conn.execute(
"SELECT file_path, MAX(updated_at) FROM chunks GROUP BY file_path"
).fetchall()
db_times = {}
for rel_path, updated_at in rows:
try:
db_times[rel_path] = datetime.fromisoformat(updated_at)
except (ValueError, TypeError):
pass
finally:
conn.close()
files_indexed = 0
chunks_total = 0
for md_file in sorted(MEMORY_DIR.rglob("*.md")):
rel_path = str(md_file.relative_to(MEMORY_DIR))
file_mtime = datetime.fromtimestamp(
md_file.stat().st_mtime, tz=timezone.utc
)
db_time = db_times.get(rel_path)
if db_time is not None:
# Ensure both are offset-aware for comparison
if db_time.tzinfo is None:
db_time = db_time.replace(tzinfo=timezone.utc)
if file_mtime <= db_time:
continue
try:
n = index_file(md_file)
files_indexed += 1
chunks_total += n
log.info("Incremental indexed %s (%d chunks)", md_file.name, n)
except Exception as e:
log.warning("Failed to index %s: %s", md_file, e)
return {"indexed": files_indexed, "chunks": chunks_total}
def search(query: str, top_k: int = 5) -> list[dict]:
"""Search for query. Returns list of {"file": str, "chunk": str, "score": float}."""
query_embedding = get_embedding(query)