|
8 | 8 | from pydantic_settings import BaseSettings, SettingsConfigDict |
9 | 9 |
|
10 | 10 |
|
| 11 | +def _find_project_root() -> Path: |
| 12 | + """Find project root directory by looking for .env file or pyproject.toml.""" |
| 13 | + current = Path(__file__).resolve().parent |
| 14 | + |
| 15 | + # Look for project root markers |
| 16 | + markers = [".env", "pyproject.toml", ".git"] |
| 17 | + |
| 18 | + # Go up the directory tree |
| 19 | + for parent in [current] + list(current.parents): |
| 20 | + if any((parent / marker).exists() for marker in markers): |
| 21 | + return parent |
| 22 | + |
| 23 | + # Fallback to current directory |
| 24 | + return Path.cwd() |
| 25 | + |
| 26 | + |
| 27 | +def _get_env_file_path() -> Path: |
| 28 | + """Get absolute path to .env file.""" |
| 29 | + project_root = _find_project_root() |
| 30 | + env_file = project_root / ".env" |
| 31 | + return env_file |
| 32 | + |
| 33 | + |
11 | 34 | class Settings(BaseSettings): |
12 | 35 | """Application settings loaded from environment variables.""" |
13 | 36 |
|
14 | 37 | model_config = SettingsConfigDict( |
15 | | - env_file=".env", |
| 38 | + env_file=str(_get_env_file_path()), |
16 | 39 | env_file_encoding="utf-8", |
17 | 40 | case_sensitive=False, |
18 | 41 | extra="ignore", |
@@ -145,4 +168,13 @@ def get_prompt_path(self, agent_role: str, version: str | None = None) -> Path: |
145 | 168 | @lru_cache |
146 | 169 | def get_settings() -> Settings: |
147 | 170 | """Get cached settings instance.""" |
148 | | - return Settings() |
| 171 | + import os |
| 172 | + |
| 173 | + settings = Settings() |
| 174 | + |
| 175 | + # Set OpenAI API key as environment variable for CrewAI compatibility |
| 176 | + # CrewAI checks environment variable even when LLM object is provided |
| 177 | + if settings.openai_api_key: |
| 178 | + os.environ["OPENAI_API_KEY"] = settings.openai_api_key |
| 179 | + |
| 180 | + return settings |
0 commit comments