Files
Aetheel/docs/setup.md

845 lines
16 KiB
Markdown

# 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.