Merge commit 'd803bfe2b1fe7f5e219e50ac20d6801a0a58ac75' as 'vendor/ruvector'
This commit is contained in:
125
vendor/ruvector/npm/packages/ruvbot/deploy/gcp/cloudbuild.yaml
vendored
Normal file
125
vendor/ruvector/npm/packages/ruvbot/deploy/gcp/cloudbuild.yaml
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
# =============================================================================
|
||||
# RuvBot - Google Cloud Build CI/CD Pipeline
|
||||
# =============================================================================
|
||||
# Trigger: Push to main branch or tag
|
||||
# Deploy to: Cloud Run (serverless)
|
||||
#
|
||||
# Cost optimization:
|
||||
# - Uses e2-standard-2 machine for builds
|
||||
# - Caches npm dependencies
|
||||
# - Multi-stage Docker builds
|
||||
# =============================================================================
|
||||
|
||||
steps:
|
||||
# ---------------------------------------------------------------------------
|
||||
# Step 1: Build and Push Docker Image
|
||||
# ---------------------------------------------------------------------------
|
||||
- name: 'gcr.io/cloud-builders/docker'
|
||||
id: 'build-image'
|
||||
args:
|
||||
- 'build'
|
||||
- '-t'
|
||||
- 'gcr.io/$PROJECT_ID/ruvbot:$COMMIT_SHA'
|
||||
- '-t'
|
||||
- 'gcr.io/$PROJECT_ID/ruvbot:latest'
|
||||
- '-f'
|
||||
- 'Dockerfile'
|
||||
- '--cache-from'
|
||||
- 'gcr.io/$PROJECT_ID/ruvbot:latest'
|
||||
- '.'
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Step 2: Push to Container Registry
|
||||
# ---------------------------------------------------------------------------
|
||||
- name: 'gcr.io/cloud-builders/docker'
|
||||
id: 'push-image'
|
||||
args:
|
||||
- 'push'
|
||||
- '--all-tags'
|
||||
- 'gcr.io/$PROJECT_ID/ruvbot'
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Step 3: Deploy to Cloud Run
|
||||
# ---------------------------------------------------------------------------
|
||||
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
|
||||
id: 'deploy-cloud-run'
|
||||
entrypoint: 'gcloud'
|
||||
args:
|
||||
- 'run'
|
||||
- 'deploy'
|
||||
- 'ruvbot'
|
||||
- '--image'
|
||||
- 'gcr.io/$PROJECT_ID/ruvbot:$COMMIT_SHA'
|
||||
- '--region'
|
||||
- '${_REGION}'
|
||||
- '--platform'
|
||||
- 'managed'
|
||||
- '--allow-unauthenticated'
|
||||
- '--port'
|
||||
- '8080'
|
||||
- '--memory'
|
||||
- '512Mi'
|
||||
- '--cpu'
|
||||
- '1'
|
||||
- '--min-instances'
|
||||
- '0'
|
||||
- '--max-instances'
|
||||
- '10'
|
||||
- '--timeout'
|
||||
- '300'
|
||||
- '--concurrency'
|
||||
- '80'
|
||||
- '--set-env-vars'
|
||||
- 'NODE_ENV=production'
|
||||
- '--set-secrets'
|
||||
- 'ANTHROPIC_API_KEY=anthropic-api-key:latest,OPENROUTER_API_KEY=openrouter-api-key:latest,DATABASE_URL=database-url:latest'
|
||||
- '--service-account'
|
||||
- 'ruvbot-runner@$PROJECT_ID.iam.gserviceaccount.com'
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Step 4: Run Database Migrations (if needed)
|
||||
# ---------------------------------------------------------------------------
|
||||
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
|
||||
id: 'run-migrations'
|
||||
entrypoint: 'bash'
|
||||
args:
|
||||
- '-c'
|
||||
- |
|
||||
gcloud run jobs execute ruvbot-migrations \
|
||||
--region ${_REGION} \
|
||||
--wait \
|
||||
|| echo "No migrations job configured, skipping"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Substitutions (can be overridden)
|
||||
# ---------------------------------------------------------------------------
|
||||
substitutions:
|
||||
_REGION: 'us-central1'
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Build Options
|
||||
# ---------------------------------------------------------------------------
|
||||
options:
|
||||
logging: CLOUD_LOGGING_ONLY
|
||||
machineType: 'E2_HIGHCPU_8'
|
||||
dynamicSubstitutions: true
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Images to push
|
||||
# ---------------------------------------------------------------------------
|
||||
images:
|
||||
- 'gcr.io/$PROJECT_ID/ruvbot:$COMMIT_SHA'
|
||||
- 'gcr.io/$PROJECT_ID/ruvbot:latest'
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Timeout
|
||||
# ---------------------------------------------------------------------------
|
||||
timeout: '1200s'
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Tags for organization
|
||||
# ---------------------------------------------------------------------------
|
||||
tags:
|
||||
- 'ruvbot'
|
||||
- 'cloud-run'
|
||||
- 'production'
|
||||
263
vendor/ruvector/npm/packages/ruvbot/deploy/gcp/deploy.sh
vendored
Executable file
263
vendor/ruvector/npm/packages/ruvbot/deploy/gcp/deploy.sh
vendored
Executable file
@@ -0,0 +1,263 @@
|
||||
#!/bin/bash
|
||||
# =============================================================================
|
||||
# RuvBot - Google Cloud Platform Deployment Script
|
||||
# =============================================================================
|
||||
# Quick deployment for RuvBot to Google Cloud Run
|
||||
#
|
||||
# Usage:
|
||||
# ./deploy.sh [options]
|
||||
#
|
||||
# Options:
|
||||
# --project-id ID GCP Project ID (required)
|
||||
# --region REGION GCP Region (default: us-central1)
|
||||
# --env ENV Environment: dev, staging, prod (default: prod)
|
||||
# --no-sql Skip Cloud SQL setup (use in-memory)
|
||||
# --terraform Use Terraform instead of gcloud
|
||||
# --destroy Destroy all resources
|
||||
#
|
||||
# Environment Variables:
|
||||
# ANTHROPIC_API_KEY Required: Anthropic API key
|
||||
# OPENROUTER_API_KEY Optional: OpenRouter API key
|
||||
# =============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Defaults
|
||||
REGION="us-central1"
|
||||
ENVIRONMENT="prod"
|
||||
USE_TERRAFORM=false
|
||||
ENABLE_SQL=true
|
||||
DESTROY=false
|
||||
|
||||
# Parse arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--project-id)
|
||||
PROJECT_ID="$2"
|
||||
shift 2
|
||||
;;
|
||||
--region)
|
||||
REGION="$2"
|
||||
shift 2
|
||||
;;
|
||||
--env)
|
||||
ENVIRONMENT="$2"
|
||||
shift 2
|
||||
;;
|
||||
--no-sql)
|
||||
ENABLE_SQL=false
|
||||
shift
|
||||
;;
|
||||
--terraform)
|
||||
USE_TERRAFORM=true
|
||||
shift
|
||||
;;
|
||||
--destroy)
|
||||
DESTROY=true
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo -e "${RED}Unknown option: $1${NC}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Validate required variables
|
||||
if [ -z "$PROJECT_ID" ]; then
|
||||
echo -e "${RED}Error: --project-id is required${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$ANTHROPIC_API_KEY" ]; then
|
||||
echo -e "${RED}Error: ANTHROPIC_API_KEY environment variable is required${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${BLUE}================================================${NC}"
|
||||
echo -e "${BLUE} RuvBot GCP Deployment${NC}"
|
||||
echo -e "${BLUE}================================================${NC}"
|
||||
echo -e "Project: ${GREEN}$PROJECT_ID${NC}"
|
||||
echo -e "Region: ${GREEN}$REGION${NC}"
|
||||
echo -e "Environment: ${GREEN}$ENVIRONMENT${NC}"
|
||||
echo -e "Cloud SQL: ${GREEN}$ENABLE_SQL${NC}"
|
||||
echo -e "Method: ${GREEN}$([ "$USE_TERRAFORM" = true ] && echo "Terraform" || echo "gcloud")${NC}"
|
||||
echo -e "${BLUE}================================================${NC}"
|
||||
|
||||
# Confirm deployment
|
||||
read -p "Continue with deployment? (y/N) " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "Deployment cancelled."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Terraform Deployment
|
||||
# -----------------------------------------------------------------------------
|
||||
if [ "$USE_TERRAFORM" = true ]; then
|
||||
cd "$(dirname "$0")/terraform"
|
||||
|
||||
if [ "$DESTROY" = true ]; then
|
||||
echo -e "${YELLOW}Destroying infrastructure...${NC}"
|
||||
terraform destroy \
|
||||
-var="project_id=$PROJECT_ID" \
|
||||
-var="region=$REGION" \
|
||||
-var="environment=$ENVIRONMENT" \
|
||||
-var="enable_cloud_sql=$ENABLE_SQL" \
|
||||
-var="anthropic_api_key=$ANTHROPIC_API_KEY" \
|
||||
-var="openrouter_api_key=${OPENROUTER_API_KEY:-}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}Initializing Terraform...${NC}"
|
||||
terraform init
|
||||
|
||||
echo -e "${YELLOW}Planning deployment...${NC}"
|
||||
terraform plan \
|
||||
-var="project_id=$PROJECT_ID" \
|
||||
-var="region=$REGION" \
|
||||
-var="environment=$ENVIRONMENT" \
|
||||
-var="enable_cloud_sql=$ENABLE_SQL" \
|
||||
-var="anthropic_api_key=$ANTHROPIC_API_KEY" \
|
||||
-var="openrouter_api_key=${OPENROUTER_API_KEY:-}" \
|
||||
-out=tfplan
|
||||
|
||||
echo -e "${YELLOW}Applying deployment...${NC}"
|
||||
terraform apply tfplan
|
||||
|
||||
echo -e "${GREEN}Deployment complete!${NC}"
|
||||
terraform output
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# gcloud Deployment
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
echo -e "${YELLOW}Setting project...${NC}"
|
||||
gcloud config set project "$PROJECT_ID"
|
||||
|
||||
echo -e "${YELLOW}Enabling APIs...${NC}"
|
||||
gcloud services enable \
|
||||
run.googleapis.com \
|
||||
cloudbuild.googleapis.com \
|
||||
secretmanager.googleapis.com \
|
||||
sqladmin.googleapis.com \
|
||||
storage.googleapis.com
|
||||
|
||||
# Create secrets
|
||||
echo -e "${YELLOW}Creating secrets...${NC}"
|
||||
echo -n "$ANTHROPIC_API_KEY" | gcloud secrets create anthropic-api-key \
|
||||
--data-file=- --replication-policy=automatic 2>/dev/null || \
|
||||
echo -n "$ANTHROPIC_API_KEY" | gcloud secrets versions add anthropic-api-key --data-file=-
|
||||
|
||||
if [ -n "$OPENROUTER_API_KEY" ]; then
|
||||
echo -n "$OPENROUTER_API_KEY" | gcloud secrets create openrouter-api-key \
|
||||
--data-file=- --replication-policy=automatic 2>/dev/null || \
|
||||
echo -n "$OPENROUTER_API_KEY" | gcloud secrets versions add openrouter-api-key --data-file=-
|
||||
fi
|
||||
|
||||
# Create service account
|
||||
echo -e "${YELLOW}Creating service account...${NC}"
|
||||
gcloud iam service-accounts create ruvbot-runner \
|
||||
--display-name="RuvBot Cloud Run" 2>/dev/null || true
|
||||
|
||||
SA_EMAIL="ruvbot-runner@$PROJECT_ID.iam.gserviceaccount.com"
|
||||
|
||||
gcloud projects add-iam-policy-binding "$PROJECT_ID" \
|
||||
--member="serviceAccount:$SA_EMAIL" \
|
||||
--role="roles/secretmanager.secretAccessor" --quiet
|
||||
|
||||
gcloud projects add-iam-policy-binding "$PROJECT_ID" \
|
||||
--member="serviceAccount:$SA_EMAIL" \
|
||||
--role="roles/cloudsql.client" --quiet
|
||||
|
||||
# Create Cloud SQL (if enabled)
|
||||
if [ "$ENABLE_SQL" = true ]; then
|
||||
echo -e "${YELLOW}Creating Cloud SQL instance...${NC}"
|
||||
|
||||
if ! gcloud sql instances describe "ruvbot-$ENVIRONMENT" --quiet 2>/dev/null; then
|
||||
gcloud sql instances create "ruvbot-$ENVIRONMENT" \
|
||||
--database-version=POSTGRES_16 \
|
||||
--tier=db-f1-micro \
|
||||
--region="$REGION" \
|
||||
--storage-size=10GB \
|
||||
--storage-auto-increase \
|
||||
--availability-type=zonal
|
||||
|
||||
# Generate password
|
||||
DB_PASSWORD=$(openssl rand -base64 24 | tr -d '/+=' | head -c 24)
|
||||
|
||||
# Create database and user
|
||||
gcloud sql databases create ruvbot --instance="ruvbot-$ENVIRONMENT"
|
||||
gcloud sql users create ruvbot --instance="ruvbot-$ENVIRONMENT" --password="$DB_PASSWORD"
|
||||
|
||||
# Get instance IP
|
||||
INSTANCE_IP=$(gcloud sql instances describe "ruvbot-$ENVIRONMENT" --format='get(ipAddresses[0].ipAddress)')
|
||||
|
||||
# Store connection string in secrets
|
||||
DATABASE_URL="postgresql://ruvbot:$DB_PASSWORD@$INSTANCE_IP:5432/ruvbot"
|
||||
echo -n "$DATABASE_URL" | gcloud secrets create database-url \
|
||||
--data-file=- --replication-policy=automatic 2>/dev/null || \
|
||||
echo -n "$DATABASE_URL" | gcloud secrets versions add database-url --data-file=-
|
||||
fi
|
||||
fi
|
||||
|
||||
# Build and push image
|
||||
echo -e "${YELLOW}Building container image...${NC}"
|
||||
cd "$(dirname "$0")/../.."
|
||||
gcloud builds submit --tag "gcr.io/$PROJECT_ID/ruvbot:latest" .
|
||||
|
||||
# Deploy to Cloud Run
|
||||
echo -e "${YELLOW}Deploying to Cloud Run...${NC}"
|
||||
SECRETS="ANTHROPIC_API_KEY=anthropic-api-key:latest"
|
||||
if [ -n "$OPENROUTER_API_KEY" ]; then
|
||||
SECRETS="$SECRETS,OPENROUTER_API_KEY=openrouter-api-key:latest"
|
||||
fi
|
||||
if [ "$ENABLE_SQL" = true ]; then
|
||||
SECRETS="$SECRETS,DATABASE_URL=database-url:latest"
|
||||
fi
|
||||
|
||||
gcloud run deploy ruvbot \
|
||||
--image="gcr.io/$PROJECT_ID/ruvbot:latest" \
|
||||
--region="$REGION" \
|
||||
--platform=managed \
|
||||
--allow-unauthenticated \
|
||||
--port=8080 \
|
||||
--memory=512Mi \
|
||||
--cpu=1 \
|
||||
--min-instances=0 \
|
||||
--max-instances=10 \
|
||||
--timeout=300 \
|
||||
--concurrency=80 \
|
||||
--set-env-vars="NODE_ENV=production" \
|
||||
--set-secrets="$SECRETS" \
|
||||
--service-account="$SA_EMAIL"
|
||||
|
||||
# Get URL
|
||||
SERVICE_URL=$(gcloud run services describe ruvbot --region="$REGION" --format='get(status.url)')
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}================================================${NC}"
|
||||
echo -e "${GREEN} Deployment Complete!${NC}"
|
||||
echo -e "${GREEN}================================================${NC}"
|
||||
echo -e "Service URL: ${BLUE}$SERVICE_URL${NC}"
|
||||
echo -e "Health Check: ${BLUE}$SERVICE_URL/health${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}Estimated Monthly Cost:${NC}"
|
||||
echo " - Cloud Run: ~\$0 (free tier)"
|
||||
if [ "$ENABLE_SQL" = true ]; then
|
||||
echo " - Cloud SQL: ~\$10-15/month"
|
||||
fi
|
||||
echo " - Secrets: ~\$0.18/month"
|
||||
echo " - Total: ~\$$([ "$ENABLE_SQL" = true ] && echo "15-20" || echo "5")/month"
|
||||
echo ""
|
||||
echo -e "${GREEN}Done!${NC}"
|
||||
443
vendor/ruvector/npm/packages/ruvbot/deploy/gcp/terraform/main.tf
vendored
Normal file
443
vendor/ruvector/npm/packages/ruvbot/deploy/gcp/terraform/main.tf
vendored
Normal file
@@ -0,0 +1,443 @@
|
||||
# =============================================================================
|
||||
# RuvBot - Google Cloud Platform Infrastructure
|
||||
# =============================================================================
|
||||
# Cost-optimized deployment using:
|
||||
# - Cloud Run (serverless, pay-per-use)
|
||||
# - Cloud SQL PostgreSQL (smallest instance, can scale)
|
||||
# - Memorystore Redis (optional, can use in-memory)
|
||||
# - Secret Manager (for credentials)
|
||||
# - Cloud Storage (for file uploads)
|
||||
#
|
||||
# Estimated monthly cost (low traffic): $15-30/month
|
||||
# - Cloud Run: ~$0 (generous free tier)
|
||||
# - Cloud SQL: ~$10-15/month (db-f1-micro)
|
||||
# - Secret Manager: ~$0.06/secret/month
|
||||
# - Cloud Storage: ~$0.02/GB/month
|
||||
# =============================================================================
|
||||
|
||||
terraform {
|
||||
required_version = ">= 1.5.0"
|
||||
|
||||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = "~> 5.0"
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = "~> 5.0"
|
||||
}
|
||||
}
|
||||
|
||||
# Uncomment for remote state (recommended for production)
|
||||
# backend "gcs" {
|
||||
# bucket = "your-terraform-state-bucket"
|
||||
# prefix = "ruvbot/state"
|
||||
# }
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Variables
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
variable "project_id" {
|
||||
description = "GCP Project ID"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "GCP Region"
|
||||
type = string
|
||||
default = "us-central1"
|
||||
}
|
||||
|
||||
variable "environment" {
|
||||
description = "Environment (dev, staging, prod)"
|
||||
type = string
|
||||
default = "prod"
|
||||
}
|
||||
|
||||
variable "enable_cloud_sql" {
|
||||
description = "Enable Cloud SQL PostgreSQL (adds ~$10/month)"
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "enable_redis" {
|
||||
description = "Enable Memorystore Redis (adds ~$30/month)"
|
||||
type = bool
|
||||
default = false # Disabled by default for cost savings
|
||||
}
|
||||
|
||||
variable "anthropic_api_key" {
|
||||
description = "Anthropic API Key"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "openrouter_api_key" {
|
||||
description = "OpenRouter API Key"
|
||||
type = string
|
||||
sensitive = true
|
||||
default = ""
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Provider Configuration
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
provider "google" {
|
||||
project = var.project_id
|
||||
region = var.region
|
||||
}
|
||||
|
||||
provider "google-beta" {
|
||||
project = var.project_id
|
||||
region = var.region
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Enable Required APIs
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
resource "google_project_service" "services" {
|
||||
for_each = toset([
|
||||
"run.googleapis.com",
|
||||
"cloudbuild.googleapis.com",
|
||||
"secretmanager.googleapis.com",
|
||||
"sqladmin.googleapis.com",
|
||||
"storage.googleapis.com",
|
||||
"redis.googleapis.com",
|
||||
"vpcaccess.googleapis.com",
|
||||
])
|
||||
|
||||
service = each.value
|
||||
disable_on_destroy = false
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Service Account for Cloud Run
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
resource "google_service_account" "ruvbot_runner" {
|
||||
account_id = "ruvbot-runner"
|
||||
display_name = "RuvBot Cloud Run Service Account"
|
||||
description = "Service account for RuvBot Cloud Run service"
|
||||
}
|
||||
|
||||
resource "google_project_iam_member" "ruvbot_runner_roles" {
|
||||
for_each = toset([
|
||||
"roles/secretmanager.secretAccessor",
|
||||
"roles/cloudsql.client",
|
||||
"roles/storage.objectAdmin",
|
||||
"roles/logging.logWriter",
|
||||
"roles/monitoring.metricWriter",
|
||||
])
|
||||
|
||||
project = var.project_id
|
||||
role = each.value
|
||||
member = "serviceAccount:${google_service_account.ruvbot_runner.email}"
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Secret Manager - Store API Keys Securely
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
resource "google_secret_manager_secret" "anthropic_api_key" {
|
||||
secret_id = "anthropic-api-key"
|
||||
|
||||
replication {
|
||||
auto {}
|
||||
}
|
||||
|
||||
depends_on = [google_project_service.services]
|
||||
}
|
||||
|
||||
resource "google_secret_manager_secret_version" "anthropic_api_key" {
|
||||
secret = google_secret_manager_secret.anthropic_api_key.id
|
||||
secret_data = var.anthropic_api_key
|
||||
}
|
||||
|
||||
resource "google_secret_manager_secret" "openrouter_api_key" {
|
||||
count = var.openrouter_api_key != "" ? 1 : 0
|
||||
secret_id = "openrouter-api-key"
|
||||
|
||||
replication {
|
||||
auto {}
|
||||
}
|
||||
|
||||
depends_on = [google_project_service.services]
|
||||
}
|
||||
|
||||
resource "google_secret_manager_secret_version" "openrouter_api_key" {
|
||||
count = var.openrouter_api_key != "" ? 1 : 0
|
||||
secret = google_secret_manager_secret.openrouter_api_key[0].id
|
||||
secret_data = var.openrouter_api_key
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Cloud SQL PostgreSQL (Cost-Optimized)
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
resource "google_sql_database_instance" "ruvbot" {
|
||||
count = var.enable_cloud_sql ? 1 : 0
|
||||
name = "ruvbot-${var.environment}"
|
||||
database_version = "POSTGRES_16"
|
||||
region = var.region
|
||||
|
||||
settings {
|
||||
# db-f1-micro: 0.6GB RAM, shared CPU - ~$10/month
|
||||
tier = "db-f1-micro"
|
||||
availability_type = "ZONAL" # Single zone for cost savings
|
||||
|
||||
disk_size = 10 # Minimum 10GB
|
||||
disk_type = "PD_SSD"
|
||||
disk_autoresize = true
|
||||
|
||||
backup_configuration {
|
||||
enabled = true
|
||||
point_in_time_recovery_enabled = false # Disable for cost savings
|
||||
backup_retention_settings {
|
||||
retained_backups = 7
|
||||
}
|
||||
}
|
||||
|
||||
ip_configuration {
|
||||
ipv4_enabled = true
|
||||
# For production, use private IP with VPC connector
|
||||
authorized_networks {
|
||||
name = "allow-cloud-run"
|
||||
value = "0.0.0.0/0" # Cloud Run uses public IP; restrict in production
|
||||
}
|
||||
}
|
||||
|
||||
database_flags {
|
||||
name = "max_connections"
|
||||
value = "50"
|
||||
}
|
||||
}
|
||||
|
||||
deletion_protection = var.environment == "prod"
|
||||
|
||||
depends_on = [google_project_service.services]
|
||||
}
|
||||
|
||||
resource "google_sql_database" "ruvbot" {
|
||||
count = var.enable_cloud_sql ? 1 : 0
|
||||
name = "ruvbot"
|
||||
instance = google_sql_database_instance.ruvbot[0].name
|
||||
}
|
||||
|
||||
resource "google_sql_user" "ruvbot" {
|
||||
count = var.enable_cloud_sql ? 1 : 0
|
||||
name = "ruvbot"
|
||||
instance = google_sql_database_instance.ruvbot[0].name
|
||||
password = random_password.db_password[0].result
|
||||
}
|
||||
|
||||
resource "random_password" "db_password" {
|
||||
count = var.enable_cloud_sql ? 1 : 0
|
||||
length = 32
|
||||
special = false
|
||||
}
|
||||
|
||||
resource "google_secret_manager_secret" "database_url" {
|
||||
count = var.enable_cloud_sql ? 1 : 0
|
||||
secret_id = "database-url"
|
||||
|
||||
replication {
|
||||
auto {}
|
||||
}
|
||||
|
||||
depends_on = [google_project_service.services]
|
||||
}
|
||||
|
||||
resource "google_secret_manager_secret_version" "database_url" {
|
||||
count = var.enable_cloud_sql ? 1 : 0
|
||||
secret = google_secret_manager_secret.database_url[0].id
|
||||
secret_data = "postgresql://ruvbot:${random_password.db_password[0].result}@${google_sql_database_instance.ruvbot[0].public_ip_address}:5432/ruvbot"
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Cloud Storage Bucket (for file uploads)
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
resource "google_storage_bucket" "ruvbot_data" {
|
||||
name = "${var.project_id}-ruvbot-data"
|
||||
location = var.region
|
||||
force_destroy = var.environment != "prod"
|
||||
|
||||
uniform_bucket_level_access = true
|
||||
|
||||
lifecycle_rule {
|
||||
condition {
|
||||
age = 30
|
||||
}
|
||||
action {
|
||||
type = "SetStorageClass"
|
||||
storage_class = "NEARLINE"
|
||||
}
|
||||
}
|
||||
|
||||
lifecycle_rule {
|
||||
condition {
|
||||
age = 90
|
||||
}
|
||||
action {
|
||||
type = "SetStorageClass"
|
||||
storage_class = "COLDLINE"
|
||||
}
|
||||
}
|
||||
|
||||
versioning {
|
||||
enabled = var.environment == "prod"
|
||||
}
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Cloud Run Service
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
resource "google_cloud_run_v2_service" "ruvbot" {
|
||||
name = "ruvbot"
|
||||
location = var.region
|
||||
ingress = "INGRESS_TRAFFIC_ALL"
|
||||
|
||||
template {
|
||||
service_account = google_service_account.ruvbot_runner.email
|
||||
|
||||
scaling {
|
||||
min_instance_count = 0 # Scale to zero when not in use
|
||||
max_instance_count = 10
|
||||
}
|
||||
|
||||
containers {
|
||||
image = "gcr.io/${var.project_id}/ruvbot:latest"
|
||||
|
||||
ports {
|
||||
container_port = 8080
|
||||
}
|
||||
|
||||
resources {
|
||||
limits = {
|
||||
cpu = "1"
|
||||
memory = "512Mi"
|
||||
}
|
||||
cpu_idle = true # Reduce cost during idle
|
||||
startup_cpu_boost = true # Faster cold starts
|
||||
}
|
||||
|
||||
env {
|
||||
name = "NODE_ENV"
|
||||
value = "production"
|
||||
}
|
||||
|
||||
env {
|
||||
name = "GCS_BUCKET"
|
||||
value = google_storage_bucket.ruvbot_data.name
|
||||
}
|
||||
|
||||
env {
|
||||
name = "ANTHROPIC_API_KEY"
|
||||
value_source {
|
||||
secret_key_ref {
|
||||
secret = google_secret_manager_secret.anthropic_api_key.secret_id
|
||||
version = "latest"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "env" {
|
||||
for_each = var.enable_cloud_sql ? [1] : []
|
||||
content {
|
||||
name = "DATABASE_URL"
|
||||
value_source {
|
||||
secret_key_ref {
|
||||
secret = google_secret_manager_secret.database_url[0].secret_id
|
||||
version = "latest"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
startup_probe {
|
||||
http_get {
|
||||
path = "/health"
|
||||
port = 8080
|
||||
}
|
||||
initial_delay_seconds = 5
|
||||
timeout_seconds = 3
|
||||
period_seconds = 10
|
||||
failure_threshold = 3
|
||||
}
|
||||
|
||||
liveness_probe {
|
||||
http_get {
|
||||
path = "/health"
|
||||
port = 8080
|
||||
}
|
||||
timeout_seconds = 3
|
||||
period_seconds = 30
|
||||
failure_threshold = 3
|
||||
}
|
||||
}
|
||||
|
||||
max_instance_request_concurrency = 80
|
||||
timeout = "300s"
|
||||
}
|
||||
|
||||
traffic {
|
||||
type = "TRAFFIC_TARGET_ALLOCATION_TYPE_LATEST"
|
||||
percent = 100
|
||||
}
|
||||
|
||||
depends_on = [
|
||||
google_project_service.services,
|
||||
google_secret_manager_secret_version.anthropic_api_key,
|
||||
]
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Allow Unauthenticated Access to Cloud Run
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
resource "google_cloud_run_v2_service_iam_member" "public_access" {
|
||||
project = var.project_id
|
||||
location = var.region
|
||||
name = google_cloud_run_v2_service.ruvbot.name
|
||||
role = "roles/run.invoker"
|
||||
member = "allUsers"
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Outputs
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
output "cloud_run_url" {
|
||||
description = "Cloud Run service URL"
|
||||
value = google_cloud_run_v2_service.ruvbot.uri
|
||||
}
|
||||
|
||||
output "cloud_sql_connection_name" {
|
||||
description = "Cloud SQL connection name"
|
||||
value = var.enable_cloud_sql ? google_sql_database_instance.ruvbot[0].connection_name : "N/A"
|
||||
}
|
||||
|
||||
output "storage_bucket" {
|
||||
description = "Cloud Storage bucket name"
|
||||
value = google_storage_bucket.ruvbot_data.name
|
||||
}
|
||||
|
||||
output "estimated_monthly_cost" {
|
||||
description = "Estimated monthly cost"
|
||||
value = <<-EOT
|
||||
Estimated Monthly Cost (low traffic):
|
||||
- Cloud Run: ~$0 (free tier covers ~2M requests)
|
||||
- Cloud SQL: ${var.enable_cloud_sql ? "~$10-15" : "$0"}
|
||||
- Secret Manager: ~$0.18 (3 secrets)
|
||||
- Cloud Storage: ~$0.02/GB
|
||||
- Redis: ${var.enable_redis ? "~$30" : "$0 (disabled)"}
|
||||
----------------------------------------
|
||||
Total: ~$${var.enable_cloud_sql ? (var.enable_redis ? "45-50" : "15-20") : "5-10"}/month
|
||||
EOT
|
||||
}
|
||||
310
vendor/ruvector/npm/packages/ruvbot/deploy/init-db.sql
vendored
Normal file
310
vendor/ruvector/npm/packages/ruvbot/deploy/init-db.sql
vendored
Normal file
@@ -0,0 +1,310 @@
|
||||
-- =============================================================================
|
||||
-- RuvBot - Database Initialization Script
|
||||
-- =============================================================================
|
||||
-- PostgreSQL schema for multi-tenant RuvBot deployment
|
||||
-- Supports: Sessions, Memory, Skills, Events, Metrics
|
||||
-- =============================================================================
|
||||
|
||||
-- Enable required extensions
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
|
||||
CREATE EXTENSION IF NOT EXISTS "pg_trgm"; -- For text search
|
||||
|
||||
-- =============================================================================
|
||||
-- Tenants (Multi-tenancy support)
|
||||
-- =============================================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS tenants (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
name VARCHAR(255) NOT NULL,
|
||||
slug VARCHAR(100) UNIQUE NOT NULL,
|
||||
settings JSONB DEFAULT '{}',
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Enable Row-Level Security
|
||||
ALTER TABLE tenants ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- =============================================================================
|
||||
-- Users
|
||||
-- =============================================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
external_id VARCHAR(255), -- Slack user ID, Discord ID, etc.
|
||||
username VARCHAR(255),
|
||||
email VARCHAR(255),
|
||||
avatar_url TEXT,
|
||||
metadata JSONB DEFAULT '{}',
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(tenant_id, external_id)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_users_tenant ON users(tenant_id);
|
||||
CREATE INDEX idx_users_external ON users(external_id);
|
||||
|
||||
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- =============================================================================
|
||||
-- Agents
|
||||
-- =============================================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS agents (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
type VARCHAR(50) DEFAULT 'assistant',
|
||||
model VARCHAR(100) DEFAULT 'claude-3-5-sonnet',
|
||||
system_prompt TEXT,
|
||||
config JSONB DEFAULT '{}',
|
||||
status VARCHAR(20) DEFAULT 'active',
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX idx_agents_tenant ON agents(tenant_id);
|
||||
|
||||
ALTER TABLE agents ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- =============================================================================
|
||||
-- Sessions
|
||||
-- =============================================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sessions (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
agent_id UUID REFERENCES agents(id) ON DELETE CASCADE,
|
||||
user_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
||||
channel_type VARCHAR(50), -- slack, discord, telegram, web
|
||||
channel_id VARCHAR(255), -- Channel/room ID
|
||||
thread_id VARCHAR(255), -- Thread ID if applicable
|
||||
status VARCHAR(20) DEFAULT 'active',
|
||||
metadata JSONB DEFAULT '{}',
|
||||
started_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
ended_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX idx_sessions_tenant ON sessions(tenant_id);
|
||||
CREATE INDEX idx_sessions_agent ON sessions(agent_id);
|
||||
CREATE INDEX idx_sessions_user ON sessions(user_id);
|
||||
CREATE INDEX idx_sessions_channel ON sessions(channel_type, channel_id);
|
||||
CREATE INDEX idx_sessions_status ON sessions(status) WHERE status = 'active';
|
||||
|
||||
ALTER TABLE sessions ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- =============================================================================
|
||||
-- Turns (Conversation Messages)
|
||||
-- =============================================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS turns (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
session_id UUID REFERENCES sessions(id) ON DELETE CASCADE,
|
||||
role VARCHAR(20) NOT NULL, -- user, assistant, system
|
||||
content TEXT NOT NULL,
|
||||
tokens_input INTEGER DEFAULT 0,
|
||||
tokens_output INTEGER DEFAULT 0,
|
||||
latency_ms INTEGER,
|
||||
tool_calls JSONB,
|
||||
metadata JSONB DEFAULT '{}',
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX idx_turns_session ON turns(session_id);
|
||||
CREATE INDEX idx_turns_created ON turns(created_at DESC);
|
||||
|
||||
-- =============================================================================
|
||||
-- Memory (Long-term storage with vector search)
|
||||
-- =============================================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS memories (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
|
||||
type VARCHAR(50) NOT NULL, -- fact, preference, episode, semantic
|
||||
content TEXT NOT NULL,
|
||||
embedding FLOAT8[], -- Vector embedding (1536 dimensions for OpenAI, 768 for local)
|
||||
importance FLOAT DEFAULT 0.5,
|
||||
access_count INTEGER DEFAULT 0,
|
||||
last_accessed TIMESTAMPTZ,
|
||||
expires_at TIMESTAMPTZ,
|
||||
metadata JSONB DEFAULT '{}',
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX idx_memories_tenant ON memories(tenant_id);
|
||||
CREATE INDEX idx_memories_user ON memories(user_id);
|
||||
CREATE INDEX idx_memories_type ON memories(type);
|
||||
CREATE INDEX idx_memories_importance ON memories(importance DESC);
|
||||
|
||||
-- Full-text search index
|
||||
CREATE INDEX idx_memories_content_trgm ON memories USING gin(content gin_trgm_ops);
|
||||
|
||||
ALTER TABLE memories ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- =============================================================================
|
||||
-- Skills
|
||||
-- =============================================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS skills (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
description TEXT,
|
||||
category VARCHAR(100),
|
||||
version VARCHAR(20) DEFAULT '1.0.0',
|
||||
schema JSONB NOT NULL, -- Input/output schema
|
||||
implementation JSONB, -- Skill configuration
|
||||
enabled BOOLEAN DEFAULT true,
|
||||
usage_count INTEGER DEFAULT 0,
|
||||
success_rate FLOAT DEFAULT 1.0,
|
||||
metadata JSONB DEFAULT '{}',
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(tenant_id, name, version)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_skills_tenant ON skills(tenant_id);
|
||||
CREATE INDEX idx_skills_category ON skills(category);
|
||||
CREATE INDEX idx_skills_enabled ON skills(enabled) WHERE enabled = true;
|
||||
|
||||
ALTER TABLE skills ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- =============================================================================
|
||||
-- Events (Event Sourcing)
|
||||
-- =============================================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS events (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
aggregate_type VARCHAR(100) NOT NULL,
|
||||
aggregate_id UUID NOT NULL,
|
||||
event_type VARCHAR(100) NOT NULL,
|
||||
event_version INTEGER DEFAULT 1,
|
||||
payload JSONB NOT NULL,
|
||||
metadata JSONB DEFAULT '{}',
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX idx_events_aggregate ON events(aggregate_type, aggregate_id);
|
||||
CREATE INDEX idx_events_type ON events(event_type);
|
||||
CREATE INDEX idx_events_created ON events(created_at DESC);
|
||||
|
||||
-- =============================================================================
|
||||
-- Metrics (Usage tracking)
|
||||
-- =============================================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS metrics (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
metric_name VARCHAR(100) NOT NULL,
|
||||
metric_value FLOAT NOT NULL,
|
||||
dimensions JSONB DEFAULT '{}',
|
||||
recorded_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX idx_metrics_tenant ON metrics(tenant_id);
|
||||
CREATE INDEX idx_metrics_name ON metrics(metric_name);
|
||||
CREATE INDEX idx_metrics_recorded ON metrics(recorded_at DESC);
|
||||
|
||||
-- Partition by time for better performance
|
||||
-- (In production, consider using TimescaleDB or partitioning)
|
||||
|
||||
-- =============================================================================
|
||||
-- Patterns (Learning patterns from interactions)
|
||||
-- =============================================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS patterns (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
pattern_type VARCHAR(50) NOT NULL, -- intent, response, workflow
|
||||
pattern_key VARCHAR(255) NOT NULL,
|
||||
pattern_value JSONB NOT NULL,
|
||||
confidence FLOAT DEFAULT 0.5,
|
||||
usage_count INTEGER DEFAULT 0,
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(tenant_id, pattern_type, pattern_key)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_patterns_tenant ON patterns(tenant_id);
|
||||
CREATE INDEX idx_patterns_type ON patterns(pattern_type);
|
||||
CREATE INDEX idx_patterns_confidence ON patterns(confidence DESC);
|
||||
|
||||
ALTER TABLE patterns ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- =============================================================================
|
||||
-- Functions
|
||||
-- =============================================================================
|
||||
|
||||
-- Update timestamp trigger
|
||||
CREATE OR REPLACE FUNCTION update_updated_at()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
NEW.updated_at = CURRENT_TIMESTAMP;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
-- Apply to all tables with updated_at
|
||||
DO $$
|
||||
DECLARE
|
||||
t text;
|
||||
BEGIN
|
||||
FOR t IN
|
||||
SELECT table_name
|
||||
FROM information_schema.columns
|
||||
WHERE column_name = 'updated_at'
|
||||
AND table_schema = 'public'
|
||||
LOOP
|
||||
EXECUTE format('
|
||||
DROP TRIGGER IF EXISTS update_%I_updated_at ON %I;
|
||||
CREATE TRIGGER update_%I_updated_at
|
||||
BEFORE UPDATE ON %I
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION update_updated_at();
|
||||
', t, t, t, t);
|
||||
END LOOP;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
-- =============================================================================
|
||||
-- Default Data
|
||||
-- =============================================================================
|
||||
|
||||
-- Default tenant for development
|
||||
INSERT INTO tenants (id, name, slug, settings)
|
||||
VALUES (
|
||||
'00000000-0000-0000-0000-000000000001',
|
||||
'Default Tenant',
|
||||
'default',
|
||||
'{"plan": "free", "features": ["basic_chat", "memory", "skills"]}'
|
||||
)
|
||||
ON CONFLICT (slug) DO NOTHING;
|
||||
|
||||
-- Default agent
|
||||
INSERT INTO agents (id, tenant_id, name, type, model, system_prompt, config)
|
||||
VALUES (
|
||||
'00000000-0000-0000-0000-000000000001',
|
||||
'00000000-0000-0000-0000-000000000001',
|
||||
'RuvBot',
|
||||
'assistant',
|
||||
'claude-3-5-sonnet',
|
||||
'You are RuvBot, a helpful AI assistant with long-term memory and learning capabilities.',
|
||||
'{"temperature": 0.7, "maxTokens": 4096}'
|
||||
)
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
-- =============================================================================
|
||||
-- Grants (for application user)
|
||||
-- =============================================================================
|
||||
|
||||
-- Note: Run these after creating the application user
|
||||
-- GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO ruvbot;
|
||||
-- GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO ruvbot;
|
||||
-- GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO ruvbot;
|
||||
Reference in New Issue
Block a user