# Aetheel Server Setup Guide Step-by-step guide to deploy Aetheel on a Linux or macOS machine. --- ## Quick Start (Recommended) The interactive installer handles everything automatically: ```bash # If repo is public: curl -fsSL http://10.0.0.59:3051/tanmay/Aetheel/raw/branch/main/install.sh | bash # If repo is private (clone first): git clone http://10.0.0.59:3051/tanmay/Aetheel.git && cd Aetheel && bash install.sh ``` Or if you already have the repo cloned: ```bash ./install.sh ``` The installer will: - Check prerequisites (Python 3.12+, uv) - Install dependencies - Detect or install AI runtimes (OpenCode / Claude Code) - Walk you through token configuration - Install the `aetheel` command - Optionally set up a background service (launchd/systemd) After install, use the `aetheel` command: ```bash aetheel start # Start the bot aetheel stop # Stop the background service aetheel restart # Restart the service aetheel status # Check status aetheel logs # Tail live logs aetheel setup # Re-run setup wizard aetheel update # Pull latest + update deps aetheel doctor # Run diagnostics aetheel config # Edit config.json ``` For flags and options: `aetheel help` --- ## Manual Setup If you prefer to set things up manually, follow the steps below. --- ## Table of Contents 1. [Prerequisites](#1-prerequisites) 2. [Install System Dependencies](#2-install-system-dependencies) 3. [Install uv (Python Package Manager)](#3-install-uv) 4. [Install an AI Runtime](#4-install-an-ai-runtime) 5. [Clone the Repository](#5-clone-the-repository) 6. [Install Python Dependencies](#6-install-python-dependencies) 7. [Configure Secrets (.env)](#7-configure-secrets) 8. [Configure Settings (config.json)](#8-configure-settings) 9. [Set Up Messaging Channels](#9-set-up-messaging-channels) 10. [Run the Test Suite](#10-run-the-test-suite) 11. [Start Aetheel](#11-start-aetheel) 12. [Run as a systemd Service](#12-run-as-a-systemd-service) 13. [Verify Everything Works](#13-verify-everything-works) 14. [Optional: Enable WebChat](#14-optional-enable-webchat) 15. [Optional: Enable Webhooks](#15-optional-enable-webhooks) 16. [Optional: Configure Hooks](#16-optional-configure-hooks) 17. [Optional: Configure Heartbeat](#17-optional-configure-heartbeat) 18. [Optional: Add MCP Servers](#18-optional-add-mcp-servers) 19. [Optional: Create Skills](#19-optional-create-skills) 20. [Updating](#20-updating) 21. [Troubleshooting](#21-troubleshooting) --- ## 1. Prerequisites | Requirement | Minimum | Recommended | |---|---|---| | OS | Ubuntu 20.04 / Debian 11 | Ubuntu 22.04+ / Debian 12+ | | Python | 3.12 | 3.13 | | RAM | 512 MB | 1 GB+ (fastembed uses ~300 MB for embeddings) | | Disk | 500 MB | 1 GB+ | | Network | Outbound HTTPS | Outbound HTTPS | You also need at least one of: - Slack workspace with admin access (for Slack adapter) - Telegram bot token (for Telegram adapter) - Discord bot token (for Discord adapter) - Nothing (for WebChat-only mode) And at least one AI runtime: - [OpenCode](https://opencode.ai) CLI - [Claude Code](https://docs.anthropic.com/en/docs/claude-code) CLI - An API key for the LLM provider (Anthropic, OpenAI, etc.) --- ## 2. Install System Dependencies ```bash # Update packages sudo apt update && sudo apt upgrade -y # Install essentials sudo apt install -y git curl build-essential # Verify git --version curl --version ``` --- ## 3. Install uv [uv](https://docs.astral.sh/uv/) is the recommended Python package manager. It handles Python versions, virtual environments, and dependencies. ```bash # Install uv curl -LsSf https://astral.sh/uv/install.sh | sh # Add to PATH (restart shell or source profile) source ~/.bashrc # or ~/.zshrc # Verify uv --version ``` uv will automatically install the correct Python version (3.13) when you run `uv sync`. --- ## 4. Install an AI Runtime You need at least one AI runtime. Pick one (or both): ### Option A: OpenCode (recommended) ```bash curl -fsSL https://opencode.ai/install | bash # Verify opencode --version # Configure a provider opencode auth login ``` ### Option B: Claude Code ```bash # Requires Node.js curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - sudo apt install -y nodejs # Install Claude Code npm install -g @anthropic-ai/claude-code # Verify claude --version ``` ### Set your API key Whichever runtime you use, you need an API key for the LLM provider: ```bash # For Anthropic (used by both OpenCode and Claude Code) export ANTHROPIC_API_KEY="sk-ant-..." # For OpenAI export OPENAI_API_KEY="sk-..." ``` Add these to your `.env` file later (step 7). --- ## 5. Clone the Repository ```bash # Clone cd ~ git clone http://10.0.0.59:3051/tanmay/Aetheel.git cd Aetheel # Verify ls pyproject.toml # Should exist ``` --- ## 6. Install Python Dependencies ```bash # Install project + test dependencies uv sync --extra test # Verify Python version uv run python --version # Should be 3.13.x # Verify key packages uv run python -c "import click; import aiohttp; import apscheduler; print('All packages OK')" ``` --- ## 7. Configure Secrets Secrets (tokens, API keys) go in the `.env` file. This file is gitignored. ```bash # Create from template cp .env.example .env # Edit with your tokens nano .env ``` Fill in the tokens you need: ```bash # Required for Slack SLACK_BOT_TOKEN=xoxb-your-bot-token SLACK_APP_TOKEN=xapp-your-app-token # Required for Telegram (if using --telegram) TELEGRAM_BOT_TOKEN=your-telegram-token # Required for Discord (if using --discord) DISCORD_BOT_TOKEN=your-discord-token # AI provider API key ANTHROPIC_API_KEY=sk-ant-your-key # Optional overrides # OPENCODE_MODEL=anthropic/claude-sonnet-4-20250514 # LOG_LEVEL=DEBUG ``` See [docs/slack-setup.md](slack-setup.md) and [docs/discord-setup.md](discord-setup.md) for how to get these tokens. --- ## 8. Configure Settings Non-secret settings go in `~/.aetheel/config.json`. A default is created on first run, but you can create it now: ```bash # Create the config directory mkdir -p ~/.aetheel/workspace # Generate default config uv run python -c "from config import save_default_config; save_default_config()" # View it cat ~/.aetheel/config.json ``` Edit if needed: ```bash nano ~/.aetheel/config.json ``` Key settings to review: ```json { "runtime": { "mode": "cli", "model": null }, "claude": { "no_tools": false, "allowed_tools": ["Bash", "Read", "Write", "..."] }, "heartbeat": { "enabled": true, "default_channel": "slack", "default_channel_id": "" }, "webchat": { "enabled": false, "port": 8080 }, "webhooks": { "enabled": false, "port": 8090, "token": "" } } ``` --- ## 9. Set Up Messaging Channels ### Slack (see [docs/slack-setup.md](slack-setup.md)) 1. Create a Slack app at https://api.slack.com/apps 2. Add bot scopes: `app_mentions:read`, `chat:write`, `im:history`, `im:read`, `im:write`, `channels:history`, `users:read` 3. Enable Socket Mode, generate an app-level token (`xapp-...`) 4. Install to workspace, copy bot token (`xoxb-...`) 5. Invite bot to channels: `/invite @Aetheel` ### Discord (see [docs/discord-setup.md](discord-setup.md)) 1. Create app at https://discord.com/developers/applications 2. Create bot, copy token 3. Enable Message Content Intent 4. Invite with `bot` scope + Send Messages + Read Message History ### Telegram 1. Message @BotFather on Telegram 2. `/newbot` → follow prompts → copy token 3. Set `TELEGRAM_BOT_TOKEN` in `.env` --- ## 10. Run the Test Suite Before starting, verify everything works: ```bash cd ~/Aetheel # Run the full test + smoke check script uv run python test_all.py ``` You should see all checks pass: ``` ━━━ RESULTS ━━━ Total: 45 checks Passed: 45 Failed: 0 Skipped: 0 All checks passed! 🎉 ``` If anything fails, fix it before proceeding. Common issues: - Missing packages → `uv sync --extra test` - Wrong directory → `cd ~/Aetheel` You can also run just the pytest suite: ```bash uv run python -m pytest tests/ -v --ignore=tests/test_scheduler.py ``` --- ## 11. Start Aetheel ### Basic start (Slack only) ```bash uv run python main.py ``` ### With additional adapters ```bash # Slack + Discord uv run python main.py --discord # Slack + Telegram uv run python main.py --telegram # Slack + Discord + WebChat uv run python main.py --discord --webchat # All adapters uv run python main.py --discord --telegram --webchat ``` ### With Claude Code runtime ```bash uv run python main.py --claude ``` ### Test mode (no AI, echo handler) ```bash uv run python main.py --test ``` ### Using the CLI ```bash # Same as above but via the click CLI uv run python cli.py start --discord --webchat # One-shot chat (no adapters needed) uv run python cli.py chat "What is Python?" # Diagnostics uv run python cli.py doctor ``` --- ## 12. Run as a systemd Service To keep Aetheel running after you disconnect from SSH: ### Create the service file ```bash sudo nano /etc/systemd/system/aetheel.service ``` Paste (adjust paths to match your setup): ```ini [Unit] Description=Aetheel AI Assistant After=network.target [Service] Type=simple User=your-username WorkingDirectory=/home/your-username/Aetheel ExecStart=/home/your-username/.local/bin/uv run python main.py Restart=on-failure RestartSec=10 Environment=PATH=/home/your-username/.local/bin:/usr/local/bin:/usr/bin:/bin # Load .env file EnvironmentFile=/home/your-username/Aetheel/.env # Optional: add more adapters # ExecStart=/home/your-username/.local/bin/uv run python main.py --discord --webchat [Install] WantedBy=multi-user.target ``` ### Enable and start ```bash # Reload systemd sudo systemctl daemon-reload # Enable on boot sudo systemctl enable aetheel # Start now sudo systemctl start aetheel # Check status sudo systemctl status aetheel # View logs sudo journalctl -u aetheel -f ``` ### Manage the service ```bash sudo systemctl stop aetheel # Stop sudo systemctl restart aetheel # Restart sudo systemctl disable aetheel # Disable on boot ``` --- ## 13. Verify Everything Works ### Check the startup log ```bash sudo journalctl -u aetheel --no-pager | tail -20 ``` You should see: ``` ============================================================ Aetheel Starting ============================================================ Config: /home/user/.aetheel/config.json Runtime: opencode/cli, model=default Channels: slack Skills: 0 Scheduler: ✅ Heartbeat: ✅ 3 tasks Subagents: ✅ Hooks: ✅ 0 hooks Webhooks: ❌ ============================================================ ``` ### Test from Slack/Discord/Telegram 1. Send `status` → should show runtime info 2. Send `help` → should show command list 3. Send any question → should get an AI response 4. Send `/reload` → should confirm reload ### Test from CLI ```bash uv run python cli.py doctor uv run python cli.py status ``` --- ## 14. Optional: Enable WebChat Browser-based chat at `http://your-server:8080`. ### Via config Edit `~/.aetheel/config.json`: ```json { "webchat": { "enabled": true, "port": 8080, "host": "0.0.0.0" } } ``` Set `host` to `0.0.0.0` to accept connections from other machines (not just localhost). ### Via CLI flag ```bash uv run python main.py --webchat ``` ### Firewall If using `ufw`: ```bash sudo ufw allow 8080/tcp ``` Then open `http://your-server-ip:8080` in a browser. --- ## 15. Optional: Enable Webhooks HTTP endpoints for external systems to trigger the agent. ### Configure Edit `~/.aetheel/config.json`: ```json { "webhooks": { "enabled": true, "port": 8090, "host": "0.0.0.0", "token": "your-secret-webhook-token" } } ``` Generate a random token: ```bash python3 -c "import secrets; print(secrets.token_urlsafe(32))" ``` ### Firewall ```bash sudo ufw allow 8090/tcp ``` ### Test ```bash # Health check (no auth) curl http://localhost:8090/hooks/health # Wake the agent curl -X POST http://localhost:8090/hooks/wake \ -H "Authorization: Bearer your-secret-webhook-token" \ -H "Content-Type: application/json" \ -d '{"text": "What time is it?"}' # Send to a specific channel curl -X POST http://localhost:8090/hooks/agent \ -H "Authorization: Bearer your-secret-webhook-token" \ -H "Content-Type: application/json" \ -d '{ "message": "New alert from monitoring", "channel": "slack", "channel_id": "C123456" }' ``` --- ## 16. Optional: Configure Hooks Lifecycle hooks run custom code on gateway events. ### Create a hook ```bash mkdir -p ~/.aetheel/workspace/hooks/startup-logger ``` Create `~/.aetheel/workspace/hooks/startup-logger/HOOK.md`: ```markdown --- name: startup-logger description: Log when the gateway starts events: [gateway:startup] enabled: true --- # Startup Logger Logs a message when Aetheel starts. ``` Create `~/.aetheel/workspace/hooks/startup-logger/handler.py`: ```python import logging logger = logging.getLogger("aetheel.hooks.startup-logger") def handle(event): logger.info("Gateway started — startup hook fired!") ``` Hooks are discovered automatically on startup. --- ## 17. Optional: Configure Heartbeat The heartbeat system runs periodic tasks automatically. ### Edit HEARTBEAT.md ```bash nano ~/.aetheel/workspace/HEARTBEAT.md ``` Example: ```markdown # Heartbeat Tasks ## Every 30 minutes - Check if any scheduled reminders need attention ## Every morning (9:00 AM) - Summarize yesterday's conversations - Check for any pending follow-ups ## Every evening (6:00 PM) - Update MEMORY.md with today's key learnings ``` ### Configure where heartbeat responses go Edit `~/.aetheel/config.json`: ```json { "heartbeat": { "enabled": true, "default_channel": "slack", "default_channel_id": "C123456" } } ``` Set `default_channel_id` to the Slack channel ID where heartbeat responses should be sent. --- ## 18. Optional: Add MCP Servers External tool servers that extend the agent's capabilities. Edit `~/.aetheel/config.json`: ```json { "mcp": { "servers": { "brave-search": { "command": "uvx", "args": ["brave-search-mcp@latest"], "env": { "BRAVE_API_KEY": "your-key" } } } } } ``` Aetheel writes the appropriate config file (`.mcp.json` or `opencode.json`) to the workspace before launching the runtime. --- ## 19. Optional: Create Skills Skills teach the agent how to handle specific types of requests. ```bash mkdir -p ~/.aetheel/workspace/skills/weather ``` Create `~/.aetheel/workspace/skills/weather/SKILL.md`: ```markdown --- name: weather description: Check weather for any city triggers: [weather, forecast, temperature, rain] --- # Weather Skill When the user asks about weather: 1. Use web search to find current conditions 2. Include temperature, conditions, and forecast 3. Format the response with emoji ``` Skills are loaded at startup and can be reloaded with `/reload`. --- ## 20. Updating ```bash cd ~/Aetheel # Pull latest git pull # Update dependencies uv sync --extra test # Run tests uv run python test_all.py # Restart service sudo systemctl restart aetheel ``` --- ## 21. Troubleshooting ### "No channel adapters initialized!" No messaging tokens are set. Check your `.env` file has at least one of: - `SLACK_BOT_TOKEN` + `SLACK_APP_TOKEN` - `TELEGRAM_BOT_TOKEN` (with `--telegram` flag) - `DISCORD_BOT_TOKEN` (with `--discord` flag) - `--webchat` flag (no tokens needed) ### "AI runtime not initialized" The AI CLI (opencode or claude) isn't installed or isn't in PATH. ```bash # Check which opencode which claude # Install OpenCode curl -fsSL https://opencode.ai/install | bash ``` ### "Request timed out" The AI took too long. Increase timeout in config: ```json { "runtime": { "timeout_seconds": 300 }, "claude": { "timeout_seconds": 300 } } ``` ### Memory system init failed Usually means fastembed can't download the embedding model on first run. Check internet access and disk space. ```bash # Test manually uv run python -c "from fastembed import TextEmbedding; e = TextEmbedding(); print('OK')" ``` ### Port already in use (WebChat/Webhooks) Another process is using the port. Change it in config or find the process: ```bash sudo lsof -i :8080 # Find what's using port 8080 ``` ### systemd service won't start Check logs: ```bash sudo journalctl -u aetheel -n 50 --no-pager ``` Common issues: - Wrong `WorkingDirectory` path - Wrong `User` - `.env` file not found (check `EnvironmentFile` path) - uv not in PATH (check `Environment=PATH=...`) ### Run diagnostics ```bash uv run python cli.py doctor ``` This checks config validity, workspace, runtime CLIs, tokens, and memory DB.