mirror of
https://github.com/All-Hands-AI/OpenHands.git
synced 2026-04-29 03:00:45 -04:00
Compare commits
2 Commits
fix/git-ap
...
enterprise
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a001491c3 | ||
|
|
11c11e633a |
118
enterprise/.env.example
Normal file
118
enterprise/.env.example
Normal file
@@ -0,0 +1,118 @@
|
||||
# ============================================
|
||||
# OpenHands Enterprise Local Development
|
||||
# Environment Variables Example
|
||||
# ============================================
|
||||
# Copy this to .env and fill in your values
|
||||
|
||||
# ============================================
|
||||
# Database Configuration
|
||||
# ============================================
|
||||
DB_HOST=localhost
|
||||
DB_PORT=5432
|
||||
DB_USER=postgres
|
||||
DB_PASS=postgres
|
||||
DB_NAME=openhands
|
||||
|
||||
# ============================================
|
||||
# Redis Configuration
|
||||
# ============================================
|
||||
REDIS_HOST=localhost
|
||||
REDIS_PORT=6379
|
||||
REDIS_PASSWORD=
|
||||
REDIS_DB=0
|
||||
|
||||
# ============================================
|
||||
# Keycloak Configuration
|
||||
# ============================================
|
||||
# For local development with the docker-compose setup
|
||||
KEYCLOAK_SERVER_URL=http://localhost:8080
|
||||
KEYCLOAK_SERVER_URL_EXT=http://localhost:8080
|
||||
KEYCLOAK_REALM_NAME=openhands
|
||||
KEYCLOAK_CLIENT_ID=openhands-client
|
||||
KEYCLOAK_CLIENT_SECRET=your-client-secret
|
||||
KEYCLOAK_PROVIDER_NAME=github
|
||||
KEYCLOAK_ADMIN_PASSWORD=admin
|
||||
|
||||
# ============================================
|
||||
# LiteLLM Configuration
|
||||
# ============================================
|
||||
LITE_LLM_API_URL=http://localhost:4000
|
||||
LITE_LLM_API_KEY=sk-local-dev-master-key
|
||||
LITELLM_DEFAULT_MODEL=litellm_proxy/claude-sonnet-4-20250514
|
||||
|
||||
# ============================================
|
||||
# OpenHands Configuration
|
||||
# ============================================
|
||||
OPENHANDS_CONFIG_CLS=server.config.SaaSServerConfig
|
||||
OPENHANDS_GITHUB_SERVICE_CLS=integrations.github.github_service.SaaSGitHubService
|
||||
OPENHANDS_GITLAB_SERVICE_CLS=integrations.gitlab.gitlab_service.SaaSGitLabService
|
||||
OPENHANDS_BITBUCKET_SERVICE_CLS=integrations.bitbucket.bitbucket_service.SaaSBitBucketService
|
||||
OPENHANDS_CONVERSATION_VALIDATOR_CLS=storage.saas_conversation_validator.SaasConversationValidator
|
||||
|
||||
# ============================================
|
||||
# GitHub App Configuration (Optional)
|
||||
# Required for GitHub OAuth and GitHub integration features
|
||||
# Create a GitHub App at: https://github.com/settings/apps
|
||||
# ============================================
|
||||
# GITHUB_APP_CLIENT_ID=
|
||||
# GITHUB_APP_CLIENT_SECRET=
|
||||
# GITHUB_APP_WEBHOOK_SECRET=
|
||||
# GITHUB_APP_PRIVATE_KEY=
|
||||
|
||||
# ============================================
|
||||
# GitLab App Configuration (Optional)
|
||||
# Required for GitLab OAuth and integration features
|
||||
# ============================================
|
||||
# GITLAB_APP_CLIENT_ID=
|
||||
# GITLAB_APP_CLIENT_SECRET=
|
||||
|
||||
# ============================================
|
||||
# Bitbucket App Configuration (Optional)
|
||||
# ============================================
|
||||
# BITBUCKET_APP_CLIENT_ID=
|
||||
# BITBUCKET_APP_CLIENT_SECRET=
|
||||
|
||||
# ============================================
|
||||
# Feature Flags
|
||||
# ============================================
|
||||
ENABLE_BILLING=false
|
||||
HIDE_LLM_SETTINGS=false
|
||||
ENABLE_JIRA=false
|
||||
ENABLE_JIRA_DC=false
|
||||
ENABLE_LINEAR=false
|
||||
LOCAL_DEPLOYMENT=true
|
||||
|
||||
# ============================================
|
||||
# Frontend Configuration
|
||||
# ============================================
|
||||
# Path to the frontend build directory
|
||||
# FRONTEND_DIRECTORY=../frontend/build
|
||||
|
||||
# ============================================
|
||||
# Logging
|
||||
# ============================================
|
||||
LOG_PLAIN_TEXT=1
|
||||
|
||||
# ============================================
|
||||
# Runtime Configuration
|
||||
# ============================================
|
||||
SANDBOX_RUNTIME_CONTAINER_IMAGE=ghcr.io/openhands/runtime:main-nikolaik
|
||||
|
||||
# ============================================
|
||||
# PostHog (Analytics - can use dummy for local)
|
||||
# ============================================
|
||||
POSTHOG_CLIENT_KEY=test
|
||||
|
||||
# ============================================
|
||||
# LLM API Keys (for LiteLLM proxy)
|
||||
# Add these to litellm container environment
|
||||
# ============================================
|
||||
# OPENAI_API_KEY=
|
||||
# ANTHROPIC_API_KEY=
|
||||
# GOOGLE_API_KEY=
|
||||
|
||||
# ============================================
|
||||
# CORS Configuration
|
||||
# ============================================
|
||||
WEB_HOST=localhost:3000
|
||||
PERMITTED_CORS_ORIGINS=http://localhost:3000,http://localhost:3001
|
||||
323
enterprise/LOCAL_DEV_SETUP.md
Normal file
323
enterprise/LOCAL_DEV_SETUP.md
Normal file
@@ -0,0 +1,323 @@
|
||||
# OpenHands Enterprise Local Development Setup
|
||||
|
||||
This guide provides instructions for setting up OpenHands Enterprise locally for development.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **Docker** and **Docker Compose** (v2+)
|
||||
- **Python 3.12+**
|
||||
- **Poetry** (Python package manager)
|
||||
- **Node.js 18+** and **npm** (for frontend)
|
||||
- An LLM API key (OpenAI, Anthropic, or other supported provider)
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Start Infrastructure Services
|
||||
|
||||
Start all required services using Docker Compose:
|
||||
|
||||
```bash
|
||||
cd enterprise
|
||||
|
||||
# Start PostgreSQL, Redis, Keycloak, and LiteLLM
|
||||
docker-compose -f docker-compose.local.yml up -d
|
||||
```
|
||||
|
||||
This will start:
|
||||
- **PostgreSQL** on port `5432` (database for OpenHands and Keycloak)
|
||||
- **Redis** on port `6379` (caching and pub/sub)
|
||||
- **Keycloak** on port `8080` (authentication)
|
||||
- **LiteLLM** on port `4000` (LLM proxy)
|
||||
|
||||
### 2. Configure Environment Variables
|
||||
|
||||
Copy the example environment file and configure it:
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
Edit `.env` and set your LLM API keys. For LiteLLM to work, you need at least one of:
|
||||
- `OPENAI_API_KEY` - for GPT models
|
||||
- `ANTHROPIC_API_KEY` - for Claude models
|
||||
|
||||
Update the docker-compose to include your API keys:
|
||||
|
||||
```bash
|
||||
# Add to litellm service environment in docker-compose.local.yml
|
||||
# Or create a .env file for docker-compose
|
||||
|
||||
# Then restart litellm
|
||||
docker-compose -f docker-compose.local.yml up -d litellm
|
||||
```
|
||||
|
||||
### 3. Initialize the Database
|
||||
|
||||
Run Alembic migrations to set up the database schema:
|
||||
|
||||
```bash
|
||||
cd enterprise
|
||||
poetry install
|
||||
poetry run alembic upgrade head
|
||||
```
|
||||
|
||||
### 4. Configure Keycloak (Authentication)
|
||||
|
||||
#### Option A: Skip Keycloak (Simplified Setup)
|
||||
|
||||
For basic local development without authentication, you can skip Keycloak by not setting `GITHUB_APP_CLIENT_ID` and related variables. The app will still work but OAuth login won't be available.
|
||||
|
||||
#### Option B: Set Up Keycloak Realm
|
||||
|
||||
1. Access Keycloak Admin Console at `http://localhost:8080`
|
||||
2. Login with `admin` / `admin`
|
||||
3. Create a new realm called `openhands`
|
||||
4. Create a client:
|
||||
- Client ID: `openhands-client`
|
||||
- Client authentication: ON
|
||||
- Valid redirect URIs: `http://localhost:3000/*`, `http://localhost:3001/*`
|
||||
5. Copy the client secret and update your `.env`:
|
||||
```
|
||||
KEYCLOAK_CLIENT_SECRET=<your-client-secret>
|
||||
```
|
||||
|
||||
### 5. Build the Frontend
|
||||
|
||||
```bash
|
||||
# From the repository root (not enterprise/)
|
||||
cd ..
|
||||
make build-frontend
|
||||
# OR
|
||||
cd frontend && npm install && npm run build
|
||||
```
|
||||
|
||||
### 6. Start the Enterprise Backend
|
||||
|
||||
```bash
|
||||
cd enterprise
|
||||
|
||||
# Option A: Using Make
|
||||
OPENHANDS_PATH=../ make start-backend
|
||||
|
||||
# Option B: Using Poetry directly
|
||||
FRONTEND_DIRECTORY=../frontend/build poetry run uvicorn saas_server:app --host 127.0.0.1 --port 3000 --reload
|
||||
```
|
||||
|
||||
### 7. Access the Application
|
||||
|
||||
- **Frontend**: http://localhost:3000 (or 3001 if using dev server)
|
||||
- **Backend API**: http://localhost:3000/api
|
||||
- **Keycloak Admin**: http://localhost:8080
|
||||
- **LiteLLM Proxy**: http://localhost:4000
|
||||
|
||||
## Individual Service Setup
|
||||
|
||||
If you prefer to run services individually:
|
||||
|
||||
### PostgreSQL
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name openhands-postgres \
|
||||
-p 5432:5432 \
|
||||
-e POSTGRES_USER=postgres \
|
||||
-e POSTGRES_PASSWORD=postgres \
|
||||
-e POSTGRES_DB=openhands \
|
||||
postgres:15
|
||||
```
|
||||
|
||||
### Redis
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name openhands-redis \
|
||||
-p 6379:6379 \
|
||||
redis:7-alpine
|
||||
```
|
||||
|
||||
### Keycloak
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name openhands-keycloak \
|
||||
-p 8080:8080 \
|
||||
-e KC_BOOTSTRAP_ADMIN_USERNAME=admin \
|
||||
-e KC_BOOTSTRAP_ADMIN_PASSWORD=admin \
|
||||
-e KC_HTTP_ENABLED=true \
|
||||
-e KC_HOSTNAME_STRICT=false \
|
||||
quay.io/keycloak/keycloak:26.1.1 start-dev
|
||||
```
|
||||
|
||||
### LiteLLM
|
||||
|
||||
```bash
|
||||
# Create litellm-config.yaml first (see file in this directory)
|
||||
docker run -d \
|
||||
--name openhands-litellm \
|
||||
-p 4000:4000 \
|
||||
-v $(pwd)/litellm-config.yaml:/app/config.yaml \
|
||||
-e LITELLM_MASTER_KEY=sk-local-dev-master-key \
|
||||
-e OPENAI_API_KEY=your-openai-key \
|
||||
-e ANTHROPIC_API_KEY=your-anthropic-key \
|
||||
ghcr.io/berriai/litellm:main-latest \
|
||||
--config /app/config.yaml --port 4000 --host 0.0.0.0
|
||||
```
|
||||
|
||||
## Configuration Details
|
||||
|
||||
### Environment Variables Reference
|
||||
|
||||
| Variable | Description | Default |
|
||||
|----------|-------------|---------|
|
||||
| `DB_HOST` | PostgreSQL host | `localhost` |
|
||||
| `DB_PORT` | PostgreSQL port | `5432` |
|
||||
| `DB_USER` | PostgreSQL user | `postgres` |
|
||||
| `DB_PASS` | PostgreSQL password | `postgres` |
|
||||
| `DB_NAME` | PostgreSQL database name | `openhands` |
|
||||
| `REDIS_HOST` | Redis host | `localhost` |
|
||||
| `REDIS_PORT` | Redis port | `6379` |
|
||||
| `KEYCLOAK_SERVER_URL` | Keycloak internal URL | - |
|
||||
| `KEYCLOAK_SERVER_URL_EXT` | Keycloak external URL | - |
|
||||
| `KEYCLOAK_REALM_NAME` | Keycloak realm | - |
|
||||
| `KEYCLOAK_CLIENT_ID` | Keycloak client ID | - |
|
||||
| `KEYCLOAK_CLIENT_SECRET` | Keycloak client secret | - |
|
||||
| `LITE_LLM_API_URL` | LiteLLM proxy URL | `http://localhost:4000` |
|
||||
| `LITE_LLM_API_KEY` | LiteLLM master key | - |
|
||||
| `LITELLM_DEFAULT_MODEL` | Default model to use | `litellm_proxy/claude-sonnet-4-20250514` |
|
||||
| `OPENHANDS_CONFIG_CLS` | Server config class | `server.config.SaaSServerConfig` |
|
||||
| `LOCAL_DEPLOYMENT` | Flag for local mode | `true` |
|
||||
|
||||
### LiteLLM Configuration
|
||||
|
||||
The `litellm-config.yaml` file defines which LLM models are available through the proxy. You can add or modify models as needed.
|
||||
|
||||
To test if LiteLLM is working:
|
||||
|
||||
```bash
|
||||
curl http://localhost:4000/v1/models
|
||||
```
|
||||
|
||||
### Keycloak Realm Setup for GitHub OAuth
|
||||
|
||||
To enable GitHub OAuth through Keycloak:
|
||||
|
||||
1. Create a GitHub OAuth App at https://github.com/settings/developers
|
||||
2. In Keycloak:
|
||||
- Go to Identity Providers > Add provider > GitHub
|
||||
- Enter your GitHub Client ID and Secret
|
||||
- Set redirect URI to match your Keycloak URL
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Database Connection Issues
|
||||
|
||||
```bash
|
||||
# Check if PostgreSQL is running
|
||||
docker ps | grep postgres
|
||||
|
||||
# Check logs
|
||||
docker logs openhands-postgres
|
||||
|
||||
# Test connection
|
||||
psql -h localhost -U postgres -d openhands
|
||||
```
|
||||
|
||||
### Redis Connection Issues
|
||||
|
||||
```bash
|
||||
# Check if Redis is running
|
||||
docker ps | grep redis
|
||||
|
||||
# Test connection
|
||||
redis-cli -h localhost ping
|
||||
```
|
||||
|
||||
### Keycloak Issues
|
||||
|
||||
```bash
|
||||
# Check logs
|
||||
docker logs openhands-keycloak
|
||||
|
||||
# Access admin console
|
||||
open http://localhost:8080/admin
|
||||
```
|
||||
|
||||
### LiteLLM Issues
|
||||
|
||||
```bash
|
||||
# Check logs
|
||||
docker logs openhands-litellm
|
||||
|
||||
# Check health
|
||||
curl http://localhost:4000/health
|
||||
|
||||
# List available models
|
||||
curl http://localhost:4000/v1/models
|
||||
```
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **"Connection refused" errors**: Ensure all Docker containers are running and ports are not blocked.
|
||||
|
||||
2. **Authentication failures**: Check Keycloak configuration and client credentials.
|
||||
|
||||
3. **LLM errors**: Verify your API keys are correctly set in the LiteLLM environment.
|
||||
|
||||
4. **Database migration errors**: Ensure PostgreSQL is running before running migrations.
|
||||
|
||||
## Stopping Services
|
||||
|
||||
```bash
|
||||
# Stop all services
|
||||
docker-compose -f docker-compose.local.yml down
|
||||
|
||||
# Stop and remove volumes (clears all data)
|
||||
docker-compose -f docker-compose.local.yml down -v
|
||||
```
|
||||
|
||||
## Development Tips
|
||||
|
||||
1. **Hot reloading**: Use `--reload` flag with uvicorn for automatic server restarts.
|
||||
|
||||
2. **Frontend development**: Run the frontend dev server separately for faster iteration:
|
||||
```bash
|
||||
cd ../frontend && npm run dev
|
||||
```
|
||||
|
||||
3. **Database changes**: After modifying models, create a new migration:
|
||||
```bash
|
||||
poetry run alembic revision --autogenerate -m "description"
|
||||
poetry run alembic upgrade head
|
||||
```
|
||||
|
||||
4. **Debugging**: Set `LOG_PLAIN_TEXT=1` for readable logs.
|
||||
|
||||
## Minimal Setup (Without Authentication)
|
||||
|
||||
For the simplest possible setup without OAuth:
|
||||
|
||||
```bash
|
||||
# Start only PostgreSQL and Redis
|
||||
docker run -d --name openhands-postgres -p 5432:5432 \
|
||||
-e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres \
|
||||
-e POSTGRES_DB=openhands postgres:15
|
||||
|
||||
docker run -d --name openhands-redis -p 6379:6379 redis:7-alpine
|
||||
|
||||
# Create minimal .env
|
||||
cat > .env << 'EOF'
|
||||
DB_HOST=localhost
|
||||
REDIS_HOST=localhost
|
||||
OPENHANDS_CONFIG_CLS=server.config.SaaSServerConfig
|
||||
LOCAL_DEPLOYMENT=true
|
||||
POSTHOG_CLIENT_KEY=test
|
||||
LOG_PLAIN_TEXT=1
|
||||
EOF
|
||||
|
||||
# Run migrations and start server
|
||||
poetry install
|
||||
poetry run alembic upgrade head
|
||||
FRONTEND_DIRECTORY=../frontend/build poetry run uvicorn saas_server:app --host 0.0.0.0 --port 3000 --reload
|
||||
```
|
||||
|
||||
This provides a working enterprise server without Keycloak authentication or LiteLLM proxy. You can configure LLM directly through the UI or environment variables.
|
||||
108
enterprise/docker-compose.local.yml
Normal file
108
enterprise/docker-compose.local.yml
Normal file
@@ -0,0 +1,108 @@
|
||||
# Docker Compose for running OpenHands Enterprise locally
|
||||
# Usage: docker-compose -f docker-compose.local.yml up -d
|
||||
|
||||
services:
|
||||
# PostgreSQL database
|
||||
postgres:
|
||||
image: postgres:15
|
||||
container_name: openhands-postgres
|
||||
environment:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: openhands
|
||||
# Create additional databases for keycloak and litellm
|
||||
POSTGRES_MULTIPLE_DATABASES: keycloak,litellm
|
||||
ports:
|
||||
- "5432:5432"
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
- ./init-db.sh:/docker-entrypoint-initdb.d/init-db.sh
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U postgres"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
# Redis for caching and pub/sub
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: openhands-redis
|
||||
ports:
|
||||
- "6379:6379"
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
# Keycloak for authentication
|
||||
keycloak:
|
||||
image: quay.io/keycloak/keycloak:26.1.1
|
||||
container_name: openhands-keycloak
|
||||
environment:
|
||||
# Admin credentials
|
||||
KC_BOOTSTRAP_ADMIN_USERNAME: admin
|
||||
KC_BOOTSTRAP_ADMIN_PASSWORD: admin
|
||||
# Database configuration (using embedded H2 for simplicity)
|
||||
KC_DB: postgres
|
||||
KC_DB_URL: jdbc:postgresql://postgres:5432/keycloak
|
||||
KC_DB_USERNAME: postgres
|
||||
KC_DB_PASSWORD: postgres
|
||||
# Features
|
||||
KC_FEATURES: token-exchange
|
||||
KC_HEALTH_ENABLED: true
|
||||
KC_METRICS_ENABLED: true
|
||||
# HTTP settings (for local dev, disable HTTPS requirement)
|
||||
KC_HTTP_ENABLED: true
|
||||
KC_HTTP_PORT: 8080
|
||||
KC_HOSTNAME_STRICT: false
|
||||
KC_HOSTNAME_STRICT_HTTPS: false
|
||||
KC_PROXY_HEADERS: xforwarded
|
||||
ports:
|
||||
- "8080:8080"
|
||||
command: start-dev
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "exec 3<>/dev/tcp/127.0.0.1/8080;echo -e 'GET /health/ready HTTP/1.1\r\nhost: localhost\r\nConnection: close\r\n\r\n' >&3;if [ $? -eq 0 ]; then echo 'Healthcheck Successful';exit 0;else echo 'Healthcheck Failed';exit 1;fi;"]
|
||||
interval: 10s
|
||||
timeout: 10s
|
||||
retries: 10
|
||||
start_period: 30s
|
||||
|
||||
# LiteLLM Proxy for LLM routing
|
||||
litellm:
|
||||
image: ghcr.io/berriai/litellm:main-latest
|
||||
container_name: openhands-litellm
|
||||
environment:
|
||||
# Master key for admin access
|
||||
LITELLM_MASTER_KEY: sk-local-dev-master-key
|
||||
# Database for tracking spend/keys (using same postgres)
|
||||
DATABASE_URL: postgresql://postgres:postgres@postgres:5432/litellm
|
||||
# General settings
|
||||
LITELLM_LOG: DEBUG
|
||||
ports:
|
||||
- "4000:4000"
|
||||
volumes:
|
||||
- ./litellm-config.yaml:/app/config.yaml
|
||||
command: --config /app/config.yaml --port 4000 --host 0.0.0.0 --detailed_debug
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:4000/health"]
|
||||
interval: 10s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
start_period: 15s
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
redis_data:
|
||||
|
||||
networks:
|
||||
default:
|
||||
name: openhands-network
|
||||
14
enterprise/init-db.sh
Executable file
14
enterprise/init-db.sh
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
# Initialize additional databases for OpenHands Enterprise
|
||||
|
||||
set -e
|
||||
|
||||
# Create keycloak database
|
||||
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
|
||||
CREATE DATABASE keycloak;
|
||||
CREATE DATABASE litellm;
|
||||
GRANT ALL PRIVILEGES ON DATABASE keycloak TO $POSTGRES_USER;
|
||||
GRANT ALL PRIVILEGES ON DATABASE litellm TO $POSTGRES_USER;
|
||||
EOSQL
|
||||
|
||||
echo "Additional databases created: keycloak, litellm"
|
||||
76
enterprise/litellm-config.yaml
Normal file
76
enterprise/litellm-config.yaml
Normal file
@@ -0,0 +1,76 @@
|
||||
# LiteLLM Configuration for Local Development
|
||||
# Documentation: https://docs.litellm.ai/docs/proxy/configs
|
||||
|
||||
general_settings:
|
||||
master_key: sk-local-dev-master-key
|
||||
database_url: postgresql://postgres:postgres@postgres:5432/litellm
|
||||
|
||||
model_list:
|
||||
# OpenAI Models
|
||||
- model_name: gpt-4o
|
||||
litellm_params:
|
||||
model: openai/gpt-4o
|
||||
api_key: os.environ/OPENAI_API_KEY
|
||||
|
||||
- model_name: gpt-4o-mini
|
||||
litellm_params:
|
||||
model: openai/gpt-4o-mini
|
||||
api_key: os.environ/OPENAI_API_KEY
|
||||
|
||||
- model_name: gpt-4-turbo
|
||||
litellm_params:
|
||||
model: openai/gpt-4-turbo
|
||||
api_key: os.environ/OPENAI_API_KEY
|
||||
|
||||
# Anthropic Claude Models
|
||||
- model_name: claude-3-5-sonnet-20241022
|
||||
litellm_params:
|
||||
model: anthropic/claude-3-5-sonnet-20241022
|
||||
api_key: os.environ/ANTHROPIC_API_KEY
|
||||
|
||||
- model_name: claude-3-7-sonnet-20250219
|
||||
litellm_params:
|
||||
model: anthropic/claude-3-7-sonnet-20250219
|
||||
api_key: os.environ/ANTHROPIC_API_KEY
|
||||
|
||||
- model_name: claude-sonnet-4-20250514
|
||||
litellm_params:
|
||||
model: anthropic/claude-sonnet-4-20250514
|
||||
api_key: os.environ/ANTHROPIC_API_KEY
|
||||
|
||||
- model_name: claude-opus-4-5-20251101
|
||||
litellm_params:
|
||||
model: anthropic/claude-opus-4-5-20251101
|
||||
api_key: os.environ/ANTHROPIC_API_KEY
|
||||
|
||||
- model_name: claude-3-opus-20240229
|
||||
litellm_params:
|
||||
model: anthropic/claude-3-opus-20240229
|
||||
api_key: os.environ/ANTHROPIC_API_KEY
|
||||
|
||||
# Google Gemini Models (optional)
|
||||
- model_name: gemini-1.5-pro
|
||||
litellm_params:
|
||||
model: gemini/gemini-1.5-pro
|
||||
api_key: os.environ/GOOGLE_API_KEY
|
||||
|
||||
- model_name: gemini-2.0-flash
|
||||
litellm_params:
|
||||
model: gemini/gemini-2.0-flash
|
||||
api_key: os.environ/GOOGLE_API_KEY
|
||||
|
||||
litellm_settings:
|
||||
# Enable request/response logging
|
||||
set_verbose: true
|
||||
# Fallback behavior
|
||||
drop_params: true
|
||||
# Default max tokens if not specified
|
||||
max_tokens: 4096
|
||||
|
||||
router_settings:
|
||||
# Enable retries on failure
|
||||
num_retries: 2
|
||||
# Timeout for each request
|
||||
timeout: 600
|
||||
# Routing strategy
|
||||
routing_strategy: simple-shuffle
|
||||
270
enterprise/setup-local.sh
Executable file
270
enterprise/setup-local.sh
Executable file
@@ -0,0 +1,270 @@
|
||||
#!/bin/bash
|
||||
|
||||
# OpenHands Enterprise Local Development Setup Script
|
||||
# This script helps set up the local development environment
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Script directory
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ENTERPRISE_DIR="$SCRIPT_DIR"
|
||||
OPENHANDS_DIR="$(dirname "$ENTERPRISE_DIR")"
|
||||
|
||||
echo -e "${BLUE}╔═══════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e "${BLUE}║ OpenHands Enterprise Local Development Setup ║${NC}"
|
||||
echo -e "${BLUE}╚═══════════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
|
||||
# Function to check if a command exists
|
||||
command_exists() {
|
||||
command -v "$1" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# Function to check if a Docker container is running
|
||||
container_running() {
|
||||
docker ps --format '{{.Names}}' | grep -q "^$1$"
|
||||
}
|
||||
|
||||
# Function to wait for a service
|
||||
wait_for_service() {
|
||||
local host=$1
|
||||
local port=$2
|
||||
local name=$3
|
||||
local max_attempts=30
|
||||
local attempt=1
|
||||
|
||||
echo -ne " Waiting for $name to be ready..."
|
||||
while ! nc -z "$host" "$port" 2>/dev/null; do
|
||||
if [ $attempt -ge $max_attempts ]; then
|
||||
echo -e " ${RED}FAILED${NC}"
|
||||
echo -e " ${RED}$name did not become ready in time${NC}"
|
||||
return 1
|
||||
fi
|
||||
sleep 2
|
||||
attempt=$((attempt + 1))
|
||||
echo -ne "."
|
||||
done
|
||||
echo -e " ${GREEN}READY${NC}"
|
||||
}
|
||||
|
||||
# Check prerequisites
|
||||
echo -e "${YELLOW}Checking prerequisites...${NC}"
|
||||
|
||||
if ! command_exists docker; then
|
||||
echo -e " ${RED}✗ Docker is not installed${NC}"
|
||||
echo " Please install Docker: https://docs.docker.com/get-docker/"
|
||||
exit 1
|
||||
fi
|
||||
echo -e " ${GREEN}✓ Docker${NC}"
|
||||
|
||||
if ! command_exists docker-compose && ! docker compose version >/dev/null 2>&1; then
|
||||
echo -e " ${RED}✗ Docker Compose is not installed${NC}"
|
||||
exit 1
|
||||
fi
|
||||
echo -e " ${GREEN}✓ Docker Compose${NC}"
|
||||
|
||||
if ! command_exists poetry; then
|
||||
echo -e " ${RED}✗ Poetry is not installed${NC}"
|
||||
echo " Install with: curl -sSL https://install.python-poetry.org | python3 -"
|
||||
exit 1
|
||||
fi
|
||||
echo -e " ${GREEN}✓ Poetry${NC}"
|
||||
|
||||
echo ""
|
||||
|
||||
# Parse arguments
|
||||
MINIMAL=false
|
||||
FULL=false
|
||||
START_ONLY=false
|
||||
STOP=false
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--minimal)
|
||||
MINIMAL=true
|
||||
shift
|
||||
;;
|
||||
--full)
|
||||
FULL=true
|
||||
shift
|
||||
;;
|
||||
--start)
|
||||
START_ONLY=true
|
||||
shift
|
||||
;;
|
||||
--stop)
|
||||
STOP=true
|
||||
shift
|
||||
;;
|
||||
--help|-h)
|
||||
echo "Usage: $0 [OPTIONS]"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --minimal Start only PostgreSQL and Redis (no Keycloak/LiteLLM)"
|
||||
echo " --full Start all services including Keycloak and LiteLLM"
|
||||
echo " --start Only start services, skip installation"
|
||||
echo " --stop Stop all services"
|
||||
echo " --help Show this help message"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Stop services
|
||||
if [ "$STOP" = true ]; then
|
||||
echo -e "${YELLOW}Stopping services...${NC}"
|
||||
cd "$ENTERPRISE_DIR"
|
||||
if [ -f docker-compose.local.yml ]; then
|
||||
docker compose -f docker-compose.local.yml down 2>/dev/null || true
|
||||
fi
|
||||
docker rm -f openhands-postgres openhands-redis openhands-keycloak openhands-litellm 2>/dev/null || true
|
||||
echo -e "${GREEN}Services stopped${NC}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Determine mode
|
||||
if [ "$MINIMAL" = false ] && [ "$FULL" = false ]; then
|
||||
echo -e "${YELLOW}Select setup mode:${NC}"
|
||||
echo " 1) Minimal (PostgreSQL + Redis only)"
|
||||
echo " 2) Full (PostgreSQL + Redis + Keycloak + LiteLLM)"
|
||||
read -p "Enter choice [1]: " choice
|
||||
choice=${choice:-1}
|
||||
|
||||
if [ "$choice" = "1" ]; then
|
||||
MINIMAL=true
|
||||
else
|
||||
FULL=true
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Start services
|
||||
if [ "$MINIMAL" = true ]; then
|
||||
echo -e "${YELLOW}Starting minimal services (PostgreSQL + Redis)...${NC}"
|
||||
|
||||
# PostgreSQL
|
||||
if ! container_running openhands-postgres; then
|
||||
echo -e " Starting PostgreSQL..."
|
||||
docker run -d \
|
||||
--name openhands-postgres \
|
||||
-p 5432:5432 \
|
||||
-e POSTGRES_USER=postgres \
|
||||
-e POSTGRES_PASSWORD=postgres \
|
||||
-e POSTGRES_DB=openhands \
|
||||
postgres:15 >/dev/null
|
||||
else
|
||||
echo -e " ${GREEN}PostgreSQL already running${NC}"
|
||||
fi
|
||||
|
||||
# Redis
|
||||
if ! container_running openhands-redis; then
|
||||
echo -e " Starting Redis..."
|
||||
docker run -d \
|
||||
--name openhands-redis \
|
||||
-p 6379:6379 \
|
||||
redis:7-alpine >/dev/null
|
||||
else
|
||||
echo -e " ${GREEN}Redis already running${NC}"
|
||||
fi
|
||||
|
||||
wait_for_service localhost 5432 "PostgreSQL"
|
||||
wait_for_service localhost 6379 "Redis"
|
||||
|
||||
else
|
||||
echo -e "${YELLOW}Starting full services (PostgreSQL + Redis + Keycloak + LiteLLM)...${NC}"
|
||||
cd "$ENTERPRISE_DIR"
|
||||
|
||||
# Use docker compose
|
||||
if docker compose version >/dev/null 2>&1; then
|
||||
docker compose -f docker-compose.local.yml up -d
|
||||
else
|
||||
docker-compose -f docker-compose.local.yml up -d
|
||||
fi
|
||||
|
||||
wait_for_service localhost 5432 "PostgreSQL"
|
||||
wait_for_service localhost 6379 "Redis"
|
||||
wait_for_service localhost 8080 "Keycloak"
|
||||
wait_for_service localhost 4000 "LiteLLM"
|
||||
fi
|
||||
|
||||
if [ "$START_ONLY" = true ]; then
|
||||
echo ""
|
||||
echo -e "${GREEN}Services started!${NC}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Create .env file if it doesn't exist
|
||||
echo -e "${YELLOW}Configuring environment...${NC}"
|
||||
cd "$ENTERPRISE_DIR"
|
||||
|
||||
if [ ! -f .env ]; then
|
||||
cp .env.example .env
|
||||
echo -e " ${GREEN}Created .env file from template${NC}"
|
||||
echo -e " ${YELLOW}Please edit .env to add your LLM API keys!${NC}"
|
||||
else
|
||||
echo -e " ${GREEN}.env file already exists${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Install Python dependencies
|
||||
echo -e "${YELLOW}Installing Python dependencies...${NC}"
|
||||
cd "$ENTERPRISE_DIR"
|
||||
poetry install
|
||||
|
||||
echo ""
|
||||
|
||||
# Run database migrations
|
||||
echo -e "${YELLOW}Running database migrations...${NC}"
|
||||
poetry run alembic upgrade head
|
||||
|
||||
echo ""
|
||||
|
||||
echo -e "${GREEN}╔═══════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e "${GREEN}║ Setup Complete! ║${NC}"
|
||||
echo -e "${GREEN}╚═══════════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
echo -e "Services running:"
|
||||
echo -e " • PostgreSQL: ${BLUE}localhost:5432${NC}"
|
||||
echo -e " • Redis: ${BLUE}localhost:6379${NC}"
|
||||
if [ "$FULL" = true ]; then
|
||||
echo -e " • Keycloak: ${BLUE}http://localhost:8080${NC} (admin/admin)"
|
||||
echo -e " • LiteLLM: ${BLUE}http://localhost:4000${NC}"
|
||||
fi
|
||||
echo ""
|
||||
echo -e "${YELLOW}Next steps:${NC}"
|
||||
echo ""
|
||||
echo "1. Edit .env and add your LLM API keys (OPENAI_API_KEY or ANTHROPIC_API_KEY)"
|
||||
echo ""
|
||||
if [ "$FULL" = true ]; then
|
||||
echo "2. Configure LiteLLM with your API keys:"
|
||||
echo " docker exec -it openhands-litellm /bin/sh"
|
||||
echo " # Then set environment variables"
|
||||
echo ""
|
||||
echo "3. (Optional) Configure Keycloak realm for OAuth"
|
||||
echo ""
|
||||
fi
|
||||
echo "3. Build the frontend (from repo root):"
|
||||
echo " cd .. && make build-frontend"
|
||||
echo ""
|
||||
echo "4. Start the backend server:"
|
||||
echo " cd enterprise"
|
||||
echo " OPENHANDS_PATH=../ make start-backend"
|
||||
echo ""
|
||||
echo "5. Access the application at: ${BLUE}http://localhost:3000${NC}"
|
||||
echo ""
|
||||
echo "To stop all services: $0 --stop"
|
||||
Reference in New Issue
Block a user