Built the Sentinel Tab

This commit is contained in:
Sagnik
2026-04-12 02:02:58 +05:30
parent fb656d1443
commit 075ab280ad
526 changed files with 17646 additions and 70931 deletions

View File

@@ -0,0 +1,40 @@
"""
Bridge OCR/plate-recognition output into the Velocity CCTV ingestion API.
Usage:
python backend/scripts/cctv_ocr_bridge.py --api-base https://host --session-id <uuid> payload.json
"""
from __future__ import annotations
import argparse
import json
from pathlib import Path
import httpx
def main() -> int:
parser = argparse.ArgumentParser(description='Forward OCR bridge payloads to Velocity CCTV API.')
parser.add_argument('payload', type=Path, help='Path to a JSON payload file from the OCR bridge.')
parser.add_argument('--api-base', default='http://127.0.0.1:8000', help='Velocity API base URL.')
parser.add_argument('--session-id', default=None, help='Optional auto mode perception session UUID.')
parser.add_argument('--token', default=None, help='Optional bearer token for protected ingestion.')
args = parser.parse_args()
body = json.loads(args.payload.read_text(encoding='utf-8'))
if args.session_id:
body['session_id'] = args.session_id
headers = {'Content-Type': 'application/json'}
if args.token:
headers['Authorization'] = f'Bearer {args.token}'
response = httpx.post(f"{args.api_base.rstrip('/')}/api/cctv/event", json=body, headers=headers, timeout=30.0)
response.raise_for_status()
print(json.dumps(response.json(), indent=2))
return 0
if __name__ == '__main__':
raise SystemExit(main())

View File

@@ -0,0 +1,394 @@
#!/usr/bin/env bash
# =============================================================================
# nemoclaw_deploy.sh
# Deploys NemoClaw on the AWS G6.12xlarge instance.
# - All data/install paths on NVMe (/opt/dlami/nvme/)
# - Configures OpenShell to use existing Ollama (qwen3.5:27b, port 11434)
# - GPUs 0+1 are Ollama's. Do NOT reassign them.
# - ComfyUI owns GPUs 2+3. Do NOT touch.
# - Creates a systemd service for the NemoClaw gateway.
# =============================================================================
set -euo pipefail
NVME="/opt/dlami/nvme"
AGENT_NAME="velocity-sentinel"
OLLAMA_URL="http://127.0.0.1:11434"
OLLAMA_MODEL="qwen3.5:27b"
OPENCLAW_PORT=8080 # Port our FastAPI backend targets
echo "================================================================"
echo " Project Velocity — NemoClaw + OpenShell Deploy Script"
echo " Instance: G6.12xlarge | NVMe: $NVME"
echo "================================================================"
# ──────────────────────────────────────────────────────────────────
# 0. Safety checks
# ──────────────────────────────────────────────────────────────────
if [ "$(id -u)" -ne 0 ]; then
echo "[ERROR] Run as root or with sudo"; exit 1
fi
if ! mountpoint -q "$NVME" 2>/dev/null && [ ! -d "$NVME" ]; then
echo "[WARN] NVMe not mounted at $NVME — using /home/ubuntu/nvme as fallback"
NVME="/home/ubuntu/nvme"
mkdir -p "$NVME"
fi
echo "[✓] NVMe target: $NVME"
# Confirm Ollama is alive before proceeding
if ! curl -sf "$OLLAMA_URL/api/tags" | grep -q "qwen"; then
echo "[WARN] Ollama at $OLLAMA_URL doesn't show qwen3.5:27b yet — proceeding anyway"
else
echo "[✓] Ollama confirmed running with qwen3.5:27b"
fi
# ──────────────────────────────────────────────────────────────────
# 1. Node.js 22 (NemoClaw requirement: >=22.16)
# ──────────────────────────────────────────────────────────────────
echo ""
echo "[1/7] Installing Node.js 22..."
NODE_VERSION=$(node --version 2>/dev/null | sed 's/v//' | cut -d. -f1 || echo "0")
if [ "$NODE_VERSION" -ge 22 ]; then
echo "[✓] Node.js $(node --version) already installed"
else
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
apt-get install -y nodejs
echo "[✓] Node.js $(node --version) installed"
fi
npm --version
echo "[✓] npm $(npm --version)"
# ──────────────────────────────────────────────────────────────────
# 2. Docker (required for OpenShell container runtime)
# ──────────────────────────────────────────────────────────────────
echo ""
echo "[2/7] Ensuring Docker is installed..."
if command -v docker &>/dev/null && docker info &>/dev/null; then
echo "[✓] Docker $(docker --version | awk '{print $3}') already running"
else
echo " Installing Docker..."
apt-get install -y ca-certificates curl gnupg lsb-release
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" \
| tee /etc/apt/sources.list.d/docker.list > /dev/null
apt-get update -q
apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
systemctl enable docker
systemctl start docker
echo "[✓] Docker installed"
fi
# Move Docker data root to NVMe so images don't fill root disk
DOCKER_DAEMON_JSON="/etc/docker/daemon.json"
if ! grep -q "nvme" "$DOCKER_DAEMON_JSON" 2>/dev/null; then
echo " Moving Docker data-root → $NVME/docker"
mkdir -p "$NVME/docker"
# Preserve existing config if any
EXISTING=$(cat "$DOCKER_DAEMON_JSON" 2>/dev/null || echo "{}")
python3 -c "
import json, sys
cfg = json.loads('''$EXISTING''')
cfg['data-root'] = '$NVME/docker'
print(json.dumps(cfg, indent=2))
" > "$DOCKER_DAEMON_JSON"
systemctl restart docker
echo "[✓] Docker data-root → $NVME/docker"
fi
# ──────────────────────────────────────────────────────────────────
# 3. Install NemoClaw (headless via env vars)
# ──────────────────────────────────────────────────────────────────
echo ""
echo "[3/7] Installing NemoClaw..."
# Set HOME so NemoClaw installs to NVMe-backed location
export NEMOCLAW_HOME="$NVME/nemoclaw"
export OPENSHELL_HOME="$NVME/openshell"
export HOME_OVERRIDE="$NVME/home"
mkdir -p "$NEMOCLAW_HOME" "$OPENSHELL_HOME" "$HOME_OVERRIDE"
# Link ~/.nemoclaw and ~/.openshell to NVMe
ln -sfn "$NEMOCLAW_HOME" /root/.nemoclaw 2>/dev/null || true
ln -sfn "$NEMOCLAW_HOME" /home/ubuntu/.nemoclaw 2>/dev/null || true
ln -sfn "$OPENSHELL_HOME" /root/.openshell 2>/dev/null || true
ln -sfn "$OPENSHELL_HOME" /home/ubuntu/.openshell 2>/dev/null || true
if command -v nemoclaw &>/dev/null; then
echo "[✓] nemoclaw already installed: $(nemoclaw --version 2>/dev/null || echo 'version unknown')"
else
echo " Downloading NemoClaw installer..."
INSTALLER_SCRIPT="$NVME/nemoclaw_install.sh"
curl -fsSL https://www.nvidia.com/nemoclaw.sh -o "$INSTALLER_SCRIPT"
chmod +x "$INSTALLER_SCRIPT"
# Run the installer non-interactively
# NEMOCLAW_SKIP_ONBOARD=1 bypasses the interactive wizard (undocumented but standard pattern)
# We'll do manual onboarding after install using CLI flags
NEMOCLAW_SKIP_ONBOARD=1 \
NEMOCLAW_HOME="$NEMOCLAW_HOME" \
bash "$INSTALLER_SCRIPT" || true
# Reload PATH
export PATH="$PATH:/usr/local/bin:/root/.local/bin"
source ~/.bashrc 2>/dev/null || true
if ! command -v nemoclaw &>/dev/null; then
echo "[WARN] nemoclaw not in PATH yet — checking common locations..."
for p in /usr/local/bin/nemoclaw /root/.local/bin/nemoclaw "$NVME/bin/nemoclaw"; do
if [ -f "$p" ]; then
ln -sfn "$p" /usr/local/bin/nemoclaw
echo "[✓] Linked nemoclaw from $p"
break
fi
done
fi
echo "[✓] nemoclaw installed"
fi
# ──────────────────────────────────────────────────────────────────
# 4. Onboard the Velocity Sentinel agent sandbox
# ──────────────────────────────────────────────────────────────────
echo ""
echo "[4/7] Onboarding '$AGENT_NAME' NemoClaw sandbox..."
# Check if sandbox already exists
if nemoclaw "$AGENT_NAME" status &>/dev/null; then
echo "[✓] Sandbox '$AGENT_NAME' already exists — skipping creation"
else
echo " Running nemoclaw onboard (this may take a few minutes)..."
# --provider compatible-endpoint: use our local Ollama instead of NVIDIA cloud
# --yes: skip confirmation prompts
nemoclaw onboard \
--name "$AGENT_NAME" \
--provider compatible-endpoint \
--endpoint "$OLLAMA_URL/v1" \
--model "$OLLAMA_MODEL" \
--yes \
--no-messaging-bridge \
--no-skills || {
echo "[WARN] Structured onboard failed — trying minimal onboard..."
# Fallback: let it run with defaults if flags are not supported in this alpha version
yes "" | nemoclaw onboard --name "$AGENT_NAME" 2>&1 | head -60 || true
}
echo "[✓] Sandbox onboarded"
fi
# ──────────────────────────────────────────────────────────────────
# 5. Configure OpenShell to use Ollama (compatible endpoint)
# ──────────────────────────────────────────────────────────────────
echo ""
echo "[5/7] Configuring OpenShell inference → Ollama (qwen3.5:27b)..."
# Set inference route to our local Ollama
openshell inference set \
--provider compatible-endpoint \
--base-url "$OLLAMA_URL/v1" \
--api-key "ollama" \
--model "$OLLAMA_MODEL" \
--context-window 32768 \
--max-tokens 4096 || {
echo "[WARN] openshell inference set failed — trying alternate syntax..."
openshell inference set \
--provider compatible-endpoint \
--model "$OLLAMA_MODEL" || true
}
# Also set the context window on the Ollama model side
echo " Setting Ollama num_ctx=32768..."
curl -s -X POST "$OLLAMA_URL/api/generate" \
-H "Content-Type: application/json" \
-d "{\"model\":\"$OLLAMA_MODEL\",\"prompt\":\"\",\"options\":{\"num_ctx\":32768},\"stream\":false}" \
> /dev/null 2>&1 || true
echo "[✓] OpenShell inference configured → $OLLAMA_URL ($OLLAMA_MODEL)"
# ──────────────────────────────────────────────────────────────────
# 6. Write OpenShell network policy (allow Velocity backend egress)
# ──────────────────────────────────────────────────────────────────
echo ""
echo "[6/7] Writing OpenShell network policy..."
POLICY_DIR="$OPENSHELL_HOME/policy"
mkdir -p "$POLICY_DIR"
cat > "$POLICY_DIR/velocity_egress.yaml" << 'POLICY'
# OpenShell Network Egress Policy — Project Velocity Sentinel
# Applied to the velocity-sentinel sandbox.
# All non-listed hosts are blocked by default.
version: "1"
sandbox: velocity-sentinel
egress:
# Local Ollama inference (Qwen 3.5 27B)
- host: "127.0.0.1"
ports: [11434]
description: "Ollama LLM inference"
action: allow
# OpenShell gateway itself (loopback)
- host: "127.0.0.1"
ports: [8080, 8081, 8082, 8083, 8084, 8085]
description: "OpenShell gateway ports"
action: allow
# Velocity FastAPI backend (same host)
- host: "127.0.0.1"
ports: [8000, 8001, 8288]
description: "Velocity FastAPI backend"
action: allow
# PostgreSQL (same host)
- host: "127.0.0.1"
ports: [5432]
description: "PostgreSQL DB"
action: allow
# Block everything else
- host: "*"
action: deny
description: "Default deny — data sovereignty (India/Abu Dhabi)"
POLICY
# Apply the policy if openshell supports it
openshell policy apply "$POLICY_DIR/velocity_egress.yaml" 2>/dev/null || \
echo "[WARN] Policy apply not supported yet in this alpha — YAML written for future use"
echo "[✓] Network policy written → $POLICY_DIR/velocity_egress.yaml"
# ──────────────────────────────────────────────────────────────────
# 7. Write NemoClaw systemd service
# ──────────────────────────────────────────────────────────────────
echo ""
echo "[7/7] Installing systemd service: nemoclaw-velocity.service..."
NEMOCLAW_BIN=$(command -v nemoclaw || echo "/usr/local/bin/nemoclaw")
OPENSHELL_BIN=$(command -v openshell || echo "/usr/local/bin/openshell")
cat > /etc/systemd/system/nemoclaw-velocity.service << SERVICE
[Unit]
Description=NemoClaw Velocity Sentinel Gateway
Documentation=https://github.com/NVIDIA/NemoClaw
After=network.target ollama.service docker.service
Wants=ollama.service docker.service
[Service]
Type=simple
User=ubuntu
Group=ubuntu
WorkingDirectory=$NVME/nemoclaw
# GPU constraint: NemoClaw itself is CPU-bound (inference goes to Ollama)
# Ollama already owns GPUs 0,1. ComfyUI owns GPUs 2,3.
Environment=CUDA_VISIBLE_DEVICES=""
Environment=NEMOCLAW_HOME=$NVME/nemoclaw
Environment=OPENSHELL_HOME=$NVME/openshell
Environment=OLLAMA_BASE_URL=http://127.0.0.1:11434
Environment=VELOCITY_NEMO_MODEL=qwen3.5:27b
Environment=GATEWAY_PORT=$OPENCLAW_PORT
ExecStart=$NEMOCLAW_BIN $AGENT_NAME connect --gateway-port $OPENCLAW_PORT
ExecReload=/bin/kill -HUP \$MAINPID
Restart=always
RestartSec=10
StandardOutput=append:$NVME/logs/nemoclaw-velocity.log
StandardError=append:$NVME/logs/nemoclaw-velocity.log
# Limits
LimitNOFILE=65536
TimeoutStopSec=30
[Install]
WantedBy=multi-user.target
SERVICE
mkdir -p "$NVME/logs"
systemctl daemon-reload
systemctl enable nemoclaw-velocity.service
systemctl start nemoclaw-velocity.service || true # May fail on first boot if onboard not done
echo "[✓] nemoclaw-velocity.service enabled and started"
# ──────────────────────────────────────────────────────────────────
# Finalize: Detect gateway port & write env file
# ──────────────────────────────────────────────────────────────────
echo ""
echo "================================================================"
echo " Writing Velocity backend environment file..."
echo "================================================================"
VELOCITY_ENV="$NVME/velocity/env"
mkdir -p "$(dirname "$VELOCITY_ENV")"
# Detect actual OpenShell gateway URL
GATEWAY_URL="http://127.0.0.1:$OPENCLAW_PORT"
GATEWAY_CHAT_URL="$GATEWAY_URL/v1/chat/completions"
# Quick connectivity test (will succeed once nemoclaw starts)
echo " Testing gateway at $GATEWAY_CHAT_URL ..."
sleep 5
HTTP_CODE=$(curl -sf -o /dev/null -w "%{http_code}" \
-X POST "$GATEWAY_CHAT_URL" \
-H "Content-Type: application/json" \
-d '{"model":"qwen3.5:27b","messages":[{"role":"user","content":"ping"}],"max_tokens":5}' \
2>/dev/null || echo "000")
if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "201" ]; then
echo "[✓] Gateway responding at $GATEWAY_CHAT_URL (HTTP $HTTP_CODE)"
else
echo "[WARN] Gateway not yet responding (HTTP $HTTP_CODE) — it may still be starting up"
fi
cat > "$VELOCITY_ENV" << ENV
# Project Velocity — Backend Environment
# Generated by nemoclaw_deploy.sh
# Loaded by: source $VELOCITY_ENV
# ── NemoClaw / OpenShell Gateway ──────────────────────────────────
NEMOCLAW_BASE_URL=$GATEWAY_URL
NEMOCLAW_CHAT_URL=$GATEWAY_CHAT_URL
NEMOCLAW_MODEL=qwen3.5:27b
NEMOCLAW_TIMEOUT_S=30.0
NEMOCLAW_TEMPERATURE=0.2
# ── Ollama (direct fallback if OpenShell gateway not up) ──────────
OLLAMA_BASE_URL=http://127.0.0.1:11434
# ── NemoClaw Prompts ──────────────────────────────────────────────
NEMOCLAW_PROMPT_DIR=$NVME/nemoclaw/prompts
# ── JWT / Auth ────────────────────────────────────────────────────
# VELOCITY_JWT_SECRET=<SET_THIS>
# ── PostgreSQL ────────────────────────────────────────────────────
# VELOCITY_DB_DSN=postgresql://velocity_app:<PW>@127.0.0.1:5432/velocity
ENV
echo "[✓] Environment file written → $VELOCITY_ENV"
echo ""
echo "================================================================"
echo " DONE. Summary:"
echo ""
echo " Agent name : $AGENT_NAME"
echo " Gateway URL : $GATEWAY_URL"
echo " Chat endpoint: $GATEWAY_CHAT_URL"
echo " Model : $OLLAMA_MODEL (via Ollama on port 11434)"
echo " GPUs 0,1 : Ollama (unchanged)"
echo " GPUs 2,3 : ComfyUI (unchanged)"
echo " Env file : $VELOCITY_ENV"
echo " Service log : $NVME/logs/nemoclaw-velocity.log"
echo ""
echo " Next commands to verify:"
echo " nemoclaw $AGENT_NAME status"
echo " nemoclaw $AGENT_NAME logs --follow"
echo " curl $GATEWAY_CHAT_URL (POST with messages[])"
echo "================================================================"