| """Application configuration. |
| |
| Loads settings and secrets from environment variables (and the local .env file) |
| using pydantic-settings. Everything the rest of the app needs — API keys, model |
| names, the SQLite path, generation tunables — lives here, so no other module |
| ever has to touch os.environ directly. |
| |
| Usage: |
| from src.config import settings |
| settings.anthropic_api_key |
| """ |
|
|
| from __future__ import annotations |
|
|
| import os |
|
|
| from pydantic_settings import BaseSettings, SettingsConfigDict |
|
|
| |
| |
| |
| |
| |
| |
| _SECRET_ENV_VARS = ( |
| "ANTHROPIC_API_KEY", |
| "HF_TOKEN", |
| "LANGFUSE_PUBLIC_KEY", |
| "LANGFUSE_SECRET_KEY", |
| "LANGFUSE_HOST", |
| "TAVILY_API_KEY", |
| ) |
| for _key in _SECRET_ENV_VARS: |
| if os.environ.get(_key, None) == "": |
| del os.environ[_key] |
|
|
|
|
| class Settings(BaseSettings): |
| """Typed view over the .env file / environment variables. |
| |
| Secrets default to empty strings so that *importing* this module never |
| fails just because a key is missing. Each assistant/tool checks that the |
| key it needs is actually present at call time and raises a clear error if |
| not. This keeps the smoke tests and partial setups working. |
| """ |
|
|
| model_config = SettingsConfigDict( |
| env_file=".env", |
| env_file_encoding="utf-8", |
| extra="ignore", |
| ) |
|
|
| |
| anthropic_api_key: str = "" |
| hf_token: str = "" |
| langfuse_public_key: str = "" |
| langfuse_secret_key: str = "" |
| langfuse_host: str = "https://cloud.langfuse.com" |
| tavily_api_key: str = "" |
|
|
| |
| |
| frontier_model: str = "claude-sonnet-4-5" |
| |
| moderation_model: str = "claude-haiku-4-5" |
| |
| oss_model: str = "Qwen/Qwen2.5-1.5B-Instruct" |
|
|
| |
| max_tokens: int = 512 |
| temperature: float = 0.7 |
|
|
| |
| |
| sqlite_path: str = "./data/sessions.db" |
|
|
|
|
| |
| settings = Settings() |
|
|