#!/usr/bin/env bash set -euo pipefail # Fail fast on broken Space metadata, duplicate templates, or stale cache artifacts. python3 /home/user/app/scripts/preflight.py # ============================================================ # Required non-model settings # ============================================================ : "${MARINE_API_URL:?Missing MARINE_API_URL variable}" # ============================================================ # Model key # # We do NOT require or use OPENCODE_API_KEY. # Prefer the dedicated OpenCode Go secret. # Fall back to OPENAI_API_KEY only if you chose to store the same # OpenCode Go key under that name in Hugging Face. # ============================================================ MODEL_API_KEY="${OPENCODE_API_KEY:-${OPENAI_API_KEY:-}}" if [ -z "${MODEL_API_KEY}" ]; then echo "[startup] ERROR: no OpenCode Go key was injected." echo "[startup] Expected: OPENCODE_API_KEY or OPENAI_API_KEY" echo "[startup] Available environment variable names containing KEY/API:" env | cut -d= -f1 | grep -E 'KEY|API' | sort || true exit 1 fi # ============================================================ # Official OpenAI Codex CLI runtime # ============================================================ export OPENAI_API_KEY="${MODEL_API_KEY}" # OpenCode is an OpenAI-compatible provider for Codex CLI export OPENAI_BASE_URL="${OPENCODE_BASE_URL:-${OPENAI_BASE_URL:-}}" export CODEX_MODEL="${CODEX_MODEL:-gpt-5-codex}" # ============================================================ # Web / Runtime # ============================================================ export PORT="${PORT:-7860}" export FISHERIES_EXPORT_ROOT="${FISHERIES_EXPORT_ROOT:-/tmp/squid_fisheries_exports}" export HF_FISHERIES_CACHE_ROOT="${HF_FISHERIES_CACHE_ROOT:-/tmp/squid_hf_fisheries_cache}" if [ -z "${PUBLIC_BASE_URL:-}" ] && [ -n "${SPACE_HOST:-}" ]; then export PUBLIC_BASE_URL="https://${SPACE_HOST}" fi # ============================================================ # Build private Marine MCP runtime configuration # ============================================================ RUNTIME_MCP_CONFIG="/tmp/codex-marine-mcp.json" export RUNTIME_MCP_CONFIG python3 - <<'PY_MCP_CONFIG' import json import os from pathlib import Path env = { "MARINE_API_URL": os.environ["MARINE_API_URL"], "HF_SQUID_DATASET_REPO": ( os.environ.get("HF_SQUID_DATASET_REPO") or os.environ.get("HF_DATASET_REPO") or "globalsquiddatabase/squid_dataset" ), "HF_TUNA_DATASET_REPO": ( os.environ.get("HF_TUNA_DATASET_REPO") or "globalsquiddatabase/Tuna-Fisheries-Dataset" ), "FISHERIES_EXPORT_ROOT": os.environ.get( "FISHERIES_EXPORT_ROOT", "/tmp/squid_fisheries_exports" ), "HF_FISHERIES_CACHE_ROOT": os.environ.get( "HF_FISHERIES_CACHE_ROOT", "/tmp/squid_hf_fisheries_cache" ), "HF_SQUID_DATASET_REVISION": ( os.environ.get("HF_SQUID_DATASET_REVISION") or os.environ.get("HF_DATASET_REVISION", "") ), "HF_TUNA_DATASET_REVISION": os.environ.get("HF_TUNA_DATASET_REVISION", ""), "PUBLIC_BASE_URL": os.environ.get("PUBLIC_BASE_URL", ""), } hf_token = os.environ.get("HF_TOKEN", "").strip() if hf_token: env["HF_TOKEN"] = hf_token cfg = { "timeouts": { "connect_timeout": 15, "execute_timeout": 900, "read_timeout": 900, }, "servers": { "marine": { "command": "python3", "args": ["/home/user/app/marine_mcp.py"], "disabled": False, "required": False, "env": env, } }, } p = Path(os.environ["RUNTIME_MCP_CONFIG"]) p.write_text( json.dumps(cfg, ensure_ascii=False, indent=2) + "\n", encoding="utf-8", ) p.chmod(0o600) print("[startup] private Marine MCP runtime config ready") PY_MCP_CONFIG # ============================================================ # Marine API health check # ============================================================ curl -fsS --max-time 12 "${MARINE_API_URL%/}/health" || true echo # ============================================================ # Start Squid Agent Web UI # ============================================================ exec uvicorn ui_server:app \ --host 0.0.0.0 \ --port "${PORT}" \ --proxy-headers