File size: 4,425 Bytes
72f802a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
"""

Configuration management for Product Feature Validation Agent

Handles API keys, environment settings, and deployment configurations

"""

import os
from typing import Dict, Any, Optional
from dataclasses import dataclass
import logging

logger = logging.getLogger(__name__)

@dataclass
class APIConfig:
    """API configuration settings"""
    anthropic_api_key: Optional[str] = None
    modal_token: Optional[str] = None
    newsapi_key: Optional[str] = None
    reddit_client_id: Optional[str] = None
    reddit_client_secret: Optional[str] = None

@dataclass
class ProcessingConfig:
    """Processing configuration settings"""
    max_reviews_per_app: int = 50
    max_reddit_posts: int = 50
    max_news_articles: int = 50
    sentiment_batch_size: int = 32
    modal_gpu_type: str = "T4"
    claude_model: str = "claude-3.5-sonnet-20241022"
    max_tokens: int = 2000

@dataclass
class HackathonConfig:
    """Hackathon-specific configuration"""
    project_name: str = "product-feature-agent"
    team_name: str = "IYKYKnow.ai"
    track: str = "mcp-server-track"
    gradio_server_port: int = 7860
    mcp_server_enabled: bool = True

class ConfigManager:
    """Manages application configuration"""
    
    def __init__(self):
        self.api_config = self._load_api_config()
        self.processing_config = ProcessingConfig()
        self.hackathon_config = HackathonConfig()
        
    def _load_api_config(self) -> APIConfig:
        """Load API configuration from environment variables"""
        return APIConfig(
            anthropic_api_key=os.getenv("ANTHROPIC_API_KEY"),
            modal_token=os.getenv("MODAL_TOKEN"),
            newsapi_key=os.getenv("NEWSAPI_KEY"),
            reddit_client_id=os.getenv("REDDIT_CLIENT_ID"),
            reddit_client_secret=os.getenv("REDDIT_CLIENT_SECRET")
        )
    
    def is_production_ready(self) -> bool:
        """Check if all required API keys are configured"""
        required_keys = [
            self.api_config.anthropic_api_key,
            self.api_config.modal_token,
            self.api_config.newsapi_key
        ]
        return all(key is not None for key in required_keys)
    
    def get_demo_mode_status(self) -> Dict[str, bool]:
        """Get status of which services are in demo mode"""
        return {
            "anthropic": self.api_config.anthropic_api_key is None,
            "modal": self.api_config.modal_token is None,
            "newsapi": self.api_config.newsapi_key is None,
            "reddit": self.api_config.reddit_client_id is None
        }
    
    def get_cost_estimates(self) -> Dict[str, Any]:
        """Get estimated costs for different operations"""
        return {
            "modal_labs": {
                "t4_gpu_per_hour": 0.60,
                "credits_available": 250,
                "estimated_usage": 15.77,
                "efficiency_percentage": 6.3
            },
            "anthropic": {
                "credits_available": 25,
                "batch_discount": 0.50,
                "estimated_tokens": 125000,
                "cost_per_1k_tokens": 0.003
            },
            "newsapi": {
                "free_tier_requests": 1000,
                "estimated_usage": 200
            }
        }

# Global configuration instance
config = ConfigManager()

def get_config() -> ConfigManager:
    """Get the global configuration instance"""
    return config

def log_configuration_status():
    """Log current configuration status"""
    demo_status = config.get_demo_mode_status()
    demo_services = [service for service, is_demo in demo_status.items() if is_demo]
    
    if config.is_production_ready():
        logger.info("All API keys configured - running in production mode")
    else:
        logger.warning(f"Missing API keys: {demo_services} - running in demo mode")
    
    cost_estimates = config.get_cost_estimates()
    logger.info(f"Estimated Modal Labs usage: ${cost_estimates['modal_labs']['estimated_usage']}")
    logger.info(f"Estimated Anthropic usage: {cost_estimates['anthropic']['estimated_tokens']} tokens")

if __name__ == "__main__":
    # Test configuration
    log_configuration_status()
    print(f"Production ready: {config.is_production_ready()}")
    print(f"Demo mode services: {config.get_demo_mode_status()}")