Spaces:
Runtime error
Runtime error
| """Centralized configuration management.""" | |
| from dataclasses import dataclass, field | |
| from typing import Optional | |
| import os | |
| from dotenv import load_dotenv | |
| class TimingConfig: | |
| """Timing configuration for various operations.""" | |
| screenshot_delay: float = 0.5 | |
| action_delay: float = 0.1 | |
| navigation_delay: float = 1.0 | |
| click_delay: float = 0.05 | |
| typing_delay_ms: int = 12 | |
| class ScreenConfig: | |
| """Screen and display configuration.""" | |
| width: int = 1024 | |
| height: int = 768 | |
| display_number: int = 1 | |
| class NetworkConfig: | |
| """Network access configuration.""" | |
| block_all: bool = False | |
| allow_list: str = "0.0.0.0/0" | |
| class SandboxConfig: | |
| """Sandbox lifecycle configuration.""" | |
| auto_stop_interval: int = 30 # minutes | |
| auto_archive_interval: Optional[int] = None | |
| auto_delete_interval: Optional[int] = None | |
| class ClaudeConfig: | |
| """Claude API configuration.""" | |
| model: str = "claude-sonnet-4-5" | |
| max_tokens: int = 4096 | |
| max_screenshots_in_history: int = 0 | |
| max_messages_in_history: int = 20 # Keep only last N messages (user + assistant pairs) | |
| api_timeout: float = 300.0 # 5 minutes | |
| max_retries: int = 3 | |
| auto_screenshot_after_action: bool = False # Capture screenshot after each action (needed for Gemini, not Claude) | |
| class GUIConfig: | |
| """GUI and browser configuration for desktop automation.""" | |
| initial_url: str = "https://www.google.com" | |
| search_engine_url: str = "https://www.google.com/" | |
| user_agent: Optional[str] = None | |
| class ExecutionConfig: | |
| """Code execution configuration.""" | |
| default_timeout: int = 60 | |
| max_timeout: int = 300 | |
| allow_package_install: bool = True | |
| class DaytonaConfig: | |
| """Complete Daytona configuration.""" | |
| # Core configs | |
| timing: TimingConfig = field(default_factory=TimingConfig) | |
| screen: ScreenConfig = field(default_factory=ScreenConfig) | |
| network: NetworkConfig = field(default_factory=NetworkConfig) | |
| sandbox: SandboxConfig = field(default_factory=SandboxConfig) | |
| claude: ClaudeConfig = field(default_factory=ClaudeConfig) | |
| gui: GUIConfig = field(default_factory=GUIConfig) | |
| execution: ExecutionConfig = field(default_factory=ExecutionConfig) | |
| # API Keys | |
| daytona_api_key: Optional[str] = None | |
| anthropic_api_key: Optional[str] = None | |
| def from_env(cls) -> "DaytonaConfig": | |
| """Create configuration from environment variables. | |
| Returns: | |
| DaytonaConfig instance with values from environment | |
| """ | |
| # Load .env file if it exists | |
| load_dotenv() | |
| config = cls() | |
| # Load API keys | |
| config.daytona_api_key = os.environ.get("DAYTONA_API_KEY") | |
| config.anthropic_api_key = os.environ.get("ANTHROPIC_API_KEY") | |
| # Override with environment variables if present | |
| if screen_width := os.environ.get("DAYTONA_SCREEN_WIDTH"): | |
| config.screen.width = int(screen_width) | |
| if screen_height := os.environ.get("DAYTONA_SCREEN_HEIGHT"): | |
| config.screen.height = int(screen_height) | |
| if model := os.environ.get("CLAUDE_MODEL"): | |
| config.claude.model = model | |
| if initial_url := os.environ.get("DAYTONA_INITIAL_URL"): | |
| config.gui.initial_url = initial_url | |
| if auto_stop := os.environ.get("DAYTONA_AUTO_STOP"): | |
| config.sandbox.auto_stop_interval = int(auto_stop) | |
| return config | |
| def validate(self) -> list[str]: | |
| """Validate configuration. | |
| Returns: | |
| List of validation errors (empty if valid) | |
| """ | |
| errors = [] | |
| # Validate API keys | |
| if not self.daytona_api_key: | |
| errors.append("DAYTONA_API_KEY is required") | |
| if not self.anthropic_api_key: | |
| errors.append("ANTHROPIC_API_KEY is required") | |
| # Validate screen size | |
| if self.screen.width <= 0 or self.screen.height <= 0: | |
| errors.append(f"Invalid screen size: {self.screen.width}x{self.screen.height}") | |
| # Validate timing | |
| if self.timing.screenshot_delay < 0: | |
| errors.append("screenshot_delay must be non-negative") | |
| # Validate timeouts | |
| if self.claude.api_timeout <= 0: | |
| errors.append("API timeout must be positive") | |
| if self.execution.default_timeout <= 0: | |
| errors.append("Execution timeout must be positive") | |
| if self.execution.max_timeout < self.execution.default_timeout: | |
| errors.append("max_timeout must be greater than or equal to default_timeout") | |
| return errors | |
| # Global default configuration instance | |
| DEFAULT_CONFIG = DaytonaConfig() | |