from dataclasses import dataclass from dotenv import load_dotenv from pathlib import Path from typing import Optional import argparse import os @dataclass class Config: """ Configuration class that handles both command line and environment variables. Command line arguments take precedence over environment variables. Environment variables serve as defaults that can be overridden via CLI. """ def __init__(self): """ Create configuration from command line arguments and environment variables. Required arguments must be provided either via CLI or environment variables. """ load_dotenv() parser = argparse.ArgumentParser(description='SIA - Self Improving Agent') parser.add_argument( '--system-prompt', type=Path, default=os.getenv('SIA_SYSTEM_PROMPT', 'system_prompt.md'), help='Path to the system prompt file (default: system_prompt.md, env: SIA_SYSTEM_PROMPT)' ) parser.add_argument( '--action-schema', type=Path, default=os.getenv('SIA_ACTION_SCHEMA', 'action_schema.xsd'), help='Path to the action schema file (default: action_schema.xsd, env: SIA_ACTION_SCHEMA)' ) parser.add_argument( '--server', action='store_true', default=self._parse_bool_env('SIA_SERVER_ENABLED', False), help='Enable web server for debugging and human feedback (env: SIA_SERVER_ENABLED)' ) parser.add_argument( '--host', type=str, default=os.getenv('SIA_SERVER_HOST', '0.0.0.0'), help='Web server host (default: 0.0.0.0, env: SIA_SERVER_HOST)' ) parser.add_argument( '--port', type=int, default=int(os.getenv('SIA_SERVER_PORT', '8080')), help='Web server port (default: 8080, env: SIA_SERVER_PORT)' ) parser.add_argument( '--static-files', type=Path, default=self._parse_optional_path('SIA_STATIC_FILES', './static/'), help='Path to static web files (default: ./static/, env: SIA_STATIC_FILES)' ) parser.add_argument( '--llm-engine', type=str, default=os.getenv('SIA_LLM_ENGINE', 'local'), help='LLM engine (default: local, env: SIA_LLM_ENGINE)' ) parser.add_argument( '--api-token', type=str, default=os.getenv('SIA_API_TOKEN'), help='API access token (env: SIA_API_TOKEN)' ) parser.add_argument( '--model', type=str, default=os.getenv('SIA_MODEL', '/root/model/'), help='Path to the model directory (default: /root/model/, env: SIA_MODEL)' ) parser.add_argument( '--temperature', type=float, default=float(os.getenv('SIA_TEMPERATURE', '0.7')), help='LLM temperature parameter (default: 0.7, env: SIA_TEMPERATURE)' ) parser.add_argument( '--token-limit', type=int, default=os.getenv('SIA_TOKEN_LIMIT'), help='Token limit for the LLM (env: SIA_TOKEN_LIMIT)' ) self.args = parser.parse_args() def _parse_bool_env(self, env_var: str, default: bool) -> bool: """Parse boolean environment variable.""" val = os.getenv(env_var) if val is None: return default return val.lower() in ('true', '1', 'yes', 'on') def _parse_optional_path(self, env_var: str, default: Optional[Path]) -> Optional[Path]: """Parse optional Path environment variable.""" val = os.getenv(env_var) if val is None: return default return Path(val) @property def system_prompt(self) -> Path: """Path to the system prompt file.""" return self.args.system_prompt @property def action_schema(self) -> Path: """Path to the action schema file.""" return self.args.action_schema @property def server(self) -> bool: """Enable web server for debugging and human feedback.""" return self.args.server @property def host(self) -> str: """Web server host.""" return self.args.host @property def port(self) -> int: """Web server port.""" return self.args.port @property def static_files(self) -> Path: """Path to static web files.""" return self.args.static_files @property def llm_engine(self) -> str: """LLM engine.""" return self.args.llm_engine @property def api_token(self) -> Optional[str]: """API access token.""" return self.args.api_token @property def model(self) -> str: """Path to the model directory.""" return self.args.model @property def temperature(self) -> float: """LLM temperature parameter.""" return self.args.temperature @property def token_limit(self) -> int: """Token limit for the LLM.""" return self.args.token_limit