# Configuration Management

## Overview

The application uses a canonical configuration system centered on repo-root `settings.json` plus environment variables. The configuration is managed through the `backend/core/config/` package.

## Configuration Classes

The main configuration classes are:

- `AppConfig`: The root configuration class
- `LLMConfig`: Configuration for the Language Model
- `AgentConfig`: Configuration for the agent
- `RuntimeConfig`: Configuration for the runtime environment
- `SecurityConfig`: Configuration for security settings

These classes are Pydantic models with explicit defaults and validation.

## Loading Configuration from Environment Variables

The `load_from_env` function in the config package is responsible for loading configuration values from environment variables. It recursively processes the configuration classes, mapping environment variable names to class attributes.

### Naming Convention for Environment Variables

- Prefix: uppercase field path with underscores (e.g., `LLM_`, `AGENT_`, `EVENT_STREAM_`)
- Field Names: all uppercase
- Full Variable Name: Prefix + Field Name (e.g., `LLM_API_KEY`, `AGENT_MEMORY_ENABLED`)

### Examples

```bash
export LLM_API_KEY='your_api_key_here'
export LLM_MODEL='gpt-4'
export AGENT_MEMORY_ENABLED='true'
export RUNTIME_CONFIG_TIMEOUT='300'
```

## Type Handling

The `load_from_env` function attempts to cast environment variable values to the types specified in the models. It handles:

- Basic types (str, int, bool)
- Optional types (e.g., `str | None`)
- Nested models

If type casting fails, an error is logged, and the default value is retained.

## Default Values

If an environment variable is not set, the default value specified in the model is used.

## Security Considerations

Be cautious when setting sensitive information like API keys in environment variables. Ensure your environment is secure.

## Usage

The `load_app_config()` function is the recommended way to initialize your configuration. It performs the following steps:

1. Creates an instance of `AppConfig`
2. Loads settings from environment variables
3. Loads settings from canonical repo-root `settings.json`
4. Applies final tweaks and validations to the configuration, falling back to the default values specified in the code
5. Optionally sets global logging levels based on the configuration

CLI arguments can override selected runtime fields after config load.

Here's an example of how to use `load_app_config()`:

```python
from backend.core.config.config_loader import load_app_config

# Load all configuration settings
config = load_app_config()

# Now you can access your configuration
llm_config = config.get_llm_config()
agent_config = config.get_agent_config()
runtime_config = config.runtime_config

# Use the configuration in your application
print(f"Using LLM model: {llm_config.model}")
print(f"Agent memory enabled: {agent_config.memory_enabled}")
print(f"Runtime timeout: {runtime_config.timeout}")
```

By using `load_app_config()`, you ensure that all configuration sources are properly loaded and processed, providing a consistent and fully initialized configuration for your application.

## Additional Configuration Methods

While this document focuses on environment variables, CLI overrides are also supported for selected fields.

## Conclusion

The configuration system provides a flexible and type-safe way to manage application settings. By following the naming conventions and utilizing the provided functions, developers can customize component behavior through environment variables and other configuration sources.
