Some checks failed
CI / backend-test (push) Successful in 4m9s
CI / frontend-test (push) Failing after 3m48s
CI / lint-python (push) Successful in 1m41s
CI / secret-scanning (push) Successful in 1m20s
CI / dependency-scan (push) Successful in 10m50s
CI / workflow-summary (push) Successful in 1m11s
## Features Added
### Document Reference System
- Implemented numbered document references (@1, @2, etc.) with autocomplete dropdown
- Added fuzzy filename matching for @filename references
- Document filtering now prioritizes numeric refs > filename refs > all documents
- Autocomplete dropdown appears when typing @ with keyboard navigation (Up/Down, Enter/Tab, Escape)
- Document numbers displayed in UI for easy reference
### Conversation Management
- Added conversation rename functionality with inline editing
- Implemented conversation search (by title and content)
- Search box always visible, even when no conversations exist
- Export reports now replace @N references with actual filenames
### UI/UX Improvements
- Removed debug toggle button
- Improved text contrast in dark mode (better visibility)
- Made input textarea expand to full available width
- Fixed file text color for better readability
- Enhanced document display with numbered badges
### Configuration & Timeouts
- Made HTTP client timeouts configurable (connect, write, pool)
- Added .env.example with all configuration options
- Updated timeout documentation
### Developer Experience
- Added `make test-setup` target for automated test conversation creation
- Test setup script supports TEST_MESSAGE and TEST_DOCS env vars
- Improved Makefile with dev and test-setup targets
### Documentation
- Updated ARCHITECTURE.md with all new features
- Created comprehensive deployment documentation
- Added GPU VM setup guides
- Removed unnecessary markdown files (CLAUDE.md, CONTRIBUTING.md, header.jpg)
- Organized documentation in docs/ directory
### GPU VM / Ollama (Stability + GPU Offload)
- Updated GPU VM docs to reflect the working systemd environment for remote Ollama
- Standardized remote Ollama port to 11434 (and added /v1/models verification)
- Documented required env for GPU offload on this VM:
- `OLLAMA_MODELS=/mnt/data/ollama`, `HOME=/mnt/data/ollama/home`
- `OLLAMA_LLM_LIBRARY=cuda_v12` (not `cuda`)
- `LD_LIBRARY_PATH=/usr/local/lib/ollama:/usr/local/lib/ollama/cuda_v12`
## Technical Changes
### Backend
- Enhanced `docs_context.py` with reference parsing (numeric and filename)
- Added `update_conversation_title` to storage.py
- New endpoints: PATCH /api/conversations/{id}/title, GET /api/conversations/search
- Improved report generation with filename substitution
### Frontend
- Removed debugMode state and related code
- Added autocomplete dropdown component
- Implemented search functionality in Sidebar
- Enhanced ChatInterface with autocomplete and improved textarea sizing
- Updated CSS for better contrast and responsive design
## Files Changed
- Backend: config.py, council.py, docs_context.py, main.py, storage.py
- Frontend: App.jsx, ChatInterface.jsx, Sidebar.jsx, and related CSS files
- Documentation: README.md, ARCHITECTURE.md, new docs/ directory
- Configuration: .env.example, Makefile
- Scripts: scripts/test_setup.py
## Breaking Changes
None - all changes are backward compatible
## Testing
- All existing tests pass
- New test-setup script validates conversation creation workflow
- Manual testing of autocomplete, search, and rename features
299 lines
12 KiB
Makefile
299 lines
12 KiB
Makefile
.PHONY: dev backend frontend test test-backend test-frontend test-setup \
|
|
stop-backend stop-frontend stop-ollama reset \
|
|
start-ollama start-backend start-frontend up restart \
|
|
status logs help
|
|
|
|
help:
|
|
@# Use color only when output is a TTY. Keep plain output for logs/CI.
|
|
@is_tty=0; if [ -t 1 ]; then is_tty=1; fi; \
|
|
if [ $$is_tty -eq 1 ]; then \
|
|
BOLD=$$(printf '\033[1m'); DIM=$$(printf '\033[2m'); RESET=$$(printf '\033[0m'); \
|
|
CYAN=$$(printf '\033[36m'); GREEN=$$(printf '\033[32m'); YELLOW=$$(printf '\033[33m'); \
|
|
else \
|
|
BOLD=""; DIM=""; RESET=""; CYAN=""; GREEN=""; YELLOW=""; \
|
|
fi; \
|
|
printf "%sLLM Council%s %sMake targets%s\n" "$$BOLD" "$$RESET" "$$DIM" "$$RESET"; \
|
|
printf "\n"; \
|
|
printf "%sCore%s\n" "$$CYAN" "$$RESET"; \
|
|
printf " %smake dev%s Start backend + frontend (foreground, Ctrl+C to stop)\n" "$$GREEN" "$$RESET"; \
|
|
printf " %smake up%s Start ollama + backend + frontend (background via nohup)\n" "$$GREEN" "$$RESET"; \
|
|
printf " %smake restart%s Reset (stop) then start everything (up)\n" "$$GREEN" "$$RESET"; \
|
|
printf "\n"; \
|
|
printf "%sStart/Stop%s\n" "$$CYAN" "$$RESET"; \
|
|
printf " %smake start-ollama%s Start Ollama (systemd if available, else 'ollama serve' nohup)\n" "$$GREEN" "$$RESET"; \
|
|
printf " %smake start-backend%s Start backend (nohup, logs: %s/tmp/llm-council-backend.log%s)\n" "$$GREEN" "$$RESET" "$$DIM" "$$RESET"; \
|
|
printf " %smake start-frontend%s Start frontend (nohup, logs: %s/tmp/llm-council-frontend.log%s)\n" "$$GREEN" "$$RESET" "$$DIM" "$$RESET"; \
|
|
printf " %smake stop-backend%s Stop backend on port %s8001%s\n" "$$GREEN" "$$RESET" "$$YELLOW" "$$RESET"; \
|
|
printf " %smake stop-frontend%s Stop frontend on port %s5173%s\n" "$$GREEN" "$$RESET" "$$YELLOW" "$$RESET"; \
|
|
printf " %smake stop-ollama%s Attempt to stop Ollama (systemd if available)\n" "$$GREEN" "$$RESET"; \
|
|
printf " %smake reset%s Stop frontend + backend + attempt Ollama stop\n" "$$GREEN" "$$RESET"; \
|
|
printf "\n"; \
|
|
printf "%sTesting / setup%s\n" "$$CYAN" "$$RESET"; \
|
|
printf " %smake test%s Run backend + frontend tests\n" "$$GREEN" "$$RESET"; \
|
|
printf " %smake test-backend%s Run backend unit tests\n" "$$GREEN" "$$RESET"; \
|
|
printf " %smake test-frontend%s Run frontend tests\n" "$$GREEN" "$$RESET"; \
|
|
printf " %smake test-setup%s Create a new conversation, upload TEST_DOCS, prefill TEST_MESSAGE in UI\n" "$$GREEN" "$$RESET"; \
|
|
printf " %sEnv:%s TEST_DOCS=path1.md,path2.md TEST_MESSAGE='your msg'\n" "$$DIM" "$$RESET"; \
|
|
printf "\n"; \
|
|
printf "%sDiagnostics%s\n" "$$CYAN" "$$RESET"; \
|
|
printf " %smake status%s Show whether backend/frontend/ollama are up + PIDs + basic info\n" "$$GREEN" "$$RESET"; \
|
|
printf " %smake logs%s Tail recent backend/frontend logs (from /tmp)\n" "$$GREEN" "$$RESET"; \
|
|
printf "\n"; \
|
|
printf "%sHelp%s\n" "$$CYAN" "$$RESET"; \
|
|
printf " %smake help%s Show this message\n" "$$GREEN" "$$RESET"
|
|
|
|
backend:
|
|
uv run python -m backend.main
|
|
|
|
frontend:
|
|
cd frontend && npm run dev
|
|
|
|
dev:
|
|
./start.sh
|
|
|
|
test-backend:
|
|
uv run python -m unittest discover -s backend/tests -p "test_*.py" -q
|
|
|
|
test-frontend:
|
|
cd frontend && npm test
|
|
|
|
test: test-backend test-frontend
|
|
|
|
stop-backend:
|
|
@echo "Stopping backend processes on port 8001..."
|
|
@if lsof -ti:8001 > /dev/null 2>&1; then \
|
|
lsof -ti:8001 | xargs kill -9 2>/dev/null || true; \
|
|
echo "✓ Backend stopped"; \
|
|
sleep 1; \
|
|
else \
|
|
echo "✓ No backend process found on port 8001"; \
|
|
fi
|
|
|
|
stop-frontend:
|
|
@echo "Stopping frontend processes on port 5173..."
|
|
@if lsof -ti:5173 > /dev/null 2>&1; then \
|
|
lsof -ti:5173 | xargs kill -9 2>/dev/null || true; \
|
|
echo "✓ Frontend stopped"; \
|
|
sleep 1; \
|
|
else \
|
|
echo "✓ No frontend process found on port 5173"; \
|
|
fi
|
|
|
|
stop-ollama:
|
|
@echo "Stopping Ollama..."
|
|
@# Prefer systemd if available; do not force-kill processes (safer).
|
|
@if command -v systemctl >/dev/null 2>&1; then \
|
|
if systemctl is-active --quiet ollama 2>/dev/null; then \
|
|
echo "Stopping systemd service: ollama"; \
|
|
systemctl stop ollama 2>/dev/null || true; \
|
|
sleep 2; \
|
|
else \
|
|
echo "Ollama systemd service is not active"; \
|
|
fi; \
|
|
else \
|
|
echo "systemctl not found (not a systemd environment)"; \
|
|
fi
|
|
@PIDS=$$(pgrep -x ollama 2>/dev/null || true); \
|
|
if [ -n "$$PIDS" ]; then \
|
|
echo "⚠️ Ollama processes still running (PIDs: $$PIDS)"; \
|
|
echo " Stop manually with one of:"; \
|
|
echo " - systemctl stop ollama (if installed as a service)"; \
|
|
echo " - pkill -x ollama"; \
|
|
echo " - sudo pkill -x ollama"; \
|
|
else \
|
|
echo "✓ Ollama is stopped"; \
|
|
fi
|
|
|
|
reset: stop-frontend stop-backend stop-ollama
|
|
@echo ""
|
|
@echo "✓ Reset complete - Frontend/Backend stopped (Ollama stop attempted)"
|
|
@echo ""
|
|
@echo "To start fresh (recommended):"
|
|
@echo " make up"
|
|
@echo ""
|
|
@echo "Or manually:"
|
|
@echo " 1) make start-ollama"
|
|
@echo " 2) make start-backend"
|
|
@echo " 3) make start-frontend"
|
|
|
|
start-ollama:
|
|
@echo "Starting Ollama..."
|
|
@if curl -s --max-time 2 http://localhost:11434/api/tags >/dev/null 2>&1; then \
|
|
echo "✓ Ollama already responding on http://localhost:11434"; \
|
|
exit 0; \
|
|
fi
|
|
@if command -v systemctl >/dev/null 2>&1 && systemctl list-unit-files 2>/dev/null | grep -q "^ollama\\.service"; then \
|
|
echo "Starting systemd service: ollama"; \
|
|
systemctl start ollama 2>/dev/null || true; \
|
|
sleep 2; \
|
|
else \
|
|
echo "systemd service not available; starting 'ollama serve' in background"; \
|
|
nohup ollama serve > /tmp/llm-council-ollama.log 2>&1 & \
|
|
echo "ollama serve PID: $$!"; \
|
|
sleep 2; \
|
|
fi
|
|
@if curl -s --max-time 2 http://localhost:11434/api/tags >/dev/null 2>&1; then \
|
|
echo "✓ Ollama is up: http://localhost:11434"; \
|
|
else \
|
|
echo "⚠️ Ollama did not respond yet. Check: /tmp/llm-council-ollama.log"; \
|
|
fi
|
|
|
|
start-backend:
|
|
@echo "Starting backend..."
|
|
@if curl -s --max-time 2 http://localhost:8001/ >/dev/null 2>&1; then \
|
|
echo "✓ Backend already responding on http://localhost:8001"; \
|
|
exit 0; \
|
|
fi
|
|
@nohup uv run python -m backend.main > /tmp/llm-council-backend.log 2>&1 & \
|
|
echo "backend PID: $$!"; \
|
|
sleep 2; \
|
|
if curl -s --max-time 2 http://localhost:8001/ >/dev/null 2>&1; then \
|
|
echo "✓ Backend is up: http://localhost:8001"; \
|
|
else \
|
|
echo "⚠️ Backend did not respond yet. Check: /tmp/llm-council-backend.log"; \
|
|
fi
|
|
|
|
start-frontend:
|
|
@echo "Starting frontend..."
|
|
@if curl -s --max-time 2 http://localhost:5173/ >/dev/null 2>&1; then \
|
|
echo "✓ Frontend already responding on http://localhost:5173"; \
|
|
exit 0; \
|
|
fi
|
|
@nohup sh -c "cd frontend && npm run dev" > /tmp/llm-council-frontend.log 2>&1 & \
|
|
echo "frontend PID: $$!"; \
|
|
sleep 2; \
|
|
if curl -s --max-time 2 http://localhost:5173/ >/dev/null 2>&1; then \
|
|
echo "✓ Frontend is up: http://localhost:5173"; \
|
|
else \
|
|
echo "⚠️ Frontend did not respond yet. Check: /tmp/llm-council-frontend.log"; \
|
|
fi
|
|
|
|
up: start-ollama start-backend start-frontend
|
|
@echo ""
|
|
@echo "✓ All services started (or already running)"
|
|
@echo "Frontend: http://localhost:5173"
|
|
@echo "Backend: http://localhost:8001"
|
|
@echo "Ollama: http://localhost:11434"
|
|
|
|
restart: reset up
|
|
|
|
status:
|
|
@echo "=== LLM Council status ==="
|
|
@date
|
|
@echo ""
|
|
@echo "-- Backend (8001) --"
|
|
@if curl -s --max-time 2 http://localhost:8001/ >/dev/null 2>&1; then \
|
|
echo "✓ UP: http://localhost:8001"; \
|
|
else \
|
|
echo "✗ DOWN: http://localhost:8001"; \
|
|
fi
|
|
@echo "PIDs:"; lsof -ti:8001 2>/dev/null | tr '\n' ' ' || true; echo ""
|
|
@echo ""
|
|
@echo "-- Frontend (5173) --"
|
|
@if curl -s --max-time 2 http://localhost:5173/ >/dev/null 2>&1; then \
|
|
echo "✓ UP: http://localhost:5173"; \
|
|
else \
|
|
echo "✗ DOWN: http://localhost:5173"; \
|
|
fi
|
|
@echo "PIDs:"; lsof -ti:5173 2>/dev/null | tr '\n' ' ' || true; echo ""
|
|
@echo ""
|
|
@echo "-- Ollama (11434) --"
|
|
@if curl -s --max-time 2 http://localhost:11434/api/tags >/dev/null 2>&1; then \
|
|
echo "✓ UP: http://localhost:11434"; \
|
|
else \
|
|
echo "✗ DOWN/UNREACHABLE: http://localhost:11434"; \
|
|
fi
|
|
@O_PID=$$(pgrep -x ollama 2>/dev/null || true); \
|
|
R_CNT=$$(pgrep -f "ollama runner" 2>/dev/null | wc -l | tr -d ' '); \
|
|
if [ -n "$$O_PID" ]; then \
|
|
echo "ollama PIDs: $$O_PID"; \
|
|
echo "runner count: $$R_CNT"; \
|
|
echo ""; \
|
|
echo "top ollama processes:"; \
|
|
ps -o pid,ppid,pcpu,pmem,etime,command -p $$O_PID 2>/dev/null || true; \
|
|
pgrep -f "ollama runner" 2>/dev/null | head -5 | while read pid; do \
|
|
ps -o pid,ppid,pcpu,pmem,etime,command -p $$pid 2>/dev/null || true; \
|
|
done; \
|
|
else \
|
|
echo "ollama not running"; \
|
|
fi
|
|
@echo ""
|
|
@echo "-- Quick health hints --"
|
|
@echo "Backend log: /tmp/llm-council-backend.log"
|
|
@echo "Frontend log: /tmp/llm-council-frontend.log"
|
|
@echo "Run: make logs"
|
|
|
|
logs:
|
|
@echo "=== Recent logs ==="
|
|
@echo ""
|
|
@echo "-- Backend log (/tmp/llm-council-backend.log) --"
|
|
@tail -n 80 /tmp/llm-council-backend.log 2>/dev/null || echo "(no backend log found)"
|
|
@echo ""
|
|
@echo "-- Frontend log (/tmp/llm-council-frontend.log) --"
|
|
@tail -n 120 /tmp/llm-council-frontend.log 2>/dev/null || echo "(no frontend log found)"
|
|
|
|
test-setup:
|
|
@echo "Setting up test conversation..."
|
|
@echo "Usage: TEST_MESSAGE='your message' TEST_DOCS='path1.md,path2.md' make test-setup"
|
|
@echo ""
|
|
@echo "⚠️ Safeguard check: Verifying backend is running..."
|
|
@if ! curl -s http://localhost:8001/ > /dev/null 2>&1; then \
|
|
echo "✗ Backend is NOT running on port 8001"; \
|
|
echo " Starting backend in background..."; \
|
|
uv run python -m backend.main > /tmp/llm-council-backend.log 2>&1 & \
|
|
BACKEND_PID=$$!; \
|
|
echo " Backend PID: $$BACKEND_PID"; \
|
|
sleep 2; \
|
|
if ! curl -s http://localhost:8001/ > /dev/null 2>&1; then \
|
|
echo "✗ Backend failed to start"; \
|
|
exit 1; \
|
|
fi; \
|
|
echo "✓ Backend started"; \
|
|
else \
|
|
echo "✓ Backend is already running"; \
|
|
fi
|
|
@echo ""
|
|
@echo "Running test setup script..."
|
|
@uv run python scripts/test_setup.py > /tmp/llm-council-test-setup.log 2>&1; \
|
|
cat /tmp/llm-council-test-setup.log; \
|
|
CONV_ID=$$(grep "CONVERSATION_ID=" /tmp/llm-council-test-setup.log | cut -d'=' -f2 | head -1); \
|
|
OPEN_URL=$$(grep "OPEN_URL=" /tmp/llm-council-test-setup.log | cut -d'=' -f2- | head -1); \
|
|
echo ""; \
|
|
echo "Checking frontend status..."; \
|
|
if pgrep -f "vite" > /dev/null 2>&1 || pgrep -f "npm.*dev" > /dev/null 2>&1; then \
|
|
echo "✓ Frontend process detected (already running)"; \
|
|
elif timeout 2 curl -s http://localhost:5173/ > /dev/null 2>&1; then \
|
|
echo "✓ Frontend is responding"; \
|
|
else \
|
|
echo "Starting frontend in background..."; \
|
|
cd frontend && npm run dev > /tmp/llm-council-frontend.log 2>&1 & \
|
|
echo "Frontend starting (PID: $$!)"; \
|
|
echo "Waiting up to 10 seconds for frontend..."; \
|
|
for i in 1 2 3 4 5 6 7 8 9 10; do \
|
|
if timeout 1 curl -s http://localhost:5173/ > /dev/null 2>&1; then \
|
|
echo "✓ Frontend is ready!"; \
|
|
break; \
|
|
fi; \
|
|
sleep 1; \
|
|
done; \
|
|
fi; \
|
|
echo ""; \
|
|
echo "✓ Test setup complete!"; \
|
|
echo ""; \
|
|
if [ -n "$$OPEN_URL" ]; then \
|
|
echo "Opening browser: $$OPEN_URL"; \
|
|
xdg-open "$$OPEN_URL" 2>/dev/null || \
|
|
open "$$OPEN_URL" 2>/dev/null || \
|
|
echo "Open manually: $$OPEN_URL"; \
|
|
elif [ -n "$$CONV_ID" ]; then \
|
|
echo "Opening browser with new conversation: $$CONV_ID"; \
|
|
xdg-open "http://localhost:5173/?conversation=$$CONV_ID" 2>/dev/null || \
|
|
open "http://localhost:5173/?conversation=$$CONV_ID" 2>/dev/null || \
|
|
echo "Open manually: http://localhost:5173/?conversation=$$CONV_ID"; \
|
|
else \
|
|
echo "Open: http://localhost:5173"; \
|
|
echo "The new conversation should appear in the sidebar"; \
|
|
fi; \
|
|
echo ""; \
|
|
echo "Note: TEST_MESSAGE is NOT sent automatically - check the script output above for the message to paste"
|