Files
lovdata-chat/README.md
2026-02-08 20:27:35 +01:00

162 lines
5.0 KiB
Markdown

# Lovdata Chat Interface
A container-per-session architecture for Norwegian legal research. Each user session gets an isolated [OpenCode](https://opencode.ai/) container connected to the external [Lovdata MCP server](https://modelcontextprotocol.io/), which provides 15+ tools for searching Norwegian laws, provisions, and cross-references.
## Architecture
```
Users → Caddy (reverse proxy) → Session Manager (FastAPI)
Docker-in-Docker daemon
↓ ↓ ↓
[OC 1] [OC 2] [OC 3] ← OpenCode containers
↓ ↓ ↓
Lovdata MCP Server (external)
LLM APIs (OpenAI/Anthropic/Google)
```
| Component | Purpose |
|-----------|---------|
| **Session Manager** | FastAPI service managing OpenCode container lifecycles |
| **OpenCode Containers** | Isolated chat environments with MCP integration |
| **Lovdata MCP Server** | External Norwegian legal research (laws, provisions, cross-references) |
| **Caddy** | Reverse proxy with dynamic session-based routing |
| **PostgreSQL** | Session persistence across restarts |
| **Docker-in-Docker** | TLS-secured Docker daemon for container management |
### Session Manager Components
```
main.py → FastAPI endpoints, session lifecycle orchestration
docker_service.py → Docker abstraction layer (testable, mockable)
async_docker_client.py → Async Docker operations
database.py → PostgreSQL session persistence with asyncpg
session_auth.py → Token-based session authentication
container_health.py → Health monitoring and auto-recovery
resource_manager.py → CPU/memory limits, throttling
http_pool.py → Connection pooling for container HTTP requests
host_ip_detector.py → Docker host IP detection
logging_config.py → Structured JSON logging with context
```
## Quick Start
1. **Set up environment variables:**
```bash
cp .env.example .env
# Edit .env with your API keys and MCP server URL
```
2. **Start the services:**
```bash
docker-compose up --build
```
3. **Create a session:**
```bash
curl http://localhost/api/sessions -X POST
```
4. **Access the chat interface** at the URL returned in step 3.
## Development
### Running the Stack
```bash
# Start all services (session-manager, docker-daemon, caddy)
docker-compose up --build
# Start in background
docker-compose up -d --build
# View logs
docker-compose logs -f session-manager
# Stop services
docker-compose down
```
### Session Management API
```bash
POST /api/sessions # Create new session
GET /api/sessions # List all sessions
GET /api/sessions/{id} # Get session info
DELETE /api/sessions/{id} # Delete session
POST /api/cleanup # Manual cleanup
GET /api/health # Health check
```
### Running Locally (without Docker)
```bash
cd session-manager
pip install -r requirements.txt
uvicorn main:app --reload --host 0.0.0.0 --port 8000
```
### Testing
Test scripts live in `docker/scripts/` and are self-contained:
```bash
python docker/scripts/test-docker-service.py
python docker/scripts/test-async-docker.py
python docker/scripts/test-resource-limits.py
python docker/scripts/test-session-auth.py
python docker/scripts/test-database-persistence.py
python docker/scripts/test-container-health.py
python docker/scripts/test-http-connection-pool.py
python docker/scripts/test-host-ip-detection.py
python docker/scripts/test-structured-logging.py
```
### Building the OpenCode Image
```bash
make build MCP_SERVER=http://your-lovdata-server:8001
make run # Run interactively
make clean # Clean up
```
## Environment Configuration
Required variables (see `.env.example`):
```bash
MCP_SERVER=http://localhost:8001 # External Lovdata MCP server URL
# Docker TLS (if using TLS instead of socket)
DOCKER_TLS_VERIFY=1
DOCKER_CERT_PATH=/etc/docker/certs
DOCKER_HOST=tcp://host.docker.internal:2376
# Optional LLM keys (at least one required for chat)
OPENAI_API_KEY=...
ANTHROPIC_API_KEY=...
GOOGLE_API_KEY=...
```
## Security
**Docker socket**: Default setup uses socket mounting (`/var/run/docker.sock`). For production, enable TLS:
```bash
cd docker && DOCKER_ENV=production ./scripts/generate-certs.sh
./scripts/setup-docker-tls.sh
```
**Session isolation:**
- Each session gets a dedicated container
- Resource limits: 4GB RAM, 1 CPU core per container
- Max 3 concurrent sessions (configurable via `resource_manager.py`)
- Auto-cleanup after 60 minutes inactivity
- Token-based session authentication
## Further Documentation
- [`CLAUDE.md`](CLAUDE.md) — AI assistant guidance for working with this codebase
- [`LOW_PRIORITY_IMPROVEMENTS.md`](LOW_PRIORITY_IMPROVEMENTS.md) — Backlog of non-critical improvements
- [`docs/project-analysis.md`](docs/project-analysis.md) — Detailed architectural analysis
- `docker/*.md` — Implementation docs for individual components