Spaces:
Configuration error
Configuration error
File size: 3,653 Bytes
aa15bce |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
"""Simplified configuration management."""
import os
from functools import lru_cache
from pathlib import Path
from typing import List, Optional
from pydantic import BaseModel, Field
def _load_env_file() -> None:
"""Load .env from root directory if present."""
env_path = Path(__file__).parent.parent / ".env"
if not env_path.is_file():
return
try:
for line in env_path.read_text(encoding="utf-8").splitlines():
stripped = line.strip()
if stripped and not stripped.startswith("#") and "=" in stripped:
key, value = stripped.split("=", 1)
key, value = key.strip(), value.strip().strip("'\"")
if key and value and key not in os.environ:
os.environ[key] = value
except Exception:
pass
_load_env_file()
DEFAULT_APP_NAME = "OpenPoke Server"
DEFAULT_APP_VERSION = "0.3.0"
def _env_int(name: str, fallback: int) -> int:
try:
return int(os.getenv(name, str(fallback)))
except (TypeError, ValueError):
return fallback
class Settings(BaseModel):
"""Application settings with lightweight env fallbacks."""
# App metadata
app_name: str = Field(default=DEFAULT_APP_NAME)
app_version: str = Field(default=DEFAULT_APP_VERSION)
# Server runtime
server_host: str = Field(default=os.getenv("OPENPOKE_HOST", "0.0.0.0"))
server_port: int = Field(default=_env_int("OPENPOKE_PORT", 8001))
# LLM model selection
interaction_agent_model: str = Field(default=os.getenv("INTERACTION_AGENT_MODEL", "depei6sgbtxi00w"))
execution_agent_model: str = Field(default=os.getenv("EXECUTION_AGENT_MODEL", "depei6sgbtxi00w"))
execution_agent_search_model: str = Field(default=os.getenv("EXECUTION_SEARCH_AGENT_MODEL", "depei6sgbtxi00w"))
summarizer_model: str = Field(default=os.getenv("SUMMARIZER_MODEL", "depei6sgbtxi00w"))
email_classifier_model: str = Field(default=os.getenv("EMAIL_CLASSIFIER_MODEL", "depei6sgbtxi00w"))
# API Configuration
api_base_url: str = Field(default=os.getenv("API_BASE_URL", "https://api.friendli.ai/dedicated/v1"))
api_key: Optional[str] = Field(default=os.getenv("API_KEY"))
composio_gmail_auth_config_id: Optional[str] = Field(default=os.getenv("COMPOSIO_GMAIL_AUTH_CONFIG_ID"))
composio_api_key: Optional[str] = Field(default=os.getenv("COMPOSIO_API_KEY"))
# HTTP behaviour
cors_allow_origins_raw: str = Field(default=os.getenv("OPENPOKE_CORS_ALLOW_ORIGINS", "*"))
enable_docs: bool = Field(default=os.getenv("OPENPOKE_ENABLE_DOCS", "1") != "0")
docs_url: Optional[str] = Field(default=os.getenv("OPENPOKE_DOCS_URL", "/docs"))
# Summarisation controls
conversation_summary_threshold: int = Field(default=100)
conversation_summary_tail_size: int = Field(default=10)
@property
def cors_allow_origins(self) -> List[str]:
"""Parse CORS origins from comma-separated string."""
if self.cors_allow_origins_raw.strip() in {"", "*"}:
return ["*"]
return [origin.strip() for origin in self.cors_allow_origins_raw.split(",") if origin.strip()]
@property
def resolved_docs_url(self) -> Optional[str]:
"""Return documentation URL when docs are enabled."""
return (self.docs_url or "/docs") if self.enable_docs else None
@property
def summarization_enabled(self) -> bool:
"""Flag indicating conversation summarisation is active."""
return self.conversation_summary_threshold > 0
@lru_cache(maxsize=1)
def get_settings() -> Settings:
"""Get cached settings instance."""
return Settings()
|