| """ |
| Carregamento de configuração centralizada. |
| ========================================== |
| Lê config.yaml (ou variáveis de ambiente) e expõe um único dicionário |
| para pipeline, API e agentes. |
| """ |
|
|
| from __future__ import annotations |
| import os |
| from pathlib import Path |
| from typing import Any, Dict |
|
|
| |
| PROJECT_ROOT = Path(__file__).resolve().parent |
| CONFIG_PATH = PROJECT_ROOT / "config.yaml" |
|
|
|
|
| def load_config(config_path: str | Path | None = None) -> Dict[str, Any]: |
| """ |
| Carrega a configuração a partir de config.yaml. |
| Se o arquivo não existir ou estiver incompleto, usa defaults e env. |
| """ |
| path = Path(config_path) if config_path else CONFIG_PATH |
| config: Dict[str, Any] = { |
| "knowledge_base": { |
| "path": "", |
| "chroma_path": os.getenv("VECTOR_DB_PATH", "meu_vector_db"), |
| }, |
| "l3": { |
| "model_path": "truth_scoring_model.pt", |
| "backbone": "bert-base-multilingual-cased", |
| }, |
| "l4": { |
| "russell_concepts_path": "l4_russell_concepts.json", |
| }, |
| "generation": { |
| "provider": os.getenv("GENERATION_PROVIDER", "template"), |
| "groq_model": os.getenv("GROQ_MODEL", "mixtral-8x7b-32768"), |
| "custom_lm_path": "", |
| }, |
| "agent": { |
| "use_agent": os.getenv("USE_AGENT", "false").lower() == "true", |
| "vector_db_path": os.getenv("VECTOR_DB_PATH", "meu_vector_db"), |
| "embedding_model": "sentence-transformers/all-MiniLM-L6-v2", |
| }, |
| "api": { |
| "host": os.getenv("API_HOST", "0.0.0.0"), |
| "port": int(os.getenv("API_PORT", "8000")), |
| }, |
| "chat": { |
| "max_turns_in_context": 10, |
| }, |
| } |
|
|
| if path.exists(): |
| try: |
| import yaml |
| with open(path, "r", encoding="utf-8") as f: |
| loaded = yaml.safe_load(f) |
| if isinstance(loaded, dict): |
| _deep_merge(config, loaded) |
| except Exception: |
| pass |
|
|
| |
| for key in ["model_path", "russell_concepts_path", "custom_lm_path", "path"]: |
| for section in ["l3", "l4", "generation", "knowledge_base"]: |
| if section in config and key in config[section]: |
| val = config[section][key] |
| if val and not Path(val).is_absolute(): |
| config[section][key] = str(PROJECT_ROOT / val) |
| return config |
|
|
|
|
| def _deep_merge(base: Dict[str, Any], override: Dict[str, Any]) -> None: |
| """Mescla override em base recursivamente.""" |
| for k, v in override.items(): |
| if k in base and isinstance(base[k], dict) and isinstance(v, dict): |
| _deep_merge(base[k], v) |
| else: |
| base[k] = v |
|
|