55# What this script does (in order):
66# 1. Loads .env into the shell environment
77# 2. Waits until Redis is reachable (up to 30 s)
8- # 3. Starts the Manim MCP server in the background (optional, skipped if
9- # SKIP_MANIM=1 is set or the venv doesn't have manim installed)
10- # 4. Starts the Streamlit app in the foreground
8+ # 3. Starts the Streamlit app in the foreground
119#
1210# Usage:
1311# chmod +x entrypoint.sh
1412# ./entrypoint.sh
1513#
16- # Skip Manim:
17- # SKIP_MANIM=1 ./entrypoint.sh
18- #
1914# Custom port:
2015# STREAMLIT_PORT=8502 ./entrypoint.sh
2116#
@@ -49,27 +44,38 @@ echo -e "${NC}"
4944
5045# ── Step 1: load .env ─────────────────────────────────────────────────────────
5146ENV_FILE=" ${ENV_FILE:- .env} "
47+
5248if [ -f " $ENV_FILE " ]; then
5349 log " Loading environment from $ENV_FILE "
54- # Export every non-comment, non-blank line
55- set -o allexport
56- # shellcheck disable=SC1090
57- source " $ENV_FILE "
58- set +o allexport
59- ok " Environment loaded"
50+
51+ # Export each KEY=value line safely
52+ while IFS= read -r line || [[ -n " $line " ]]; do
53+ # Skip empty lines and comments
54+ [[ -z " $line " || " $line " =~ ^[[:space:]]* # ]] && continue
55+
56+ # Export the variable
57+ if [[ " $line " =~ ^[A-Za-z_][A-Za-z0-9_]* = ]]; then
58+ key=" ${line%% =* } "
59+ value=" ${line#* =} "
60+ export " $key =$value "
61+ # Show masked value for logging
62+ if [ ${# value} -gt 12 ]; then
63+ masked=" ${value: 0: 6} ...${value: -4} "
64+ else
65+ masked=" $value "
66+ fi
67+ log " Set: $key =${masked} "
68+ fi
69+ done < " $ENV_FILE "
70+
71+ ok " Environment variables loaded"
6072else
61- warn " .env not found at $ENV_FILE — relying on existing environment variables "
73+ warn " .env file not found at $ENV_FILE "
6274fi
6375
6476# ── Step 2: verify required variables ─────────────────────────────────────────
6577REQUIRED_VARS= (
66- GROQ_API_KEY
67- COHERE_API_KEY
68- TAVILY_API_KEY
6978 REDIS_URL
70- GOOGLE_CLIENT_ID
71- GOOGLE_CLIENT_SECRET
72- OAUTH_REDIRECT_URI
7379)
7480
7581MISSING= 0
@@ -91,11 +97,15 @@ if [ -z "${GOOGLE_CREDENTIALS_JSON:-}" ] && [ -z "${GOOGLE_APPLICATION_CREDENTIA
9197 warn " Image (OCR) input will not work."
9298fi
9399
100+ # ── Optional: run tests only and exit ─────────────────────────────────────────
101+ if [ " ${RUN_TESTS:- 0} " = " 1" ]; then
102+ log " RUN_TESTS=1 detected — running pytest and exiting"
103+ exec pytest
104+ fi
105+
94106# ── Step 3: wait for Redis ────────────────────────────────────────────────────
95107log " Waiting for Redis at ${REDIS_URL} ..."
96108
97- # Extract host:port from REDIS_URL for redis-cli
98- # Handles: redis://:pass@host:port and rediss://user:pass@host:port
99109REDIS_HOST= $( echo " $REDIS_URL " | sed -E ' s|rediss?://[^@]*@([^:]+):.*|\1|' )
100110REDIS_PORT= $( echo " $REDIS_URL " | sed -E ' s|rediss?://[^@]*@[^:]+:([0-9]+).*|\1|' )
101111REDIS_PASS= $( echo " $REDIS_URL " | sed -E ' s|rediss?://[^:]*:([^@]*)@.*|\1|' )
@@ -117,62 +127,40 @@ done
117127echo " "
118128ok " Redis is up (${REDIS_HOST} :${REDIS_PORT} )"
119129
120- # ── Step 4: create required directories ──────────────────────────────────────
121- mkdir -p uploads manim_outputs logs
122- ok " Directories ready (uploads/, manim_outputs/, logs/)"
130+ # ── Step 3.5: Check RedisInsight UI (Optional & Non-blocking) ─────────────────
131+ log " Checking RedisInsight UI (optional)..."
123132
124- # ── Step 5: start Manim MCP server (background) ───────────────────────────────
125- MANIM_PID=" "
133+ INSIGHT_AVAILABLE= false
126134
127- if [ " ${SKIP_MANIM:- 0} " = " 1" ]; then
128- warn " SKIP_MANIM=1 — skipping Manim MCP server"
135+ # Check both common ports
136+ if curl -s -f http://localhost:5540 > /dev/null 2>&1 ; then
137+ INSIGHT_AVAILABLE=true
138+ ok " RedisInsight UI detected on port 5540 (recommended)"
139+ elif curl -s -f http://localhost:8001 > /dev/null 2>&1 ; then
140+ INSIGHT_AVAILABLE=true
141+ ok " RedisInsight UI detected on port 8001 (built-in)"
129142else
130- MANIM_SCRIPT=" src/backend/agents/nodes/tools/mcp/manim_mcp_server.py"
131-
132- if [ ! -f " $MANIM_SCRIPT " ]; then
133- warn " Manim MCP script not found at $MANIM_SCRIPT — skipping"
134- elif ! python -c " import manim" 2> /dev/null; then
135- warn " manim not installed in current Python env — skipping Manim MCP"
136- warn " Install with: pip install manim fastmcp"
137- elif ! python -c " import fastmcp" 2> /dev/null; then
138- warn " fastmcp not installed — skipping Manim MCP"
139- warn " Install with: pip install fastmcp"
140- else
141- MANIM_PORT=" ${MANIM_SERVER_PORT:- 8765} "
142- log " Starting Manim MCP server on port $MANIM_PORT ..."
143- MANIM_OUTPUT_DIR=" ${MANIM_OUTPUT_DIR:- ./ manim_outputs} " \
144- MANIM_SERVER_PORT=" $MANIM_PORT " \
145- MANIM_MCP_SERVER_URL=" ${MANIM_MCP_SERVER_URL:- http:// localhost: ${MANIM_PORT} / mcp} " \
146- python " $MANIM_SCRIPT " >> logs/manim_mcp.log 2>&1 &
147- MANIM_PID=$!
148-
149- # Give it 3 seconds to start
150- sleep 3
151- if kill -0 " $MANIM_PID " 2> /dev/null; then
152- ok " Manim MCP server started (PID $MANIM_PID , port $MANIM_PORT )"
153- ok " Logs: logs/manim_mcp.log"
154- else
155- warn " Manim MCP server exited immediately — check logs/manim_mcp.log"
156- MANIM_PID=" "
157- fi
158- fi
143+ warn " RedisInsight UI is not running (this is optional)"
144+ echo -e " ${YELLOW} Tip: Start it with → docker compose up -d redisinsight${NC} "
145+ fi
146+
147+ if [ " $INSIGHT_AVAILABLE " = true ]; then
148+ echo -e " ${GREEN} → Open RedisInsight at: http://localhost:5540${NC} "
159149fi
160150
161- # ── Step 6: trap for clean shutdown ───────────────────────────────────────────
151+ # ── Step 4: create required directories ──────────────────────────────────────
152+ mkdir -p uploads logs
153+ ok " Directories ready (uploads/, logs/)"
154+
155+ # ── Step 5: trap for clean shutdown ───────────────────────────────────────────
162156cleanup () {
163157 echo " "
164158 log " Shutting down..."
165- if [ -n " $MANIM_PID " ] && kill -0 " $MANIM_PID " 2> /dev/null; then
166- log " Stopping Manim MCP server (PID $MANIM_PID )..."
167- kill " $MANIM_PID "
168- wait " $MANIM_PID " 2> /dev/null || true
169- ok " Manim MCP server stopped"
170- fi
171159 ok " Goodbye."
172160}
173161trap cleanup EXIT INT TERM
174162
175- # ── Step 7 : start Streamlit ───────────────────────────────────────────────────
163+ # ── Step 6 : start Streamlit ───────────────────────────────────────────────────
176164STREAMLIT_PORT= " ${STREAMLIT_PORT:- 8501} "
177165APP_PATH= " ${APP_PATH:- src/ frontend/ app.py} "
178166
@@ -188,13 +176,14 @@ if [ ! -f "$SECRETS_FILE" ]; then
188176 warn " Continuing anyway — st.secrets will fall back to environment variables."
189177fi
190178
179+ export PYTHONPATH= " $( pwd) :$( pwd) /src:${PYTHONPATH:- } "
180+
191181log " Starting Streamlit on http://localhost:${STREAMLIT_PORT} ..."
182+
192183echo " "
193- echo -e " ${BOLD} App URL: ${GREEN} http://localhost:${STREAMLIT_PORT}${NC} "
194- if [ -n " $MANIM_PID " ]; then
195- echo -e " ${BOLD} Manim MCP: ${GREEN} http://localhost:${MANIM_SERVER_PORT:- 8765} /mcp${NC} "
196- fi
197- echo -e " ${BOLD} Redis UI: ${GREEN} http://localhost:8001${NC} (if RedisInsight is running)"
184+ echo -e " ${BOLD} App URL: ${GREEN} http://localhost:${STREAMLIT_PORT}${NC} "
185+ echo -e " ${BOLD} Redis server: ${GREEN}${REDIS_URL}${NC} "
186+ echo -e " ${BOLD} RedisInsight UI: ${GREEN} http://localhost:5540${NC} (if running)"
198187echo " "
199188
200189exec streamlit run " $APP_PATH " \
0 commit comments