The Three Enriches
AI Butler’s YAML config isn’t a flat bag of knobs. It’s organized into three tiers with progressive disclosure: simple toggles at the top, power-user structure in the middle, developer tunables at the bottom. This pattern is called the Three Enriches.
Every configurable parameter belongs to exactly one tier. This is what makes the setup wizard, web UI, and AI-assisted configuration possible without drowning new users in choices.
The Three Tiers
Section titled “The Three Tiers”| Tier | Audience | Exposed in |
|---|---|---|
| Settings | Everyone | Setup wizard, web form, natural language |
| Configurations | Power users | Web form (advanced), YAML, natural language |
| Options | Developers | YAML only |
Tier 1: Settings
Section titled “Tier 1: Settings”“Everyday knobs.” The setup wizard shows only these. They’re simple values like timezone, enabled channels, persona name, cost strategy.
settings: language: en timezone: Europe/Madrid persona_name: "Butler" active_channels: - webchat - telegram model: claude-sonnet-4-6 agent_mode: swarm cost: strategy: balanced # frugal | balanced | quality monthly_budget: 25 # USD offline_mode: false telemetry_enabled: falseTier 2: Configurations
Section titled “Tier 2: Configurations”“Power-user structure.” Used by people who know what they want. Organized by subsystem — models, channels, embeddings, MCP, IoT, plugins, etc.
configurations: models: primary: claude-sonnet-4-6 fallback: claude-haiku-4-5
channels: telegram: enabled: true typing_indicators: true voice_response: auto slack: enabled: true typing_indicators: true voice_response: text
web: port: 3377 bind_address: 0.0.0.0 max_upload_size_mb: 25
embedding: provider: ollama # openai | ollama | openai_compat | "" (auto-detect) model: nomic-embed-text
mcp: servers: - name: filesystem command: npx args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/me"]
iot: adapter: stub # stub (default); a homeassistant adapter is on the roadmap
plugins: auto_enable: false plugin_dir: /data/pluginsTier 3: Options
Section titled “Tier 3: Options”“Developer tunables.” Fine-grained internals — database timeouts, model sampling parameters, plugin sandbox limits. The average user never touches these.
options: models: temperature: 0.7 max_tokens: 8192 request_timeout: 120s retry_count: 3
database: busy_timeout: 5000 # ms
plugins: max_plugins: 20 max_memory_mb: 64 exec_timeout: 30s
transaction: per_transaction_limit: 5 # max USD per single transaction daily_limit: 20 # max USD per dayWhy Three Tiers?
Section titled “Why Three Tiers?”The same question has to be answered at multiple levels of detail. Take “which model should I use?”:
- Settings:
model: claude-sonnet-4-6— pick one model, done - Configurations:
primary: claude-sonnet-4-6,fallback: claude-haiku-4-5— specific models, fallback strategy - Options:
temperature: 0.7,max_tokens: 8192,request_timeout: 120s— sampling and request tuning
Each tier is sufficient on its own. A user who only sets settings.model gets sensible defaults for everything else. A developer who needs to tune options.models.temperature still inherits the model choice from settings.model.
Configuration Resolution
Section titled “Configuration Resolution”At startup, values are resolved in this order:
- Built-in defaults
- Your config file —
~/.aibutler/config.yaml(override the path with theAIBUTLER_CONFIGenvironment variable; there is no--configflag) - Cross-tier resolution:
settings.model, when set, overridesconfigurations.models.primary
Later sources win. This means you can leave configurations.models.primary unset and let settings.model drive the whole model stack.
Plugin Parameters
Section titled “Plugin Parameters”Plugins declare their own parameters using the same three tiers in their plugin.toml manifest. Each parameter has a type, a default, and a description:
name = "weather-plugin"version = "1.0.0"
[settings.default_location]type = "string"default = "Madrid"description = "City used when no location is given"
[configurations.cache_ttl_minutes]type = "int"default = 15description = "How long to cache weather responses"
[options.http_timeout_seconds]type = "int"default = 10description = "HTTP request timeout"The plugin management UI shows the right parameters at the right disclosure level — end users see default_location, developers see http_timeout_seconds.
Related
Section titled “Related”- Configuration Reference — full field-by-field reference for every key
- BUTLER.md — project-level instructions for the coding agent