llm_council/Makefile
Irina Levit 3546c04348
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
feat: Major UI/UX improvements and production readiness
## 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
2025-12-28 18:15:02 -05:00

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"