Generalized + redeployable: config via env, local Ollama embeddings, single portable sqlite-vec db, hybrid dense+FTS5 recall, mandatory credential scrub.
36 lines
1.7 KiB
Bash
Executable file
36 lines
1.7 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# SecondBrain — continuous refresh (niced, locked, idempotent).
|
|
# Re-ingests your configured sources, re-scrubs, and embeds a bounded backlog.
|
|
# Configure via environment (or a .env next to brain.py):
|
|
#
|
|
# BRAIN_DIR dir containing brain.py (default: script's parent)
|
|
# BRAIN_HOME db location (default: ~/.secondbrain)
|
|
# SB_FILE_DIRS colon-separated dirs to ingest as files
|
|
# SB_TRANSCRIPTS dir of *.jsonl agent sessions (optional)
|
|
# SB_EVENTS_DB sqlite events db (optional)
|
|
# SB_EMBED_LIMIT chunks to embed per run (default: 6000)
|
|
#
|
|
# Run from cron/systemd-timer, e.g. every 15 min.
|
|
set -euo pipefail
|
|
BRAIN_DIR="${BRAIN_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
|
|
BRAIN_HOME="${BRAIN_HOME:-$HOME/.secondbrain}"
|
|
PY="${SB_PYTHON:-python3}"
|
|
LOGDIR="$BRAIN_HOME/logs"; mkdir -p "$LOGDIR"
|
|
LOCK="$LOGDIR/.refresh.lock"
|
|
|
|
exec 9>"$LOCK"
|
|
flock -n 9 || { echo "[refresh] $(date -Is) busy, skip" >> "$LOGDIR/refresh.log"; exit 0; }
|
|
|
|
cd "$BRAIN_DIR"
|
|
[ -f .env ] && set -a && . ./.env && set +a
|
|
{
|
|
echo "[refresh] $(date -Is) start"
|
|
$PY brain.py init
|
|
IFS=':' read -ra DIRS <<< "${SB_FILE_DIRS:-}"
|
|
for d in "${DIRS[@]}"; do [ -n "$d" ] && [ -d "$d" ] && $PY brain.py ingest-files "$d"; done
|
|
[ -n "${SB_TRANSCRIPTS:-}" ] && [ -d "$SB_TRANSCRIPTS" ] && $PY brain.py ingest-transcripts "$SB_TRANSCRIPTS"
|
|
[ -n "${SB_EVENTS_DB:-}" ] && [ -f "$SB_EVENTS_DB" ] && $PY brain.py ingest-events --db "$SB_EVENTS_DB"
|
|
$PY brain.py rescrub
|
|
nice -n 15 $PY brain.py embed --limit "${SB_EMBED_LIMIT:-6000}" --batch 64
|
|
echo "[refresh] $(date -Is) done"
|
|
} >> "$LOGDIR/refresh.log" 2>&1
|