# Configuration Guide > How Aetheel loads its settings — config file, secrets, and CLI overrides. --- ## Table of Contents 1. [Overview](#overview) 2. [Config File](#config-file) 3. [Secrets (.env)](#secrets) 4. [CLI Overrides](#cli-overrides) 5. [Priority Order](#priority-order) 6. [Reference](#reference) 7. [Examples](#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 ```json { "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: ```bash 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. ```bash python main.py [options] ``` | Flag | Description | |------|-------------| | `--model ` | 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 ` | 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 | `/.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 │ └── / │ └── SKILL.md └── daily/ # Session logs └── YYYY-MM-DD.md ``` --- ## Examples ### Minimal Setup (Slack + OpenCode CLI) `.env`: ```env SLACK_BOT_TOKEN=xoxb-your-token SLACK_APP_TOKEN=xapp-your-token ``` No config.json changes needed — defaults work. ```bash python main.py ``` ### Custom Model + SDK Mode `~/.aetheel/config.json`: ```json { "runtime": { "mode": "sdk", "model": "anthropic/claude-sonnet-4-20250514", "server_url": "http://localhost:4096" } } ``` Start OpenCode server first, then Aetheel: ```bash opencode serve --port 4096 python main.py ``` ### Discord with Listen Channels `~/.aetheel/config.json`: ```json { "discord": { "listen_channels": ["1234567890123456"] } } ``` `.env`: ```env DISCORD_BOT_TOKEN=your-discord-token ``` ```bash python main.py --discord ``` ### Multi-Channel (Slack + Discord + Telegram) `.env`: ```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 ``` ```bash python main.py --discord --telegram ``` ### Claude Code Runtime `~/.aetheel/config.json`: ```json { "claude": { "model": "claude-sonnet-4-20250514", "max_turns": 5, "no_tools": false } } ``` ```bash python main.py --claude ```