diff --git a/src/promptforge/core/config.py b/src/promptforge/core/config.py new file mode 100644 index 0000000..cbd6289 --- /dev/null +++ b/src/promptforge/core/config.py @@ -0,0 +1,73 @@ +import os +from pathlib import Path +from typing import Any, Dict, Optional +from functools import lru_cache + +import yaml +from pydantic import BaseModel, Field + + +class ProviderConfig(BaseModel): + api_key: Optional[str] = None + model: str = "gpt-4" + temperature: float = 0.7 + base_url: Optional[str] = None + + +class RegistryConfig(BaseModel): + local_path: str = "~/.promptforge/registry" + remote_url: str = "https://registry.promptforge.io" + + +class DefaultsConfig(BaseModel): + provider: str = "openai" + output_format: str = "text" + + +class ValidationConfig(BaseModel): + strict_mode: bool = False + max_retries: int = 3 + + +class Config(BaseModel): + providers: Dict[str, ProviderConfig] = Field(default_factory=dict) + registry: RegistryConfig = Field(default_factory=RegistryConfig) + defaults: DefaultsConfig = Field(default_factory=DefaultsConfig) + validation: ValidationConfig = Field(default_factory=ValidationConfig) + + +def _expand_env_vars(value: Any) -> Any: + if isinstance(value, str): + if value.startswith("${") and value.endswith("}"): + env_var = value[2:-1] + return os.environ.get(env_var, value) + return value + + +def _process_config(config_dict: Dict[str, Any]) -> Dict[str, Any]: + processed = {} + for key, value in config_dict.items(): + if isinstance(value, dict): + processed[key] = _process_config(value) + else: + processed[key] = _expand_env_vars(value) + return processed + + +def load_config(config_path: Optional[Path] = None) -> Config: + if config_path is None: + config_path = Path.cwd() / "configs" / "promptforge.yaml" + + if not config_path.exists(): + return Config() + + with open(config_path, 'r') as f: + raw_config = yaml.safe_load(f) or {} + + processed_config = _process_config(raw_config) + return Config(**processed_config) + + +@lru_cache() +def get_config() -> Config: + return load_config() \ No newline at end of file