Files
Aetheel/docs/configuration.md
tanmay11k 6d73f74e0b feat: config-driven architecture, install wizard, live runtime switching, usage tracking, auto-failover
Major changes:
- Config-driven adapters: all channels (Slack, Discord, Telegram, WebChat, Webhooks) controlled via config.json with enabled flags and token auto-detection, no CLI flags required
- Runtime engine field: runtime.engine selects opencode/claude from config
- Interactive install script: 8-phase setup wizard with AI runtime detection/installation, token setup, identity file personalization (personality presets), aetheel CLI command, background service (launchd/systemd)
- Live runtime switching: /engine, /model, /provider commands hot-swap the AI runtime from chat without restart, changes persisted to config.json
- Usage tracking: per-request cost extraction from Claude Code JSON output, cumulative stats via /usage command
- Auto-failover: rate limit detection on both runtimes, automatic switch to other engine on quota errors with user notification
- Chat commands work without / prefix (Slack intercepts / in channels), commands: engine, model, provider, config, usage, reload, cron, subagents, status, help
- /config set for editing config.json from chat with dotted key notation
- Security audit saved to docs/security-audit.md
- Full command reference in docs/commands.md
- Future changes doc with NanoClaw agent teams analysis
- Logo added to README and WebChat UI
- README fully rewritten with all features documented
2026-02-18 01:07:12 -05:00

8.4 KiB

Configuration Guide

How Aetheel loads its settings — config file, secrets, and CLI overrides.


Table of Contents

  1. Overview
  2. Config File
  3. Secrets (.env)
  4. CLI Overrides
  5. Priority Order
  6. Reference
  7. Examples

Overview

Aetheel uses a two-file configuration approach:

File Location Purpose
config.json ~/.aetheel/config.json All non-secret settings (model, timeouts, channels, paths)
.env Project root Secrets only (tokens, passwords, API keys)

On first run, Aetheel auto-creates ~/.aetheel/config.json with sensible defaults. You only need to edit what you want to change.


Config File

Located at ~/.aetheel/config.json. Created automatically on first run.

Full Default Config

{
  "log_level": "INFO",
  "runtime": {
    "mode": "cli",
    "model": null,
    "timeout_seconds": 120,
    "server_url": "http://localhost:4096",
    "format": "json"
  },
  "claude": {
    "model": null,
    "timeout_seconds": 120,
    "max_turns": 3,
    "no_tools": true
  },
  "discord": {
    "listen_channels": []
  },
  "memory": {
    "workspace": "~/.aetheel/workspace",
    "db_path": "~/.aetheel/memory.db"
  },
  "scheduler": {
    "db_path": "~/.aetheel/scheduler.db"
  }
}

Section: runtime

Controls the OpenCode AI runtime (default).

Key Type Default Description
mode string "cli" "cli" (subprocess) or "sdk" (opencode serve API)
model string|null null Model ID, e.g. "anthropic/claude-sonnet-4-20250514". Null uses OpenCode's default.
timeout_seconds int 120 Max seconds to wait for a response
server_url string "http://localhost:4096" OpenCode server URL (SDK mode only)
format string "json" CLI output format: "json" (structured) or "default" (plain text)
workspace string|null null Working directory for OpenCode. Null uses current directory.
provider string|null null Provider override, e.g. "anthropic", "openai"

Section: claude

Controls the Claude Code runtime (used with --claude flag).

Key Type Default Description
model string|null null Model ID, e.g. "claude-sonnet-4-20250514"
timeout_seconds int 120 Max seconds to wait for a response
max_turns int 3 Max agentic tool-use turns per request
no_tools bool true Disable tools for pure conversation mode

Section: discord

Discord-specific settings (non-secret).

Key Type Default Description
listen_channels list[string] [] Channel IDs where the bot responds to all messages (no @mention needed)

Section: memory

Memory system paths.

Key Type Default Description
workspace string "~/.aetheel/workspace" Directory for identity files (SOUL.md, USER.md, MEMORY.md) and skills
db_path string "~/.aetheel/memory.db" SQLite database for embeddings and search index

Section: scheduler

Scheduler storage.

Key Type Default Description
db_path string "~/.aetheel/scheduler.db" SQLite database for persisted scheduled jobs

Top-level

Key Type Default Description
log_level string "INFO" "DEBUG", "INFO", "WARNING", "ERROR"

Secrets

Secrets live in .env in the project root. These are never written to config.json.

Copy the template:

cp .env.example .env

Required (at least one adapter)

Variable Format Description
SLACK_BOT_TOKEN xoxb-... Slack bot OAuth token
SLACK_APP_TOKEN xapp-... Slack app-level token (Socket Mode)

Optional

Variable Format Description
TELEGRAM_BOT_TOKEN string Telegram bot token from @BotFather
DISCORD_BOT_TOKEN string Discord bot token from Developer Portal
OPENCODE_SERVER_PASSWORD string Password for opencode serve (SDK mode)
ANTHROPIC_API_KEY sk-ant-... Anthropic API key (Claude Code runtime)

Environment Variable Overrides

Any config.json setting can also be overridden via environment variables. These take priority over the config file:

Env Variable Overrides
LOG_LEVEL log_level
OPENCODE_MODE runtime.mode
OPENCODE_MODEL runtime.model
OPENCODE_TIMEOUT runtime.timeout_seconds
OPENCODE_SERVER_URL runtime.server_url
OPENCODE_PROVIDER runtime.provider
OPENCODE_WORKSPACE runtime.workspace
CLAUDE_MODEL claude.model
CLAUDE_TIMEOUT claude.timeout_seconds
CLAUDE_MAX_TURNS claude.max_turns
CLAUDE_NO_TOOLS claude.no_tools
DISCORD_LISTEN_CHANNELS discord.listen_channels (comma-separated)
AETHEEL_WORKSPACE memory.workspace
AETHEEL_MEMORY_DB memory.db_path

CLI Overrides

CLI arguments have the highest priority and override both config.json and environment variables.

python main.py [options]
Flag Description
--model <id> Override model for both runtimes
--claude Use Claude Code runtime instead of OpenCode
--cli Force CLI mode (OpenCode)
--sdk Force SDK mode (OpenCode)
--telegram Enable Telegram adapter
--discord Enable Discord adapter
--test Use echo handler (no AI)
--log <level> Override log level

Priority Order

When the same setting is defined in multiple places, the highest priority wins:

CLI arguments  >  Environment variables (.env)  >  config.json  >  Defaults

For example, if config.json sets runtime.model to "anthropic/claude-sonnet-4-20250514" but you run python main.py --model openai/gpt-5.1, the CLI argument wins.


Reference

File Locations

File Path Git-tracked
Config ~/.aetheel/config.json No
Secrets <project>/.env No (in .gitignore)
Memory DB ~/.aetheel/memory.db No
Session DB ~/.aetheel/sessions.db No
Scheduler DB ~/.aetheel/scheduler.db No
Identity files ~/.aetheel/workspace/SOUL.md etc. No
Session logs ~/.aetheel/workspace/daily/ No

Data Directory Structure

~/.aetheel/
├── config.json          # Main configuration
├── memory.db            # Embeddings + search index
├── sessions.db          # Persistent session mappings
├── scheduler.db         # Scheduled jobs
└── workspace/
    ├── SOUL.md           # Bot personality
    ├── USER.md           # User profile
    ├── MEMORY.md         # Long-term memory
    ├── skills/           # Skill definitions
    │   └── <name>/
    │       └── SKILL.md
    └── daily/            # Session logs
        └── YYYY-MM-DD.md

Examples

Minimal Setup (Slack + OpenCode CLI)

.env:

SLACK_BOT_TOKEN=xoxb-your-token
SLACK_APP_TOKEN=xapp-your-token

No config.json changes needed — defaults work.

python main.py

Custom Model + SDK Mode

~/.aetheel/config.json:

{
  "runtime": {
    "mode": "sdk",
    "model": "anthropic/claude-sonnet-4-20250514",
    "server_url": "http://localhost:4096"
  }
}

Start OpenCode server first, then Aetheel:

opencode serve --port 4096
python main.py

Discord with Listen Channels

~/.aetheel/config.json:

{
  "discord": {
    "listen_channels": ["1234567890123456"]
  }
}

.env:

DISCORD_BOT_TOKEN=your-discord-token
python main.py --discord

Multi-Channel (Slack + Discord + Telegram)

.env:

SLACK_BOT_TOKEN=xoxb-your-token
SLACK_APP_TOKEN=xapp-your-token
DISCORD_BOT_TOKEN=your-discord-token
TELEGRAM_BOT_TOKEN=your-telegram-token
python main.py --discord --telegram

Claude Code Runtime

~/.aetheel/config.json:

{
  "claude": {
    "model": "claude-sonnet-4-20250514",
    "max_turns": 5,
    "no_tools": false
  }
}
python main.py --claude