Persistent semantic memory HTTP server for AI agents. No cloud, no API keys. Local vector index with Ollama/TF-IDF embeddings. Endpoints: /store, /recall, /forget, /list, /health
93 lines
2.9 KiB
Bash
Executable File
93 lines
2.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
NODE_BIN="$(command -v node)"
|
|
PLIST_LABEL="com.memory-bridge"
|
|
PLIST_DST="${HOME}/Library/LaunchAgents/${PLIST_LABEL}.plist"
|
|
LOG_DIR="${HOME}/.memory-bridge"
|
|
PORT="${MEMORY_BRIDGE_PORT:-3722}"
|
|
|
|
echo "════════════════════════════════════════"
|
|
echo " memory-bridge installer"
|
|
echo "════════════════════════════════════════"
|
|
echo " Install dir : ${SCRIPT_DIR}"
|
|
echo " Node : ${NODE_BIN}"
|
|
echo " Port : ${PORT}"
|
|
echo ""
|
|
|
|
# 1 ── npm install
|
|
echo "▶ Installing npm dependencies..."
|
|
cd "${SCRIPT_DIR}"
|
|
npm install --omit=dev
|
|
|
|
# 2 ── Pull nomic-embed-text
|
|
echo ""
|
|
echo "▶ Pulling nomic-embed-text via Ollama..."
|
|
if command -v ollama &>/dev/null; then
|
|
ollama pull nomic-embed-text
|
|
echo " nomic-embed-text ready."
|
|
else
|
|
echo " Warning: ollama not found in PATH."
|
|
echo " The server will use TF-IDF fallback for embeddings."
|
|
fi
|
|
|
|
# 3 ── Ensure log directory
|
|
mkdir -p "${LOG_DIR}"
|
|
|
|
# 4 ── Generate launchd plist from template
|
|
echo ""
|
|
echo "▶ Installing launchd agent..."
|
|
mkdir -p "${HOME}/Library/LaunchAgents"
|
|
sed \
|
|
-e "s|INSTALL_DIR|${SCRIPT_DIR}|g" \
|
|
-e "s|NODE_BIN|${NODE_BIN}|g" \
|
|
-e "s|HOME_DIR|${HOME}|g" \
|
|
"${SCRIPT_DIR}/com.memory-bridge.plist" > "${PLIST_DST}"
|
|
|
|
# 5 ── Load (or reload) service
|
|
if launchctl list 2>/dev/null | grep -q "${PLIST_LABEL}"; then
|
|
echo " Reloading existing service..."
|
|
launchctl unload "${PLIST_DST}" 2>/dev/null || true
|
|
fi
|
|
launchctl load "${PLIST_DST}"
|
|
|
|
# 6 ── Wait for server
|
|
echo ""
|
|
echo "▶ Waiting for server to start on port ${PORT}..."
|
|
READY=0
|
|
for i in $(seq 1 20); do
|
|
if curl -sf "http://localhost:${PORT}/health" >/dev/null 2>&1; then
|
|
READY=1
|
|
break
|
|
fi
|
|
sleep 1
|
|
done
|
|
|
|
if [ "${READY}" -eq 0 ]; then
|
|
echo " Server did not start within 20 seconds."
|
|
echo " Check logs: ${LOG_DIR}/server.log"
|
|
echo " Or run manually: node ${SCRIPT_DIR}/server.js"
|
|
exit 1
|
|
fi
|
|
|
|
# 7 ── Health check + show token
|
|
echo ""
|
|
echo "▶ Health check:"
|
|
curl -s "http://localhost:${PORT}/health" | python3 -m json.tool 2>/dev/null \
|
|
|| curl -s "http://localhost:${PORT}/health"
|
|
|
|
TOKEN=$(grep MEMORY_BRIDGE_TOKEN "${LOG_DIR}/.env" 2>/dev/null | cut -d= -f2 | tr -d '[:space:]' || echo '')
|
|
|
|
echo ""
|
|
echo "════════════════════════════════════════"
|
|
echo " memory-bridge is running!"
|
|
echo ""
|
|
echo " Health : http://localhost:${PORT}/health"
|
|
echo " Token : ${TOKEN:-'(see ~/.memory-bridge/.env)'}"
|
|
echo " Logs : ${LOG_DIR}/server.log"
|
|
echo ""
|
|
echo " Quick test:"
|
|
echo " curl -s http://localhost:${PORT}/health"
|
|
echo "════════════════════════════════════════"
|