# How the Config Class Handles YAML File Storage and Environment Variable Lookups in Agent-Reach

> Discover how the Agent-Reach Config class merges YAML file settings with environment variables for flexible runtime configurations. Override defaults with AGENT_REACH_<SECTION>_<KEY>.

- Repository: [Pnant/Agent-Reach](https://github.com/Panniantong/Agent-Reach)
- Tags: internals
- Published: 2026-07-16

---

**The `Config` class loads default settings from a YAML file and overlays values from environment variables using the `AGENT_REACH_<SECTION>_<KEY>` naming convention, allowing secrets to override persistent configuration at runtime.**

The `Config` class in *Agent-Reach* serves as the central configuration manager for the runtime environment. It implements a dual-source strategy that persists user settings in human-readable YAML files while allowing sensitive credentials and temporary overrides via environment variables. This design ensures that the repository remains free of secrets while maintaining straightforward configuration management.

## The Three-Phase Configuration Process

The implementation in [`agent_reach/config.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/config.py) processes configuration through three distinct phases during initialization.

### Phase 1: Loading the YAML Foundation

On instantiation, the class attempts to read a [`config.yaml`](https://github.com/Panniantong/Agent-Reach/blob/main/config.yaml) file from the current directory, or accepts a custom path via the `--config` CLI flag. The file contents are parsed using `yaml.safe_load` and stored in the private attribute `self._data` as a nested dictionary. This structure mirrors the logical sections of the application, such as `channels`, `doctor`, and `install`, providing sensible defaults for all non-sensitive settings.

### Phase 2: Applying Environment Variable Overrides

Immediately after YAML parsing, the private method `_apply_env_overrides()` scans every configuration entry for a matching environment variable. The naming convention follows `AGENT_REACH_<SECTION>_<KEY>`, where both the section and key names are upper-cased and underscored. When a match exists, the environment variable's value **overwrites** the YAML value, enabling secure injection of API keys and tokens without modifying tracked files.

The conversion logic respects basic types: strings containing `"true"` or `"false"` become `bool`, numeric strings convert to `int` or `float`, and all other values remain as `str`.

### Phase 3: Providing Typed Accessors

The public API exposes `__getitem__` and `get()` methods for dictionary-style access, along with type-safe accessors including `as_bool()`, `as_int()`, and `as_str()`. These helper methods walk the nested dictionary safely and raise a clear `ConfigError` when a key is missing or contains an incompatible type.

## YAML File Storage Implementation

Persistent configuration resides in [`config.yaml`](https://github.com/Panniantong/Agent-Reach/blob/main/config.yaml) by default. The class handles file I/O through dedicated helpers that serialize the in-memory dictionary back to YAML when `save()` is called. This persistence mechanism preserves the structure and comments where possible, though it specifically maintains keys that originated from environment variables by leaving them untouched in the file. This separation ensures that secrets injected via `AGENT_REACH_*` variables never accidentally leak into version-controlled configuration files.

## Environment Variable Resolution

Environment variables act as a dynamic overlay layer. Before any component reads its configuration, the `Config` instance checks the process environment for overrides. This mechanism proves essential for CI pipelines, Docker containers, and the `agent-reach install --env=auto` wizard, all of which can inject credentials without filesystem mutations.

Users can export variables for single-command execution:

```bash
AGENT_REACH_TWITTER_API_KEY=xyz python -m agent_reach.cli tweet

```

The value from the environment wins over whatever is stored in [`config.yaml`](https://github.com/Panniantong/Agent-Reach/blob/main/config.yaml), and the type coercion ensures that flags like `AGENT_REACH_CORE_DEBUG=true` correctly resolve as boolean `True` rather than the string `"true"`.

## How the Two Sources Interact

The interaction between file-based and environment-based configuration follows a strict precedence order:

1. **Startup Defaults** – If [`config.yaml`](https://github.com/Panniantong/Agent-Reach/blob/main/config.yaml) exists, it provides baseline values for all non-sensitive settings like channel enable flags and default timeouts.
2. **Secret Injection** – Environment variables matching the `AGENT_REACH_*` pattern overlay the YAML data before any component accesses the configuration.
3. **Runtime Persistence** – When commands like `doctor` or `install` call `config.save()` after modifying settings (such as after OAuth flows), the method serializes the current in-memory state back to YAML. Keys that existed only in the environment remain absent from the file, maintaining the security boundary.

This architecture keeps secret material out of the repository while giving users a straightforward way to customize the tool for their workflows.

## Practical Code Examples

The following patterns demonstrate typical usage of the `Config` class:

```python
from agent_reach.config import Config

# Load configuration (defaults to ./config.yaml)

cfg = Config()

# Retrieve a string value that may come from YAML or env var

twitter_key = cfg.as_str("channels", "twitter", "api_key")

# Access a boolean flag with type safety

debug_mode = cfg.as_bool("core", "debug")

# Modify settings programmatically and persist

cfg["core"]["log_level"] = "INFO"
cfg.save()  # Writes back to config.yaml

```

The test suite in [`tests/test_config.py`](https://github.com/Panniantong/Agent-Reach/blob/main/tests/test_config.py) validates these behaviors, ensuring that YAML-defined values return correctly, environment variables override files, and type-casting helpers function as expected.

## Summary

- **YAML provides stable defaults** that are version-controlled and human-editable, loaded via `yaml.safe_load` into `self._data`.
- **Environment variables provide a secure, mutable overlay** following the `AGENT_REACH_<SECTION>_<KEY>` naming convention, processed by `_apply_env_overrides()`.
- **The `Config` class merges both sources** at startup, with environment variables taking precedence over file values.
- **Typed accessors** (`as_str`, `as_bool`, `as_int`) guarantee that callers receive the expected Python types.
- **The `save()` method** persists modifications back to YAML while preserving the separation between file-based and environment-only configuration.

## Frequently Asked Questions

### What is the naming convention for environment variables in Agent-Reach?

Environment variables must follow the pattern `AGENT_REACH_<SECTION>_<KEY>`, where both the section and key names are converted to uppercase with underscores. For example, a YAML key `channels.twitter.api_key` becomes `AGENT_REACH_CHANNELS_TWITTER_API_KEY`.

### Does an environment variable override the YAML configuration value?

Yes. When `_apply_env_overrides()` executes during initialization, it checks for environment variables matching the naming convention. If found, the environment value **overwrites** the value from [`config.yaml`](https://github.com/Panniantong/Agent-Reach/blob/main/config.yaml), allowing temporary overrides and secret injection without file modifications.

### What happens to environment-only settings when I save the configuration?

The `save()` method serializes the current in-memory dictionary back to YAML but preserves keys that were only present in the environment by leaving them untouched in the file. This ensures that secrets injected via environment variables do not accidentally get written to disk in the configuration file.

### Where is the Config class implemented in the source code?

The complete implementation resides in [`agent_reach/config.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/config.py), which contains the class definition, file I/O helpers, environment overlay logic, and typed accessor methods. Unit tests demonstrating the YAML and environment variable interaction are located in [`tests/test_config.py`](https://github.com/Panniantong/Agent-Reach/blob/main/tests/test_config.py).