free-claude-code/config/settings.py

107 lines
3.4 KiB
Python

"""Centralized configuration using Pydantic Settings."""
from functools import lru_cache
from typing import Optional
from pydantic import field_validator, Field
from pydantic_settings import BaseSettings, SettingsConfigDict
from dotenv import load_dotenv
from .nim import NimSettings
load_dotenv()
# Fixed base URL for NVIDIA NIM
NVIDIA_NIM_BASE_URL = "https://integrate.api.nvidia.com/v1"
class Settings(BaseSettings):
"""Application settings loaded from environment variables."""
# ==================== Provider Selection ====================
# Valid: "nvidia_nim" | "open_router" | "lmstudio"
provider_type: str = "nvidia_nim"
# ==================== OpenRouter Config ====================
open_router_api_key: str = Field(default="", validation_alias="OPENROUTER_API_KEY")
# ==================== Messaging Platform Selection ====================
# Valid: "telegram" | "discord"
messaging_platform: str = Field(
default="discord", validation_alias="MESSAGING_PLATFORM"
)
# ==================== NVIDIA NIM Config ====================
nvidia_nim_api_key: str = ""
# ==================== LM Studio Config ====================
lm_studio_base_url: str = Field(
default="http://localhost:1234/v1",
validation_alias="LM_STUDIO_BASE_URL",
)
# ==================== Model ====================
# All Claude model requests are mapped to this single model
model: str = "moonshotai/kimi-k2-thinking"
# ==================== Provider Rate Limiting ====================
provider_rate_limit: int = Field(default=40, validation_alias="PROVIDER_RATE_LIMIT")
provider_rate_window: int = Field(
default=60, validation_alias="PROVIDER_RATE_WINDOW"
)
# ==================== Fast Prefix Detection ====================
fast_prefix_detection: bool = True
# ==================== Optimizations ====================
enable_network_probe_mock: bool = True
enable_title_generation_skip: bool = True
enable_suggestion_mode_skip: bool = True
enable_filepath_extraction_mock: bool = True
# ==================== NIM Settings ====================
nim: NimSettings = Field(default_factory=NimSettings)
# ==================== Bot Wrapper Config ====================
telegram_bot_token: Optional[str] = None
allowed_telegram_user_id: Optional[str] = None
discord_bot_token: Optional[str] = Field(
default=None, validation_alias="DISCORD_BOT_TOKEN"
)
allowed_discord_channels: Optional[str] = Field(
default=None, validation_alias="ALLOWED_DISCORD_CHANNELS"
)
claude_workspace: str = "./agent_workspace"
allowed_dir: str = ""
max_cli_sessions: int = 10
# ==================== Server ====================
host: str = "0.0.0.0"
port: int = 8082
log_file: str = "server.log"
# Handle empty strings for optional string fields
@field_validator(
"telegram_bot_token",
"allowed_telegram_user_id",
"discord_bot_token",
"allowed_discord_channels",
mode="before",
)
@classmethod
def parse_optional_str(cls, v):
if v == "":
return None
return v
model_config = SettingsConfigDict(
env_file=".env",
env_file_encoding="utf-8",
extra="ignore",
)
@lru_cache()
def get_settings() -> Settings:
"""Get cached settings instance."""
return Settings()