File size: 3,626 Bytes
a753e74
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#!/usr/bin/env bash
set -euo pipefail
source "$(dirname "${BASH_SOURCE[0]}")/_common.sh"

# Ensure .env exists.
if [ ! -f "$ROOT/.env" ]; then
  if [ -f "$ROOT/.env.example" ]; then
    cp "$ROOT/.env.example" "$ROOT/.env"
    c_yellow "Created .env from .env.example."
    set -a; . "$ROOT/.env"; set +a
  else
    c_yellow "No .env or .env.example found; using built-in defaults."
  fi
fi

start_backend() {
  c_dim "Starting backend (bind ${BIND_HOST}:${BACKEND_PORT}) …"
  nohup python -m uvicorn researchlink.api.app:app \
    --host "$BIND_HOST" --port "$BACKEND_PORT" --log-level info \
    > "$BACKEND_LOG" 2>&1 &
  echo $! > "$BACKEND_PID"
}

# ── Backend: idempotent + health-verified ────────────────────────────────────
if pid_alive "$BACKEND_PID"; then
  if http_ok "$HEALTH_URL/api/health"; then
    c_yellow "Backend already running and healthy (pid $(cat "$BACKEND_PID"))."
  else
    c_yellow "Backend pid alive but not responding β€” restarting."
    kill "$(cat "$BACKEND_PID")" 2>/dev/null || true; sleep 1; start_backend
  fi
elif port_in_use "127.0.0.1" "$BACKEND_PORT"; then
  c_red "Port ${BACKEND_PORT} is in use by another process."
  c_dim "Free it, or set RESEARCHLINK_BACKEND_PORT in .env, then run 'make start' again."
  exit 1
else
  start_backend
fi

if ! wait_health "$HEALTH_URL/api/health" 40; then
  c_red "Backend failed to become healthy. Last log lines:"
  tail -n 20 "$BACKEND_LOG" 2>/dev/null || true
  exit 1
fi

# ── Optional Node frontend (only if one exists) ──────────────────────────────
FRONTEND_URL="${BACKEND_URL}/"
if [ -f "$FRONTEND_DIR/package.json" ]; then
  if pid_alive "$FRONTEND_PID"; then
    c_yellow "Frontend already running (pid $(cat "$FRONTEND_PID"))."
  elif port_in_use "127.0.0.1" "$FRONTEND_PORT"; then
    c_red "Frontend port ${FRONTEND_PORT} in use β€” set RESEARCHLINK_FRONTEND_PORT."
  else
    c_dim "Starting frontend dev server …"
    ( cd "$FRONTEND_DIR" && nohup npm run dev -- --host "$FRONTEND_HOST" --port "$FRONTEND_PORT" \
      > "$FRONTEND_LOG" 2>&1 & echo $! > "$FRONTEND_PID" )
    FRONTEND_URL="http://${ADV_HOST}:${FRONTEND_PORT}"
  fi
else
  c_dim "No separate frontend project β€” the UI is served by the backend."
fi

# ── Verify every service endpoint (on loopback) ──────────────────────────────
echo
c_green "Services:"
all_ok=1
for path in /api/health /api/config /api/llm/status /api/papers; do
  if http_ok "${HEALTH_URL}${path}"; then
    c_green "  βœ“ ${path}"
  else
    c_red   "  βœ— ${path}"; all_ok=0
  fi
done

echo
c_green "Research-Link-AI is running."
echo "  Open in your browser : $FRONTEND_URL"
echo "  Backend / API base   : $BACKEND_URL   (API: $BACKEND_URL/api)"
if [ "$ADV_HOST" != "127.0.0.1" ]; then
  echo "  Local (on server)    : http://127.0.0.1:${BACKEND_PORT}/"
fi
echo "  Binding              : ${BIND_HOST}:${BACKEND_PORT} (all interfaces)"
echo "  LLM mode             : $LLM_MODE   model: $LLM_MODEL   $(is_external_mode && echo '(external provider)' || echo '(offline / local)')"
if is_external_mode; then echo "  API key              : $(key_configured)"; fi
echo "  Logs                 : $BACKEND_LOG"
echo
c_dim "Reachable from other machines at ${BACKEND_URL} (ensure the port is open in the firewall)."
c_dim "Stop with: make stop   Β·   Status: make status   Β·   Logs: make logs"
[ "$all_ok" -eq 1 ] || { c_yellow "Some endpoints did not respond β€” see 'make logs'."; exit 1; }