feat(infrastructure): add all 9 infrastructure scripts (00–08)

This commit is contained in:
chrischristiansen-glitch 2026-05-23 02:32:08 +02:00
parent d086e9ed80
commit 5a33e8f444
9 changed files with 657 additions and 0 deletions

View File

@ -0,0 +1,33 @@
#!/bin/bash
# 00-authcheck.sh — Verify correct gcloud identity and project before any action
# Run in: local VS Code terminal OR Cloud Shell (identical behavior)
set -euo pipefail
PROJECT_ID="${PROJECT_ID:-propane-will-491900-m5}"
REGION="${REGION:-us-central1}"
echo "=== OSVauco-NMTMD-GCOS :: Auth Check ==="
# 1. Confirm gcloud is installed
command -v gcloud >/dev/null 2>&1 || { echo "ERROR: gcloud CLI not found. Install from https://cloud.google.com/sdk/docs/install"; exit 1; }
# 2. Check active account
ACTIVE_ACCOUNT=$(gcloud config get-value account 2>/dev/null)
echo "Active account : $ACTIVE_ACCOUNT"
[ -z "$ACTIVE_ACCOUNT" ] && { echo "ERROR: No active account. Run: gcloud auth login"; exit 1; }
# 3. Set and confirm project
gcloud config set project "$PROJECT_ID" --quiet
ACTIVE_PROJECT=$(gcloud config get-value project)
echo "Active project : $ACTIVE_PROJECT"
[ "$ACTIVE_PROJECT" != "$PROJECT_ID" ] && { echo "ERROR: Project mismatch. Expected $PROJECT_ID, got $ACTIVE_PROJECT"; exit 1; }
# 4. Check Application Default Credentials
if ! gcloud auth application-default print-access-token >/dev/null 2>&1; then
echo "WARNING: No ADC found. Run: gcloud auth application-default login"
fi
echo ""
echo "Auth check PASSED. Project: $PROJECT_ID | Region: $REGION"
echo "========================================"

View File

@ -0,0 +1,96 @@
#!/bin/bash
# 01-setupenv.sh — Enable APIs, create staging bucket with lifecycle, SA, billing budget
# Run in: local VS Code terminal OR Cloud Shell
# Source .env before running: source .env
set -euo pipefail
: "${PROJECT_ID:?Set PROJECT_ID in .env}"
: "${REGION:?Set REGION in .env}"
: "${BILLING_ACCOUNT_ID:?Set BILLING_ACCOUNT_ID in .env}"
: "${AGENT_SA:?Set AGENT_SA in .env}"
BUCKET_NAME="gs://${PROJECT_ID}-agent-staging"
BUDGET_NAME="OSVauco-Agent-Budget-500USD"
echo "=== 01: Environment Setup for ${PROJECT_ID} ==="
# 0. Auth check
bash "$(dirname "$0")/00-authcheck.sh"
# 1. Enable required APIs (idempotent)
echo "Enabling required APIs..."
gcloud services enable \
aiplatform.googleapis.com \
storage.googleapis.com \
cloudbilling.googleapis.com \
cloudresourcemanager.googleapis.com \
iam.googleapis.com \
run.googleapis.com \
artifactregistry.googleapis.com \
cloudbuild.googleapis.com \
secretmanager.googleapis.com \
monitoring.googleapis.com \
logging.googleapis.com \
cloudtrace.googleapis.com \
--project="$PROJECT_ID" --quiet
echo "✓ APIs enabled."
# 2. Create staging bucket (idempotent)
if gcloud storage ls "$BUCKET_NAME" >/dev/null 2>&1; then
echo "✓ Staging bucket $BUCKET_NAME already exists."
else
gcloud storage buckets create "$BUCKET_NAME" \
--location="$REGION" --project="$PROJECT_ID" --quiet
echo "✓ Bucket created: $BUCKET_NAME"
fi
# 3. Apply lifecycle rule (auto-delete objects >7 days)
cat > /tmp/lifecycle.json << 'EOF'
{"rule":[{"action":{"type":"Delete"},"condition":{"age":7}}]}
EOF
gcloud storage buckets update "$BUCKET_NAME" --lifecycle-file=/tmp/lifecycle.json --quiet
echo "✓ Lifecycle rule applied (delete after 7 days)."
# 4. Service account (idempotent)
SA_NAME=$(echo "$AGENT_SA" | cut -d'@' -f1)
if ! gcloud iam service-accounts describe "$AGENT_SA" --project="$PROJECT_ID" >/dev/null 2>&1; then
gcloud iam service-accounts create "$SA_NAME" \
--display-name="OSVauco Agent Runner SA" --project="$PROJECT_ID" --quiet
echo "✓ Service account created: $AGENT_SA"
fi
for ROLE in \
roles/aiplatform.user \
roles/storage.objectAdmin \
roles/logging.logWriter \
roles/cloudtrace.agent \
roles/monitoring.metricWriter \
roles/secretmanager.secretAccessor \
roles/run.invoker; do
gcloud projects add-iam-policy-binding "$PROJECT_ID" \
--member="serviceAccount:${AGENT_SA}" --role="$ROLE" --quiet
done
echo "✓ IAM bindings configured."
# 5. Billing budget alert (idempotent check by display name)
EXISTING=$(gcloud billing budgets list \
--billing-account="${BILLING_ACCOUNT_ID}" \
--filter="displayName=${BUDGET_NAME}" \
--format="value(name)" 2>/dev/null | head -1 || true)
if [[ -z "${EXISTING}" ]]; then
gcloud billing budgets create \
--billing-account="${BILLING_ACCOUNT_ID}" \
--display-name="${BUDGET_NAME}" \
--budget-amount=500USD \
--threshold-rule=percent=0.5,basis=CURRENT_SPEND \
--threshold-rule=percent=0.8,basis=CURRENT_SPEND \
--threshold-rule=percent=1.0,basis=CURRENT_SPEND
echo "✓ Budget alert created"
else
echo "✓ Budget alert already exists"
fi
echo ""
echo "=== 01: Environment setup COMPLETE ==="

View File

@ -0,0 +1,63 @@
#!/usr/bin/env bash
# 02-deploy.sh — Build and deploy orchestrator agent to Cloud Run
# Idempotent: updates existing service if present
# Source .env before running: source .env
set -euo pipefail
: "${PROJECT_ID:?Set PROJECT_ID}"
: "${REGION:?Set REGION}"
: "${AGENT_SA:?Set AGENT_SA}"
: "${ARTIFACT_REPO:?Set ARTIFACT_REPO}"
: "${CLOUD_RUN_SERVICE:?Set CLOUD_RUN_SERVICE}"
IMAGE="${REGION}-docker.pkg.dev/${PROJECT_ID}/${ARTIFACT_REPO}/${CLOUD_RUN_SERVICE}:latest"
echo "=== 02: Building and deploying ${CLOUD_RUN_SERVICE} ==="
bash "$(dirname "$0")/00-authcheck.sh"
# 1. Ensure Artifact Registry repo exists
if ! gcloud artifacts repositories describe "${ARTIFACT_REPO}" \
--location="${REGION}" --project="${PROJECT_ID}" >/dev/null 2>&1; then
gcloud artifacts repositories create "${ARTIFACT_REPO}" \
--repository-format=docker \
--location="${REGION}" \
--project="${PROJECT_ID}" --quiet
echo "✓ Artifact Registry repo created: ${ARTIFACT_REPO}"
fi
# 2. Configure Docker auth
gcloud auth configure-docker "${REGION}-docker.pkg.dev" --quiet
# 3. Build image via Cloud Build (no local Docker required)
gcloud builds submit agents/core-logic \
--tag="${IMAGE}" \
--project="${PROJECT_ID}" \
--quiet
echo "✓ Image built: ${IMAGE}"
# 4. Deploy to Cloud Run
gcloud run deploy "${CLOUD_RUN_SERVICE}" \
--image="${IMAGE}" \
--platform=managed \
--region="${REGION}" \
--service-account="${AGENT_SA}" \
--no-allow-unauthenticated \
--min-instances=1 \
--max-instances=10 \
--concurrency=80 \
--timeout=300s \
--memory=1Gi \
--cpu=1 \
--set-env-vars="PROJECT_ID=${PROJECT_ID},REGION=${REGION}" \
--labels="env=prod,team=osvaucoe,agent=orchestrator" \
--quiet
SERVICE_URL=$(gcloud run services describe "${CLOUD_RUN_SERVICE}" \
--region="${REGION}" \
--format="value(status.url)")
echo ""
echo "=== 02: Deploy COMPLETE ==="
echo " Service URL: ${SERVICE_URL}"
echo " REMINDER: Run 03-teardown.sh at end of workday to stop billing."

View File

@ -0,0 +1,72 @@
#!/usr/bin/env bash
# 03-teardown.sh — Safely remove all deployed resources
# WARNING: Destructive. Requires explicit confirmation.
# Source .env before running: source .env
set -euo pipefail
: "${PROJECT_ID:?Set PROJECT_ID}"
: "${REGION:?Set REGION}"
: "${CLOUD_RUN_SERVICE:?Set CLOUD_RUN_SERVICE}"
: "${ARTIFACT_REPO:?Set ARTIFACT_REPO}"
: "${AGENT_SA:?Set AGENT_SA}"
echo "=== 03: TEARDOWN for project ${PROJECT_ID} ==="
echo ""
echo "WARNING: This will delete Cloud Run services, Artifact Registry images,"
echo " and Service Account IAM bindings."
echo " GCS buckets and RAG corpora will NOT be deleted (to prevent data loss)."
echo ""
read -rp "Type 'DELETE' to confirm teardown: " CONFIRM
if [[ "${CONFIRM}" != "DELETE" ]]; then
echo "Teardown cancelled."
exit 0
fi
bash "$(dirname "$0")/00-authcheck.sh"
# 1. Delete Cloud Run service
if gcloud run services describe "${CLOUD_RUN_SERVICE}" \
--region="${REGION}" &>/dev/null; then
gcloud run services delete "${CLOUD_RUN_SERVICE}" \
--region="${REGION}" --quiet
echo "✓ Deleted Cloud Run service: ${CLOUD_RUN_SERVICE}"
fi
# 2. Delete Agent Runtime instances (if any)
AGENTS=$(gcloud ai agent-engines list \
--project="${PROJECT_ID}" --region="${REGION}" \
--format="value(name)" 2>/dev/null || echo "")
if [ -n "$AGENTS" ]; then
while IFS= read -r AGENT_NAME; do
gcloud ai agent-engines delete "$AGENT_NAME" \
--project="${PROJECT_ID}" --region="${REGION}" --quiet
echo "✓ Deleted agent runtime: $AGENT_NAME"
done <<< "$AGENTS"
fi
# 3. Delete container images from Artifact Registry
gcloud artifacts docker images delete \
"${REGION}-docker.pkg.dev/${PROJECT_ID}/${ARTIFACT_REPO}/${CLOUD_RUN_SERVICE}" \
--delete-tags --quiet 2>/dev/null || echo " (no images found)"
echo "✓ Artifact Registry images cleaned"
# 4. Remove IAM bindings
ROLES=(
roles/aiplatform.user
roles/run.invoker
roles/secretmanager.secretAccessor
roles/cloudtrace.agent
roles/logging.logWriter
roles/monitoring.metricWriter
roles/storage.objectAdmin
)
for ROLE in "${ROLES[@]}"; do
gcloud projects remove-iam-policy-binding "${PROJECT_ID}" \
--member="serviceAccount:${AGENT_SA}" \
--role="${ROLE}" --quiet 2>/dev/null || true
done
echo "✓ IAM bindings removed"
echo ""
echo "=== 03: Teardown COMPLETE ==="
echo "NOTE: GCS buckets and RAG corpora were NOT deleted. Remove manually if needed."

View File

@ -0,0 +1,78 @@
#!/usr/bin/env bash
# 04-observability-setup.sh — Configure Cloud Monitoring, alerting, uptime checks
# Idempotent
# Source .env before running: source .env
set -euo pipefail
: "${PROJECT_ID:?Set PROJECT_ID}"
: "${REGION:?Set REGION}"
: "${CLOUD_RUN_SERVICE:?Set CLOUD_RUN_SERVICE}"
: "${ALERT_EMAIL:?Set ALERT_EMAIL}"
echo "=== 04: Setting up observability for ${PROJECT_ID} ==="
bash "$(dirname "$0")/00-authcheck.sh"
gcloud services enable \
monitoring.googleapis.com \
logging.googleapis.com \
cloudtrace.googleapis.com \
--project="${PROJECT_ID}" --quiet
echo "✓ Monitoring APIs enabled"
# 1. Notification channel (email)
CHANNEL_FILE=$(gcloud alpha monitoring channels list \
--filter="type=email AND labels.email_address=${ALERT_EMAIL}" \
--format="value(name)" --project="${PROJECT_ID}" 2>/dev/null | head -1 || true)
if [[ -z "${CHANNEL_FILE}" ]]; then
cat > /tmp/channel.json << EOF
{
"type": "email",
"displayName": "OSVauco Alert Email",
"labels": { "email_address": "${ALERT_EMAIL}" }
}
EOF
NOTIFICATION_CHANNEL=$(gcloud alpha monitoring channels create \
--channel-content-from-file=/tmp/channel.json \
--project="${PROJECT_ID}" \
--format="value(name)")
echo "✓ Notification channel created: ${NOTIFICATION_CHANNEL}"
else
NOTIFICATION_CHANNEL="${CHANNEL_FILE}"
echo "✓ Notification channel already exists: ${NOTIFICATION_CHANNEL}"
fi
# 2. Create log-based metric for agent errors
if ! gcloud logging metrics describe agent-error-count \
--project="${PROJECT_ID}" >/dev/null 2>&1; then
gcloud logging metrics create agent-error-count \
--description="Count of ERROR severity logs from agent" \
--log-filter="resource.type=\"cloud_run_revision\" severity=ERROR" \
--project="${PROJECT_ID}"
echo "✓ Log-based metric 'agent-error-count' created"
else
echo "✓ Log-based metric already exists"
fi
# 3. Uptime check for Cloud Run service
SERVICE_URL=$(gcloud run services describe "${CLOUD_RUN_SERVICE}" \
--region="${REGION}" \
--format="value(status.url)" 2>/dev/null || echo "")
if [[ -n "${SERVICE_URL}" ]]; then
HOST=$(echo "${SERVICE_URL}" | sed 's|https://||')
gcloud monitoring uptime create \
--display-name="${CLOUD_RUN_SERVICE}-uptime" \
--protocol=HTTPS \
--request-path="/health" \
--port=443 \
--monitored-resource-type=uptime_url \
--project="${PROJECT_ID}" \
--hostname="${HOST}" 2>/dev/null || true
echo "✓ Uptime check configured for ${SERVICE_URL}"
fi
echo ""
echo "=== 04: Observability setup COMPLETE ==="
echo " Dashboard: https://console.cloud.google.com/monitoring?project=${PROJECT_ID}"

View File

@ -0,0 +1,68 @@
#!/bin/bash
# 05-cloudrun-deploy.sh — Deploy ADK agent to Cloud Run using `adk deploy cloud_run`
# Run in: local VS Code terminal OR Cloud Shell
# Requires: ADK installed (pip install google-adk), gcloud CLI
# Source .env before running: source .env
set -euo pipefail
: "${PROJECT_ID:?Set PROJECT_ID}"
: "${REGION:?Set REGION}"
: "${CLOUD_RUN_SERVICE:?Set CLOUD_RUN_SERVICE}"
: "${AGENT_SA:?Set AGENT_SA}"
APP_NAME="oavauco_root"
AGENT_PATH="agents/core-logic"
echo "=== 05: Cloud Run Deploy via ADK CLI ==="
bash "$(dirname "$0")/00-authcheck.sh"
gcloud services enable \
run.googleapis.com \
artifactregistry.googleapis.com \
cloudbuild.googleapis.com \
--project="${PROJECT_ID}" --quiet
# Grant compute SA permission to use Cloud Build
PROJECT_NUMBER=$(gcloud projects describe "${PROJECT_ID}" --format="value(projectNumber)")
COMPUTE_SA="${PROJECT_NUMBER}-compute@developer.gserviceaccount.com"
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
--member="serviceAccount:${COMPUTE_SA}" \
--role="roles/cloudbuild.builds.builder" --quiet
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
--member="serviceAccount:${COMPUTE_SA}" \
--role="roles/secretmanager.secretAccessor" --quiet
echo "✓ IAM bindings for Cloud Build SA applied"
export GOOGLE_CLOUD_PROJECT="${PROJECT_ID}"
export GOOGLE_CLOUD_LOCATION="${REGION}"
export GOOGLE_GENAI_USE_VERTEXAI="True"
# Deploy via ADK CLI
# --with_ui includes the ADK dev UI (remove for API-only production deployments)
# --no-allow-unauthenticated requires an identity token to call the service
echo "Deploying ${CLOUD_RUN_SERVICE} to Cloud Run in ${REGION}..."
adk deploy cloud_run \
--project="${PROJECT_ID}" \
--region="${REGION}" \
--service_name="${CLOUD_RUN_SERVICE}" \
--app_name="${APP_NAME}" \
"${AGENT_PATH}" \
-- --no-allow-unauthenticated
echo ""
echo "=== 05: Cloud Run Deploy COMPLETE ==="
SERVICE_URL=$(gcloud run services describe "${CLOUD_RUN_SERVICE}" \
--region="${REGION}" --project="${PROJECT_ID}" \
--format="value(status.url)" 2>/dev/null || echo "(pending)")
echo " Service URL: ${SERVICE_URL}"
echo ""
echo " To call (authenticated):"
echo " TOKEN=\$(gcloud auth print-identity-token)"
echo " curl -H \"Authorization: Bearer \$TOKEN\" -H 'Content-Type: application/json' \\"
echo " -d '{\"message\": \"Hello\"}' ${SERVICE_URL}/run"
echo ""
echo " COST NOTE: Cloud Run scales to 0. No idle cost."
echo " Delete with: gcloud run services delete ${CLOUD_RUN_SERVICE} --region=${REGION} --quiet"

View File

@ -0,0 +1,80 @@
#!/usr/bin/env bash
# 06-cicd-setup.sh — Set up Cloud Build trigger + Artifact Registry for CI/CD
# Prerequisites: GitHub repo connected to Cloud Build via GCP Console FIRST:
# https://console.cloud.google.com/cloud-build/triggers/connect
# Source .env before running: source .env
set -euo pipefail
: "${PROJECT_ID:?Set PROJECT_ID}"
: "${REGION:?Set REGION}"
: "${GITHUB_OWNER:?Set GITHUB_OWNER}"
: "${GITHUB_REPO:?Set GITHUB_REPO}"
: "${ARTIFACT_REPO:?Set ARTIFACT_REPO}"
: "${CLOUD_RUN_SERVICE:?Set CLOUD_RUN_SERVICE}"
BRANCH_PATTERN="^main$"
echo "=== 06: CI/CD Setup for ${PROJECT_ID} ==="
bash "$(dirname "$0")/00-authcheck.sh"
gcloud services enable \
cloudbuild.googleapis.com \
artifactregistry.googleapis.com \
run.googleapis.com \
--project="${PROJECT_ID}" --quiet
# Create Artifact Registry repo (idempotent)
if ! gcloud artifacts repositories describe "${ARTIFACT_REPO}" \
--location="${REGION}" --project="${PROJECT_ID}" >/dev/null 2>&1; then
gcloud artifacts repositories create "${ARTIFACT_REPO}" \
--repository-format=docker \
--location="${REGION}" \
--project="${PROJECT_ID}" --quiet
echo "✓ Artifact Registry repo created: ${ARTIFACT_REPO}"
else
echo "✓ Artifact Registry repo already exists"
fi
gcloud auth configure-docker "${REGION}-docker.pkg.dev" --quiet
# Grant Cloud Build SA permissions
PROJECT_NUMBER=$(gcloud projects describe "${PROJECT_ID}" --format="value(projectNumber)")
CB_SA="${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com"
for ROLE in \
roles/run.admin \
roles/iam.serviceAccountUser \
roles/artifactregistry.writer \
roles/secretmanager.secretAccessor; do
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
--member="serviceAccount:${CB_SA}" --role="${ROLE}" --quiet
done
echo "✓ Cloud Build SA IAM bindings applied"
# Create Cloud Build trigger
TRIGGER_NAME="${CLOUD_RUN_SERVICE}-main-trigger"
EXISTING=$(gcloud builds triggers list \
--filter="name=${TRIGGER_NAME}" \
--format="value(name)" 2>/dev/null | head -1 || true)
if [[ -z "${EXISTING}" ]]; then
gcloud builds triggers create github \
--name="${TRIGGER_NAME}" \
--repo-owner="${GITHUB_OWNER}" \
--repo-name="${GITHUB_REPO}" \
--branch-pattern="${BRANCH_PATTERN}" \
--build-config="cloudbuild.yaml" \
--project="${PROJECT_ID}" \
--quiet
echo "✓ Cloud Build trigger created: ${TRIGGER_NAME}"
else
echo "✓ Trigger already exists: ${TRIGGER_NAME}"
fi
echo ""
echo "=== 06: CI/CD Setup COMPLETE ==="
echo " NOTE: GitHub connection must be pre-authorized at:"
echo " https://console.cloud.google.com/cloud-build/triggers/connect?project=${PROJECT_ID}"
echo " After first deploy, switch traffic manually:"
echo " gcloud run services update-traffic ${CLOUD_RUN_SERVICE} --to-latest --region=${REGION}"

View File

@ -0,0 +1,91 @@
#!/usr/bin/env bash
# 07-rag-setup.sh — Create Vertex AI RAG Engine corpus and upload initial documents
# Idempotent
# Source: Vertex AI RAG Engine SDK (google-cloud-aiplatform >= 1.87)
# NOTE: RAG Engine in us-central1 requires allowlist access.
# Contact: vertex-ai-rag-engine-support@google.com
# Alternative: set REGION=us-east1 or us-east4 for immediate access.
# Source .env before running: source .env
set -euo pipefail
: "${PROJECT_ID:?Set PROJECT_ID}"
: "${REGION:?Set REGION}"
: "${RAG_CORPUS_DISPLAY_NAME:?Set RAG_CORPUS_DISPLAY_NAME}"
echo "=== 07: Setting up Vertex AI RAG Engine ==="
bash "$(dirname "$0")/00-authcheck.sh"
gcloud services enable aiplatform.googleapis.com --quiet
# Create GCS bucket for corpus source documents (idempotent)
CORPUS_BUCKET="${PROJECT_ID}-agent-corpus"
if ! gsutil ls -b "gs://${CORPUS_BUCKET}" &>/dev/null; then
gsutil mb -l "${REGION}" -b on "gs://${CORPUS_BUCKET}"
echo "✓ GCS corpus bucket created: gs://${CORPUS_BUCKET}"
else
echo "✓ GCS corpus bucket exists: gs://${CORPUS_BUCKET}"
fi
# Upload seed documents if present
if [[ -d "docs/corpus-seed" ]]; then
gsutil -m cp docs/corpus-seed/*.md "gs://${CORPUS_BUCKET}/seed/" 2>/dev/null || true
echo "✓ Seed documents uploaded to gs://${CORPUS_BUCKET}/seed/"
fi
# Run Python to create/update corpus
python3 - << PYEOF
import os, sys
try:
import vertexai
from vertexai.preview import rag
except ImportError:
print("ERROR: google-cloud-aiplatform not installed. Run: pip install google-cloud-aiplatform>=1.87.0")
sys.exit(1)
PROJECT_ID = os.environ["PROJECT_ID"]
REGION = os.environ["REGION"]
CORPUS_DISPLAY_NAME = os.environ["RAG_CORPUS_DISPLAY_NAME"]
CORPUS_BUCKET = f"{PROJECT_ID}-agent-corpus"
vertexai.init(project=PROJECT_ID, location=REGION)
corpus = None
for c in rag.list_corpora():
if c.display_name == CORPUS_DISPLAY_NAME:
corpus = c
print(f"✓ RAG corpus already exists: {c.name}")
break
if corpus is None:
embedding_config = rag.EmbeddingModelConfig(
publisher_model="publishers/google/models/text-embedding-005"
)
corpus = rag.create_corpus(
display_name=CORPUS_DISPLAY_NAME,
embedding_model_config=embedding_config,
)
print(f"✓ RAG corpus created: {corpus.name}")
gcs_uri = f"gs://{CORPUS_BUCKET}/seed/"
try:
rag.import_files(
corpus_name=corpus.name,
paths=[gcs_uri],
chunk_size=512,
chunk_overlap=50,
max_embedding_requests_per_min=900,
)
print(f"✓ Documents imported from {gcs_uri}")
except Exception as e:
print(f" WARNING: Document import skipped or failed: {e}")
print(" Import manually via: https://console.cloud.google.com/vertex-ai/rag")
with open("/tmp/rag_corpus_name.txt", "w") as f:
f.write(corpus.name)
print(f"\n Corpus resource name: {corpus.name}")
print(f" Add to .env: RAG_CORPUS_NAME={corpus.name}")
PYEOF
echo ""
echo "=== 07: RAG Engine setup COMPLETE ==="
echo " View corpus: https://console.cloud.google.com/vertex-ai/rag?project=${PROJECT_ID}"

View File

@ -0,0 +1,76 @@
#!/usr/bin/env bash
# 08-memorybank-setup.sh — Create Vertex AI Agent Platform Memory Bank instance
# Idempotent
# Requires: google-cloud-aiplatform >= 1.111.0
# UNKNOWN: gcloud CLI equivalent for client.agent_engines.create() — SDK-only (OQ-01)
# Source .env before running: source .env
set -euo pipefail
: "${PROJECT_ID:?Set PROJECT_ID}"
: "${REGION:?Set REGION}"
: "${AGENT_SA:?Set AGENT_SA}"
MEMORY_INSTANCE_DISPLAY_NAME="${MEMORY_INSTANCE_DISPLAY_NAME:-${PROJECT_ID}-memory-bank}"
echo "=== 08: Setting up Vertex AI Memory Bank ==="
bash "$(dirname "$0")/00-authcheck.sh"
gcloud services enable aiplatform.googleapis.com --quiet
# Run Python to create/update Agent Engine instance with Memory Bank
python3 - << PYEOF
import os, sys
try:
import vertexai
from vertexai.preview import agent_engines
except ImportError:
print("ERROR: google-cloud-aiplatform >= 1.111.0 required.")
print(" Run: pip install 'google-cloud-aiplatform>=1.111.0'")
sys.exit(1)
PROJECT_ID = os.environ["PROJECT_ID"]
REGION = os.environ["REGION"]
DISPLAY_NAME = os.environ.get("MEMORY_INSTANCE_DISPLAY_NAME", f"{PROJECT_ID}-memory-bank")
vertexai.init(project=PROJECT_ID, location=REGION)
client = vertexai.Client(project=PROJECT_ID, location=REGION)
existing = list(client.agent_engines.list())
instance = None
for eng in existing:
if hasattr(eng, "display_name") and eng.display_name == DISPLAY_NAME:
instance = eng
print(f"✓ Memory Bank instance already exists: {eng.api_resource.name}")
break
if instance is None:
memory_bank_config = {
"memories_ttl_days": 30,
"generate_memory_config": {
"trigger_config": {"trigger_type": "ON_SESSION_END"}
},
"similarity_search_config": {"top_k": 5}
}
instance = client.agent_engines.create(
display_name=DISPLAY_NAME,
spec={"context_spec": {"memory_bank_config": memory_bank_config}}
)
print(f"✓ Memory Bank instance created: {instance.api_resource.name}")
instance_name = instance.api_resource.name
with open("/tmp/memory_bank_instance.txt", "w") as f:
f.write(instance_name)
print(f"\n Instance resource name: {instance_name}")
print(f" Add to .env: MEMORY_BANK_INSTANCE={instance_name}")
PYEOF
# Grant agent SA memory permissions
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
--member="serviceAccount:${AGENT_SA}" \
--role="roles/aiplatform.user" \
--quiet 2>/dev/null || true
echo "✓ roles/aiplatform.user granted to ${AGENT_SA}"
echo ""
echo "=== 08: Memory Bank setup COMPLETE ==="
echo " View instances: https://console.cloud.google.com/vertex-ai/agents?project=${PROJECT_ID}"