stage-10: memory search with Ollama embeddings + SQLite
Semantic search over memory/*.md files using all-minilm embeddings. Adds /search Discord command and `echo memory search/reindex` CLI. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
58
cli.py
58
cli.py
@@ -405,6 +405,52 @@ def _cron_disable(name: str):
|
||||
print(f"Job '{name}' not found.")
|
||||
|
||||
|
||||
def cmd_memory(args):
|
||||
"""Handle memory subcommand."""
|
||||
if args.memory_action == "search":
|
||||
_memory_search(args.query)
|
||||
elif args.memory_action == "reindex":
|
||||
_memory_reindex()
|
||||
|
||||
|
||||
def _memory_search(query: str):
|
||||
"""Search memory and print results."""
|
||||
from src.memory_search import search
|
||||
|
||||
try:
|
||||
results = search(query)
|
||||
except ConnectionError as e:
|
||||
print(f"Error: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
if not results:
|
||||
print("No results found (index may be empty — run `echo memory reindex`).")
|
||||
return
|
||||
|
||||
for i, r in enumerate(results, 1):
|
||||
score = r["score"]
|
||||
print(f"\n--- Result {i} (score: {score:.3f}) ---")
|
||||
print(f"File: {r['file']}")
|
||||
preview = r["chunk"][:200]
|
||||
if len(r["chunk"]) > 200:
|
||||
preview += "..."
|
||||
print(preview)
|
||||
|
||||
|
||||
def _memory_reindex():
|
||||
"""Rebuild memory search index."""
|
||||
from src.memory_search import reindex
|
||||
|
||||
print("Reindexing memory files...")
|
||||
try:
|
||||
stats = reindex()
|
||||
except ConnectionError as e:
|
||||
print(f"Error: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
print(f"Done. Indexed {stats['files']} files, {stats['chunks']} chunks.")
|
||||
|
||||
|
||||
def cmd_heartbeat(args):
|
||||
"""Run heartbeat health checks."""
|
||||
from src.heartbeat import run_heartbeat
|
||||
@@ -515,6 +561,15 @@ def main():
|
||||
|
||||
secrets_sub.add_parser("test", help="Check required secrets")
|
||||
|
||||
# memory
|
||||
memory_parser = sub.add_parser("memory", help="Memory search commands")
|
||||
memory_sub = memory_parser.add_subparsers(dest="memory_action")
|
||||
|
||||
memory_search_p = memory_sub.add_parser("search", help="Search memory files")
|
||||
memory_search_p.add_argument("query", help="Search query text")
|
||||
|
||||
memory_sub.add_parser("reindex", help="Rebuild memory search index")
|
||||
|
||||
# heartbeat
|
||||
sub.add_parser("heartbeat", help="Run heartbeat health checks")
|
||||
|
||||
@@ -563,6 +618,9 @@ def main():
|
||||
cmd_channel(a) if a.channel_action else (channel_parser.print_help() or sys.exit(0))
|
||||
),
|
||||
"send": cmd_send,
|
||||
"memory": lambda a: (
|
||||
cmd_memory(a) if a.memory_action else (memory_parser.print_help() or sys.exit(0))
|
||||
),
|
||||
"heartbeat": cmd_heartbeat,
|
||||
"cron": lambda a: (
|
||||
cmd_cron(a) if a.cron_action else (cron_parser.print_help() or sys.exit(0))
|
||||
|
||||
Reference in New Issue
Block a user