You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

205 lines
7.5 KiB

#!/bin/bash
###############################################################################
# OpenClaw Agent Onboarding Script
#
# Fully automated: creates workspace, registers in agents.yaml +
# project_registry.yaml, installs systemd service, reloads monitor.
#
# Usage:
# ./onboard.sh <agent_id> <agent_name> <project_id> [qdrant_host]
#
# Examples:
# ./onboard.sh crypto "CryptoBot" crypto # local agent
# ./onboard.sh remote1 "RemoteBot" advert 100.115.94.1 # remote agent
###############################################################################
set -e
WORKSPACE="/root/.openclaw/workspace"
TEMPLATE_DIR="$WORKSPACE/templates"
AGENTS_YAML="$WORKSPACE/agents.yaml"
REGISTRY="$WORKSPACE/skills/mem0-integration/project_registry.yaml"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[OK]${NC} $1"; }
log_warning() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
setup_user_env() {
export XDG_RUNTIME_DIR=/run/user/$(id -u)
export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$(id -u)/bus"
}
if [ $# -lt 3 ]; then
echo "Usage: $0 <agent_id> <agent_name> <project_id> [qdrant_host]"
echo ""
echo " agent_id Unique identifier (lowercase, no spaces)"
echo " agent_name Display name for the agent"
echo " project_id Project to register in (must exist in project_registry.yaml)"
echo " qdrant_host Optional: Qdrant host for remote agents (default: localhost)"
exit 1
fi
AGENT_ID="$1"
AGENT_NAME="$2"
PROJECT_ID="$3"
QDRANT_HOST="${4:-localhost}"
USER_ID="wang_yuanzhang"
DATE=$(date +%Y-%m-%d)
AGENT_WORKSPACE="$WORKSPACE/agents/${AGENT_ID}-workspace"
AGENT_CONFIG_DIR="/root/.openclaw-${AGENT_ID}"
SYSTEMD_UNIT="openclaw-gateway-${AGENT_ID}.service"
log_info "Onboarding agent: ${AGENT_NAME} (${AGENT_ID})"
log_info "Project: ${PROJECT_ID}, Qdrant: ${QDRANT_HOST}"
# Pre-check: ensure agent doesn't already exist
if python3 "$WORKSPACE/scripts/parse_agents.py" info "$AGENT_ID" >/dev/null 2>&1; then
log_error "Agent '${AGENT_ID}' already exists in agents.yaml"
exit 1
fi
# 1. Create workspace from templates
if [ -d "$AGENT_WORKSPACE" ]; then
log_error "Workspace already exists: $AGENT_WORKSPACE"
exit 1
fi
log_info "Creating workspace at $AGENT_WORKSPACE..."
mkdir -p "$AGENT_WORKSPACE/skills/mem0-integration"
mkdir -p "$AGENT_WORKSPACE/memory"
for tmpl in IDENTITY.md.template SOUL.md.template; do
base="${tmpl%.template}"
sed -e "s/{{AGENT_ID}}/${AGENT_ID}/g" \
-e "s/{{AGENT_NAME}}/${AGENT_NAME}/g" \
-e "s/{{AGENT_ROLE}}/TODO: define role/g" \
-e "s/{{PROJECT_ID}}/${PROJECT_ID}/g" \
-e "s/{{DATE}}/${DATE}/g" \
"$TEMPLATE_DIR/agent-workspace/$tmpl" > "$AGENT_WORKSPACE/$base"
done
ln -sf "$WORKSPACE/USER.md" "$AGENT_WORKSPACE/USER.md"
ln -sf "$WORKSPACE/AGENTS.md" "$AGENT_WORKSPACE/AGENTS.md"
sed -e "s/{{AGENT_ID}}/${AGENT_ID}/g" \
-e "s/{{AGENT_NAME}}/${AGENT_NAME}/g" \
-e "s/{{QDRANT_HOST}}/${QDRANT_HOST}/g" \
-e "s/{{USER_ID}}/${USER_ID}/g" \
"$TEMPLATE_DIR/agent-workspace/skills/mem0-integration/config.yaml.template" \
> "$AGENT_WORKSPACE/skills/mem0-integration/config.yaml"
log_success "Workspace created"
# 2. Register in agents.yaml (uses sys.argv to avoid shell injection)
if [ "$QDRANT_HOST" = "localhost" ]; then
AGENT_TYPE="local-systemd"
python3 - "$AGENTS_YAML" "$AGENT_ID" "$AGENT_NAME" "$AGENT_TYPE" \
"$AGENT_CONFIG_DIR" "$AGENT_WORKSPACE" "$SYSTEMD_UNIT" "$PROJECT_ID" <<'PYEOF'
import sys, yaml
yaml_path, aid, aname, atype, profile, ws, unit, proj = sys.argv[1:9]
with open(yaml_path, 'r', encoding='utf-8') as f:
data = yaml.safe_load(f)
data['agents'][aid] = {
'name': aname, 'type': atype,
'profile_dir': profile, 'workspace': ws,
'service': {'unit': unit},
'env_file': f'{aid}-gateway.env',
'projects': [proj],
}
with open(yaml_path, 'w', encoding='utf-8') as f:
yaml.dump(data, f, default_flow_style=False, allow_unicode=True, sort_keys=False)
PYEOF
else
AGENT_TYPE="remote-http"
python3 - "$AGENTS_YAML" "$AGENT_ID" "$AGENT_NAME" "$AGENT_TYPE" \
"$AGENT_WORKSPACE" "$QDRANT_HOST" "$PROJECT_ID" <<'PYEOF'
import sys, yaml
yaml_path, aid, aname, atype, ws, qhost, proj = sys.argv[1:8]
with open(yaml_path, 'r', encoding='utf-8') as f:
data = yaml.safe_load(f)
data['agents'][aid] = {
'name': aname, 'type': atype,
'workspace': ws,
'service': {'health_url': f'http://{qhost}:18789/health', 'timeout': 5000},
'projects': [proj],
'qdrant_host': qhost,
}
with open(yaml_path, 'w', encoding='utf-8') as f:
yaml.dump(data, f, default_flow_style=False, allow_unicode=True, sort_keys=False)
PYEOF
fi
log_success "Registered in agents.yaml (type: ${AGENT_TYPE})"
# 3. Register in project_registry.yaml
if grep -q "\"${AGENT_ID}\"" "$REGISTRY" 2>/dev/null; then
log_warning "Agent ${AGENT_ID} already in project registry"
else
if grep -q "^ ${PROJECT_ID}:" "$REGISTRY"; then
sed -i "/^ ${PROJECT_ID}:/,/owner:/ {
/members:/a\\ - \"${AGENT_ID}\"
}" "$REGISTRY"
log_success "Registered ${AGENT_ID} in project ${PROJECT_ID}"
else
log_warning "Project ${PROJECT_ID} not found in registry. Add manually."
fi
fi
# 4. Generate systemd service + env files (local agents only)
if [ "$AGENT_TYPE" = "local-systemd" ]; then
SERVICE_FILE="$WORKSPACE/systemd/${SYSTEMD_UNIT}"
sed -e "s/{{AGENT_ID}}/${AGENT_ID}/g" \
-e "s/{{AGENT_NAME}}/${AGENT_NAME}/g" \
"$TEMPLATE_DIR/systemd/agent-gateway.service.template" > "$SERVICE_FILE"
log_success "Service file: $SERVICE_FILE"
ENV_FILE="$WORKSPACE/systemd/${AGENT_ID}-gateway.env"
sed -e "s/{{AGENT_ID}}/${AGENT_ID}/g" \
-e "s/{{AGENT_NAME}}/${AGENT_NAME}/g" \
-e "s/{{QDRANT_HOST}}/${QDRANT_HOST}/g" \
"$TEMPLATE_DIR/systemd/agent-gateway.env.template" > "$ENV_FILE"
chmod 600 "$ENV_FILE"
log_success "Env file: $ENV_FILE"
# 5. Install and start the service
setup_user_env
mkdir -p ~/.config/systemd/user/
cp "$SERVICE_FILE" "$HOME/.config/systemd/user/${SYSTEMD_UNIT}"
systemctl --user daemon-reload
systemctl --user enable "${SYSTEMD_UNIT}"
log_success "Service installed and enabled"
# 6. Create OpenClaw profile directory
mkdir -p "$AGENT_CONFIG_DIR"
log_info "Profile directory created: $AGENT_CONFIG_DIR"
log_warning "You must create $AGENT_CONFIG_DIR/openclaw.json before starting"
fi
# 7. Reload the monitor to pick up the new agent
systemctl restart openclaw-agent-monitor 2>/dev/null && log_success "Monitor reloaded" || log_warning "Monitor reload failed (may not be running)"
echo ""
log_success "Onboarding complete for ${AGENT_NAME} (${AGENT_ID})"
echo ""
if [ "$AGENT_TYPE" = "local-systemd" ]; then
log_info "Remaining steps:"
echo " 1. Edit agent identity: vim $AGENT_WORKSPACE/IDENTITY.md"
echo " 2. Create openclaw.json: vim $AGENT_CONFIG_DIR/openclaw.json"
echo " (copy from /root/.openclaw/openclaw.json and modify)"
echo " 3. Start: systemctl --user start ${SYSTEMD_UNIT}"
echo ""
elif [ "$AGENT_TYPE" = "remote-http" ]; then
log_info "Remaining steps:"
echo " 1. Deploy the agent on the remote server at ${QDRANT_HOST}"
echo " 2. Ensure Tailscale connectivity to ${QDRANT_HOST}:6333 (Qdrant)"
echo " 3. Configure the remote agent to use Qdrant collection: mem0_v4_shared"
echo ""
fi