Configuration System
Claif’s configuration system provides flexible, hierarchical configuration management that supports multiple sources and automatic environment variable integration.
Overview
The configuration system follows a clear precedence order:
- CLI arguments (highest priority)
- Environment variables
- Configuration files
- Default values (lowest priority)
Configuration Structure
Main Configuration Class
@dataclass
class Config:
"""Main configuration class for the Claif framework."""
default_provider: Provider = Provider.CLAUDE
providers: dict[Provider, ProviderConfig] = field(default_factory=dict)
cache_enabled: bool = True
cache_ttl: int = 3600 # seconds
session_dir: str | None = None # defaults to ~/.claif/sessions
verbose: bool = False
output_format: str = "text"
retry_config: dict[str, Any] = field(default_factory=lambda: {
"count": 3,
"delay": 1.0,
"backoff": 2.0
})
mcp_servers: dict[str, Any] = field(default_factory=dict)
Provider Configuration
@dataclass
class ProviderConfig:
"""Configuration for individual providers."""
enabled: bool = True
model: str | None = None
api_key_env: str | None = None
timeout: int = 120
extra: dict[str, Any] = field(default_factory=dict)
Configuration Files
File Locations
Claif searches for configuration files in the following order:
- Specified file:
--config path/to/config.json
- User config:
~/.claif/config.json
- XDG config:
~/.config/claif/config.json
- Local config:
./claif.json
JSON Format
{
"default_provider": "claude",
"cache_enabled": true,
"cache_ttl": 3600,
"session_dir": "~/.claif/sessions",
"verbose": false,
"output_format": "text",
"retry_config": {
"count": 3,
"delay": 1.0,
"backoff": 2.0
},
"providers": {
"claude": {
"enabled": true,
"model": "claude-3-sonnet-20240229",
"api_key_env": "ANTHROPIC_API_KEY",
"timeout": 120,
"extra": {
"session_dir": "~/.claif/claude_sessions",
"auto_approve": false
}
},
"gemini": {
"enabled": true,
"model": "gemini-pro",
"api_key_env": "GEMINI_API_KEY",
"timeout": 90,
"extra": {
"auto_approve": true,
"context_length": 32000
}
},
"codex": {
"enabled": true,
"model": "o4-mini",
"api_key_env": "OPENAI_API_KEY",
"timeout": 120,
"extra": {
"action_mode": "review",
"working_dir": "."
}
}
},
"mcp_servers": {
"example_server": {
"command": "python",
"args": ["-m", "example_mcp_server"],
"env": {
"API_KEY": "${EXAMPLE_API_KEY}"
}
}
}
}
TOML Format (Alternative)
While JSON is the primary format, you can also use TOML:
# ~/.claif/config.toml
default_provider = "claude"
cache_enabled = true
cache_ttl = 3600
session_dir = "~/.claif/sessions"
verbose = false
output_format = "text"
[retry_config]
count = 3
delay = 1.0
backoff = 2.0
[providers.claude]
enabled = true
model = "claude-3-sonnet-20240229"
api_key_env = "ANTHROPIC_API_KEY"
timeout = 120
[providers.claude.extra]
session_dir = "~/.claif/claude_sessions"
auto_approve = false
[providers.gemini]
enabled = true
model = "gemini-pro"
api_key_env = "GEMINI_API_KEY"
timeout = 90
[providers.gemini.extra]
auto_approve = true
context_length = 32000
[providers.codex]
enabled = true
model = "o4-mini"
api_key_env = "OPENAI_API_KEY"
timeout = 120
[providers.codex.extra]
action_mode = "review"
working_dir = "."
[mcp_servers.example_server]
command = "python"
args = ["-m", "example_mcp_server"]
[mcp_servers.example_server.env]
API_KEY = "${EXAMPLE_API_KEY}"
Environment Variables
Global Settings
Variable | Type | Description | Default |
---|---|---|---|
CLAIF_DEFAULT_PROVIDER | string | Default provider to use | claude |
CLAIF_VERBOSE | boolean | Enable verbose logging | false |
CLAIF_OUTPUT_FORMAT | string | Output format (text/json) | text |
CLAIF_CACHE_ENABLED | boolean | Enable response caching | true |
CLAIF_CACHE_TTL | integer | Cache TTL in seconds | 3600 |
CLAIF_SESSION_DIR | string | Session storage directory | ~/.claif/sessions |
Retry Configuration
Variable | Type | Description | Default |
---|---|---|---|
CLAIF_RETRY_COUNT | integer | Number of retry attempts | 3 |
CLAIF_RETRY_DELAY | float | Initial retry delay (seconds) | 1.0 |
CLAIF_RETRY_BACKOFF | float | Backoff multiplier | 2.0 |
Provider API Keys
Variable | Provider | Description |
---|---|---|
ANTHROPIC_API_KEY | Claude | Anthropic API key |
GEMINI_API_KEY | Gemini | Google Gemini API key |
OPENAI_API_KEY | Codex | OpenAI API key |
Examples
# Basic environment setup
export CLAIF_DEFAULT_PROVIDER=gemini
export CLAIF_VERBOSE=true
export GEMINI_API_KEY=your_api_key_here
# Advanced configuration
export CLAIF_RETRY_COUNT=5
export CLAIF_RETRY_DELAY=2.0
export CLAIF_CACHE_TTL=7200
export CLAIF_SESSION_DIR=/custom/session/path
Configuration Loading
Load Process
from claif.common.config import load_config
# Load with default behavior
config = load_config()
# Load with specific config file
config = load_config("/path/to/custom/config.json")
Programmatic Access
from claif.common.config import Config, ProviderConfig
from claif.common.types import Provider
# Create configuration programmatically
config = Config(
default_provider=Provider.GEMINI,
verbose=True,
cache_enabled=False,
providers={
Provider.GEMINI: ProviderConfig(
model="gemini-pro",
timeout=60,
extra={"auto_approve": True}
)
}
)
CLI Configuration Commands
View Configuration
# Show current configuration
claif config show
# Show specific provider configuration
claif config show --provider claude
# Validate configuration
claif config validate
Modify Configuration
# Interactive configuration setup
claif config
# Set specific values
claif config set default_provider gemini
claif config set providers.claude.model claude-3-opus
claif config set verbose true
# Enable/disable providers
claif config enable claude
claif config disable codex
# Reset to defaults
claif config reset
Configuration Management
# Export current configuration
claif config export > my-config.json
# Import configuration
claif config import my-config.json
# Show configuration file locations
claif config paths
Provider-Specific Configuration
Claude Provider
{
"providers": {
"claude": {
"model": "claude-3-sonnet-20240229",
"api_key_env": "ANTHROPIC_API_KEY",
"timeout": 120,
"extra": {
"session_dir": "~/.claif/claude_sessions",
"auto_approve": false,
"approval_strategy": "conservative",
"max_session_size": 100,
"enable_vision": true,
"enable_tools": true
}
}
}
}
Gemini Provider
{
"providers": {
"gemini": {
"model": "gemini-pro",
"api_key_env": "GEMINI_API_KEY",
"timeout": 90,
"extra": {
"auto_approve": true,
"context_length": 32000,
"yes_mode": true,
"cli_path": "gemini",
"debug": false
}
}
}
}
Codex Provider
{
"providers": {
"codex": {
"model": "o4-mini",
"api_key_env": "OPENAI_API_KEY",
"timeout": 120,
"extra": {
"action_mode": "review",
"working_dir": ".",
"safe_mode": true,
"auto_format": true,
"backup_enabled": true
}
}
}
}
Advanced Configuration
Environment Variable Substitution
Configuration files support environment variable substitution:
{
"providers": {
"claude": {
"api_key_env": "ANTHROPIC_API_KEY",
"extra": {
"session_dir": "${HOME}/.claif/sessions",
"custom_endpoint": "${CLAUDE_ENDPOINT:-https://api.anthropic.com}"
}
}
}
}
Conditional Configuration
Use environment variables to enable conditional configuration:
{
"providers": {
"claude": {
"enabled": "${CLAUDE_ENABLED:-true}",
"extra": {
"debug": "${DEBUG_MODE:-false}",
"timeout": "${CLAUDE_TIMEOUT:-120}"
}
}
}
}
Multi-Environment Setup
Development Configuration
{
"default_provider": "claude",
"verbose": true,
"cache_enabled": false,
"retry_config": {
"count": 1,
"delay": 0.5
},
"providers": {
"claude": {
"extra": {
"debug": true,
"auto_approve": true
}
}
}
}
Production Configuration
{
"default_provider": "claude",
"verbose": false,
"cache_enabled": true,
"cache_ttl": 7200,
"retry_config": {
"count": 5,
"delay": 2.0,
"backoff": 2.0
},
"providers": {
"claude": {
"extra": {
"auto_approve": false,
"approval_strategy": "conservative"
}
}
}
}
Configuration Validation
Built-in Validation
from claif.common.config import load_config, validate_config
try:
config = load_config()
validate_config(config)
print("Configuration is valid!")
except ConfigurationError as e:
print(f"Configuration error: {e}")
Custom Validation
def validate_custom_config(config: Config) -> None:
"""Custom configuration validation."""
# Ensure at least one provider is enabled
enabled_providers = [
p for p, cfg in config.providers.items()
if cfg.enabled
]
if not enabled_providers:
raise ConfigurationError("At least one provider must be enabled")
# Validate cache TTL
if config.cache_ttl <= 0:
raise ConfigurationError("Cache TTL must be positive")
# Validate session directory
session_path = Path(config.session_dir)
if not session_path.parent.exists():
raise ConfigurationError(f"Session directory parent does not exist: {session_path.parent}")
Configuration Schema
JSON Schema
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"default_provider": {
"type": "string",
"enum": ["claude", "gemini", "codex"]
},
"cache_enabled": {
"type": "boolean"
},
"cache_ttl": {
"type": "integer",
"minimum": 1
},
"session_dir": {
"type": "string"
},
"verbose": {
"type": "boolean"
},
"output_format": {
"type": "string",
"enum": ["text", "json", "yaml"]
},
"retry_config": {
"type": "object",
"properties": {
"count": {
"type": "integer",
"minimum": 0
},
"delay": {
"type": "number",
"minimum": 0
},
"backoff": {
"type": "number",
"minimum": 1
}
}
},
"providers": {
"type": "object",
"patternProperties": {
"^(claude|gemini|codex)$": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"model": {
"type": "string"
},
"api_key_env": {
"type": "string"
},
"timeout": {
"type": "integer",
"minimum": 1
},
"extra": {
"type": "object"
}
}
}
}
}
}
}
Migration and Compatibility
Version Migration
def migrate_config_v1_to_v2(old_config: dict) -> dict:
"""Migrate configuration from v1 to v2 format."""
new_config = old_config.copy()
# Rename old keys
if "default_model" in old_config:
new_config["default_provider"] = old_config.pop("default_model")
# Restructure provider configuration
if "api_keys" in old_config:
api_keys = old_config.pop("api_keys")
new_config.setdefault("providers", {})
for provider, api_key in api_keys.items():
new_config["providers"].setdefault(provider, {})
new_config["providers"][provider]["api_key_env"] = api_key
return new_config
Backward Compatibility
The configuration system maintains backward compatibility:
- Old configuration keys are automatically mapped to new ones
- Deprecated settings generate warnings but continue to work
- Migration happens transparently during config loading
Best Practices
1. Security
# Store API keys in environment variables, not config files
export ANTHROPIC_API_KEY="your-secret-key"
# Use restrictive file permissions for config files
chmod 600 ~/.claif/config.json
# Avoid committing config files with secrets
echo "*.json" >> .gitignore
2. Organization
# Use different config files for different environments
claif --config dev-config.json query "test"
claif --config prod-config.json query "production query"
# Keep common settings in main config, specifics in environment
# Base: ~/.claif/config.json
# Dev: ./dev-config.json (extends base)
# Prod: ./prod-config.json (extends base)
3. Validation
# Always validate configuration in production
try:
config = load_config()
validate_config(config)
except ConfigurationError as e:
logger.error(f"Invalid configuration: {e}")
sys.exit(1)
4. Documentation
{
"_comment": "This configuration is for development",
"_version": "2.0",
"_last_updated": "2024-01-15",
"default_provider": "claude",
"verbose": true
}
Troubleshooting
Common Issues
Configuration Not Found
# Check configuration file locations
claif config paths
# Verify file exists and is readable
ls -la ~/.claif/config.json
cat ~/.claif/config.json
Invalid JSON
# Validate JSON syntax
cat ~/.claif/config.json | python -m json.tool
# Common JSON errors:
# - Trailing commas
# - Unquoted keys
# - Single quotes instead of double quotes
Environment Variables Not Working
# Check environment variables
env | grep CLAIF
env | grep API_KEY
# Verify variable names (case sensitive)
echo $CLAIF_DEFAULT_PROVIDER
echo $ANTHROPIC_API_KEY
Permission Errors
# Fix config directory permissions
chmod 755 ~/.claif
chmod 644 ~/.claif/config.json
# Create config directory if missing
mkdir -p ~/.claif
API Reference
Functions
def load_config(config_file: str | None = None) -> Config:
"""Load configuration from files and environment."""
def merge_config(base: Config, overrides: dict[str, Any]) -> Config:
"""Merge configuration overrides into base config."""
def load_env_config(config: Config) -> Config:
"""Load environment variable overrides."""
def save_config(config: Config, path: str | None = None) -> None:
"""Save configuration to file."""
def validate_config(config: Config) -> None:
"""Validate configuration structure and values."""
Classes
@dataclass
class Config:
"""Main configuration class."""
@dataclass
class ProviderConfig:
"""Provider-specific configuration."""
The configuration system provides a robust foundation for managing Claif settings across different environments and use cases while maintaining security and flexibility.