Setup & Deployment
Page Outline
Note: This document outlines the local setup, deployment patterns, and operational integration details for the RiverGen Intelligence Stack.
Prerequisites
Proper deployment of the RiverGen microservices and agent pipeline requires the following dependencies:
| Tool | Version | Purpose |
|---|---|---|
| Docker | 24+ | Container runtime |
| Docker Compose | 2.20+ | Multi-service orchestration |
| Python | 3.12+ | PSA service, TLO gateway, backend |
| Node.js | 20+ | Frontend |
| pnpm | 9+ | Frontend package manager |
| Git | 2.40+ | Version control |
Implementation Phases
The RiverGen Intelligence Stack is implemented in phases. Each phase adds new capabilities without re-architecture.
| Phase | What Ships | Domain Agents | AI Services |
|---|---|---|---|
| Phase 1 (Current) | PSA agentic orchestrator: NL-to-action via tool-calling loop for queries, CRUD, governance, discovery, write-back, administration. | PSA | RiverPlan (partial), RiverGuard (partial), RiverSemantic (partial), RiverViz (partial) |
| Phase 2 | Multi-source federation, enhanced write-back with preview / approval / rollback. | PSA + federation + write safety tools | RiverOptimize (initial), RiverCore (multi-provider) |
| Phase 3 | Model Studio, Decision Intelligence. | MSA, DIA | RiverDecide, RiverLearn (initial) |
| Phase 4 | Full governance automation, operational workflows. | GA, OSA | RiverObserve, RiverLearn (full) |
Environment Variables
PSA Service (Dynamic Orchestrator)
Provisional setup: The PSA service (
rgen-repo-ai) is being redesigned as a complete dynamic orchestrator with tool-calling. It can perform any action the user can do via the UI -- queries, CRUD, governance, write-back, etc. The setup steps below are provisional and will be updated as the redesign progresses.
# LLM Provider API Keys (configure all providers you want to use)
GEMINI_API_KEY=your_gemini_api_key_here
OPENAI_API_KEY=your_openai_api_key_here
ANTHROPIC_API_KEY=your_anthropic_api_key_here
DEEPSEEK_API_KEY=your_deepseek_api_key_here
# RiverCore: Multi-provider routing configuration
# PSA selects the best model per-turn from all configured providers
RIVERCORE_DEFAULT_PROVIDER=gemini
RIVERCORE_FALLBACK_CHAIN=openai,anthropic,deepseek
# Category preferences (which provider to prefer per category)
RIVERCORE_FAST_PROVIDER=openai # GPT-4o-mini for fast tasks
RIVERCORE_BALANCED_PROVIDER=gemini # Gemini Flash for balanced tasks
RIVERCORE_REASONING_PROVIDER=anthropic # Claude Opus for deep reasoning
RIVERCORE_CODING_PROVIDER=openai # GPT-4o for SQL generation
# Optional overrides
# PSA_HOST=0.0.0.0
# AI_MODEL= # Override: force specific model for all turns
# DEEPSEEK_BASE_URL=https://api.deepseek.com/v1
TLO Gateway
# PSA Agent (URL will change as PSA is redesigned)
PSA_TIMEOUT_SECONDS=30
PSA_RETRY_COUNT=3
# Temporal
TEMPORAL_HOST=temporal
TEMPORAL_PORT=7233
TEMPORAL_NAMESPACE=default
# Backend
BACKEND_URL=http://backend:8005
# Redis
REDIS_HOST=redis
REDIS_PORT=6381
# Catalog Matching (RiverSemantic)
TLO_MAX_MATCHED_TABLES=10
TLO_MAX_COLUMNS_PER_TABLE=20
# WebSocket
WEBSOCKET_PING_INTERVAL=30
WEBSOCKET_PING_TIMEOUT=10
# Future: Additional domain agent URLs (Phase 2+)
# MSA_SERVICE_URL=http://model-studio-agent:8010
# DIA_SERVICE_URL=http://decision-intel-agent:8011
# GA_SERVICE_URL=http://governance-agent:8012
# OSA_SERVICE_URL=http://ops-service-agent:8013
Backend
# Database
DATABASE_URL=postgresql+asyncpg://rgen:rgen@postgres:5433/rgen
POSTGRES_HOST=postgres
POSTGRES_PORT=5433
POSTGRES_DB=rgen
POSTGRES_USER=rgen
POSTGRES_PASSWORD=rgen
# Redis
REDIS_URL=redis://redis:6381
# MongoDB
MONGODB_URL=mongodb://mongo:27017
# JWT
JWT_SECRET_KEY=your-secret-key
JWT_ALGORITHM=HS256
# MinIO
MINIO_ENDPOINT=minio:9002
MINIO_ACCESS_KEY=minioadmin
MINIO_SECRET_KEY=minioadmin
Frontend
The frontend communicates through 3 gateway channels only (never directly to backend):
# TLO Gateway (Channel 1 - all API requests via HTTP)
NEXT_PUBLIC_API_BASE_URL=http://localhost:8001
# Storage Gateway (Channel 2 - file operations)
NEXT_PUBLIC_STORAGE_URL=http://localhost:8004
# TLO Gateway WebSocket (Channel 3 - real-time updates)
NEXT_PUBLIC_WEBSOCKET_URL=ws://localhost:8001/ws
Local Development Setup
1. Start Infrastructure Services
cd /opt/rgen
# Start all infrastructure (databases, Temporal, MinIO, etc.)
docker compose up -d postgres redis mongo qdrant temporal minio nginx
2. Start Backend
cd /opt/rgen/rgen-repo-backend/rgen-backend
# Create virtual environment
python -m venv venv
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Run database migrations
alembic upgrade head
# Start the backend
uvicorn app.main:app --host 0.0.0.0 --port 8005 --reload
3. Start TLO Gateway
cd /opt/rgen/rgen-repo-backend/rgen-backend
# Using the same virtual environment as the backend
uvicorn services.tlo_gateway.main:app --host 0.0.0.0 --port 8001 --reload
4. Start PSA Service (Agentic LLM Orchestrator)
The PSA service is being redesigned. The rgen-repo-ai codebase will be rebuilt to support the agentic tool-calling loop with reasoning + execution tools. Setup steps below are provisional.
cd /opt/rgen/rgen-repo-ai
# Create virtual environment
python -m venv venv
source venv/bin/activate
# Install dependencies (requirements TBD as part of redesign)
pip install -r requirements.txt
# Copy and configure environment
cp .env.example .env
# Edit .env and add your LLM provider API keys (GEMINI_API_KEY, OPENAI_API_KEY, etc.)
# Run the service (entry point TBD)
# uvicorn app:app --host 0.0.0.0 --port 8000 --reload
5. Start Frontend
cd /opt/rgen/rgen-repo-for-frontend/rgen-frontend
# Install dependencies
pnpm install
# Start development server
pnpm dev
The frontend will be available at http://localhost:3000.
Docker Compose Deployment
For full stack environment spinning, utilize docker compose orchestration:
cd /opt/rgen
# Build and start everything
docker compose up -d --build
# Check service status
docker compose ps
Service-Specific Docker Files
| Service | Dockerfile Location | Container Name | Phase |
|---|---|---|---|
| PSA Service | docker/prompt-studio-agent/Dockerfile | prompt-studio-agent | 1 (Current) |
| Backend | docker/backend/Dockerfile | backend | 1 (Current) |
| TLO Gateway | docker/tlo-gateway/Dockerfile | tlo-gateway | 1 (Current) |
| Frontend | docker/frontend/Dockerfile | frontend | 1 (Current) |
| MSA Service | docker/model-studio-agent/Dockerfile | model-studio-agent | Phase 3 |
| DIA Service | docker/decision-intel-agent/Dockerfile | decision-intel-agent | Phase 3 |
| GA Service | docker/governance-agent/Dockerfile | governance-agent | Phase 4 |
| OSA Service | docker/ops-service-agent/Dockerfile | ops-service-agent | Phase 4 |
Verification
Health Checks
# Backend
curl http://localhost:8005/health
# TLO Gateway
curl http://localhost:8001/health
curl http://localhost:8001/ready
# Frontend
curl http://localhost:3000
Test the AI Pipeline
Test 1: Query action (DATA_QUERY)
The PSA agentic loop will classify intent, generate a query, and execute it.
curl -X POST http://localhost:8001/api/v1/classify \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"request_id": "test-001",
"user_prompt": "Show all customers",
"spl_detected": false,
"user_context": {
"user_id": 1,
"workspace_id": 1,
"organization_id": 1,
"roles": ["admin"],
"permissions": ["read"],
"attributes": {}
},
"data_sources": [{
"data_source_id": 1,
"name": "Test DB",
"type": "postgresql",
"schemas": [{
"schema_name": "public",
"tables": [{
"table_name": "customers",
"row_count": 1000,
"columns": [
{"column_name": "id", "column_type": "integer", "is_primary_key": true},
{"column_name": "name", "column_type": "varchar"},
{"column_name": "email", "column_type": "varchar"},
{"column_name": "region", "column_type": "varchar"}
]
}]
}],
"governance_policies": {
"row_level_security": [],
"column_masking": []
}
}],
"execution_context": {
"max_rows": 100,
"timeout_seconds": 30
}
}'
Test Backend Prompt Execution
First, generate a JSON Web Token:
# Get a JWT token first (login)
TOKEN=$(curl -s -X POST http://localhost:8005/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "admin@example.com", "password": "password"}' | jq -r '.access_token')
Test 2: Query via prompt execution
curl -X POST http://localhost:8001/api/v1/prompts/execute \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"prompt_text": "Show all customers",
"selected_data_source_ids": [1],
"save_prompt": false
}'
Test 3: CRUD action via prompt (data source management)
curl -X POST http://localhost:8001/api/v1/prompts/execute \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"prompt_text": "Test connection to billing_db",
"selected_data_source_ids": [1],
"save_prompt": false
}'
Test 4: Governance action via prompt
curl -X POST http://localhost:8001/api/v1/prompts/execute \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"prompt_text": "Show which masking rules apply to the customers table",
"selected_data_source_ids": [1],
"save_prompt": false
}'
Test WebSocket Connection (Interactive Flows)
WebSocket enables: progress updates, clarification, confirmation, credential input. Using websocat or similar WebSocket client:
websocat ws://localhost:8001/ws/executions/test-exec-id \
-H "Authorization: Bearer $TOKEN"
Expected flow for CRUD actions:
- Server sends:
{ "type": "connected" } - Server sends:
{ "type": "progress_update", "step": "classifying_intent", "progress": 20 } - Server sends:
{ "type": "progress_update", "step": "checking_permissions", "progress": 40 } - If confirmation needed:
{ "type": "confirmation_request", "message": "...", "is_destructive": true } - Client sends:
{ "type": "user_response", "confirmed": true } - Server sends:
{ "type": "execution_complete", "result": { "intent_type": "DATA_SOURCE_MANAGEMENT", ... } }
Port Reference
| Port | Service | Phase | Frontend Channel | Access |
|---|---|---|---|---|
| 80 | Nginx (reverse proxy) | 1 | - | http://localhost |
| 3000 | Frontend | 1 | - | http://localhost:3000 |
| 8001 | TLO Gateway | 1 | Channel 1 (HTTP), Channel 3 (WS) | http://localhost:8001 |
| 8004 | Storage Gateway | 1 | Channel 2 (HTTP) | http://localhost:8004 |
| 8005 | Backend | 1 | Via TLO only | http://localhost:8005 |
| 5433 | PostgreSQL | 1 | postgresql://localhost:5433 | |
| 6333 | Qdrant | 1 | http://localhost:6333 | |
| 6381 | Redis | 1 | redis://localhost:6381 | |
| 7233 | Temporal | 1 | temporal://localhost:7233 | |
| 8088 | Temporal UI | 1 | http://localhost:8088 | |
| 9002 | MinIO API | 1 | http://localhost:9002 | |
| 9003 | MinIO Console | 1 | http://localhost:9003 | |
| 8010 | MSA Service | 3 | http://localhost:8010 | |
| 8011 | DIA Service | 3 | http://localhost:8011 | |
| 8012 | GA Service | 4 | http://localhost:8012 | |
| 8013 | OSA Service | 4 | http://localhost:8013 |
Troubleshooting
TLO Gateway Not Starting
# Check Temporal is running
curl http://localhost:7233/health
# Check Redis is running
redis-cli -p 6381 ping
# Check port availability
lsof -i :8001
AI Responses Are Slow
- Ensure Fast category is using a lightweight model (e.g., GPT-4o-mini, Gemini Flash Lite).
- Check if the current provider's API rate limits are being hit (429 errors in logs). RiverCore should auto-fallback to another provider if one is rate-limited.
- Reduce schema size by specifying
selected_schema_names. - Lower
tlo_max_matched_tablesin TLO config. - Future: RiverCore will add caching and provider failover.
Temporal Workflows Fail
# Check Temporal is running
curl http://localhost:7233/health
# Check Temporal UI for workflow status
# Open http://localhost:8088
# Check TLO Gateway readiness
curl http://localhost:8001/ready
Database Connection Issues
# Check PostgreSQL
docker compose exec postgres pg_isready -h localhost -p 5432
# Check migrations
cd /opt/rgen/rgen-repo-backend/rgen-backend
alembic current
alembic upgrade head
Frontend Connection Failures
The frontend connects to the TLO Gateway via HTTP (:8001) and WebSocket (:8001), plus Storage Gateway (:8004):
# Check TLO Gateway (Channel 1 - HTTP)
curl http://localhost:8001/health
curl http://localhost:8001/ready
# Check WebSocket endpoint (Channel 3)
# Use browser DevTools Network tab -> WS filter to verify connection
# Check Storage Gateway (Channel 2)
curl http://localhost:8004/health
# Verify frontend environment variables
# NEXT_PUBLIC_API_BASE_URL should point to http://localhost:8001
# NEXT_PUBLIC_WEBSOCKET_URL should point to ws://localhost:8001/ws
# Check CORS settings on TLO Gateway
WebSocket Connection Issues
# Verify WebSocket endpoint is responding
curl -i -N \
-H "Connection: Upgrade" \
-H "Upgrade: websocket" \
-H "Sec-WebSocket-Version: 13" \
-H "Sec-WebSocket-Key: test" \
http://localhost:8001/ws/executions/test
# Check for proxy issues (Nginx must pass WebSocket headers)
# Nginx config should include:
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection "upgrade";
# Check TLO Gateway logs for WebSocket errors
docker compose logs tlo-gateway --tail=50
Monitoring Configuration
| Tool | URL | Purpose |
|---|---|---|
| Temporal UI | http://localhost:8088 | Workflow monitoring, execution history |
| PgAdmin | http://localhost:5051 | PostgreSQL database management |
| Portainer | http://localhost:9090 | Docker container management |
| MinIO Console | http://localhost:9003 | Object storage management |
| Qdrant Dashboard | http://localhost:6333/dashboard | Vector database monitoring |
Future additions (via RiverObserve): Token usage and cost dashboards, SLA tracking for AI response times, Connector health monitoring, and cross-system lineage tracing.