Spaces:
Running
Running
| import os | |
| from dotenv import load_dotenv | |
| load_dotenv() | |
| # LLM Provider Configuration | |
| LLM_PROVIDERS = { | |
| "openrouter": { | |
| "name": "OpenRouter", | |
| "base_url": "https://openrouter.ai/api/v1", | |
| "api_key_env": "OPENROUTER_API_KEY", | |
| "description": "Access to multiple models through OpenRouter", | |
| "supports_all_models": True | |
| }, | |
| "anthropic": { | |
| "name": "Anthropic Direct", | |
| "base_url": "https://api.anthropic.com", | |
| "api_key_env": "ANTHROPIC_API_KEY", | |
| "description": "Direct access to Claude models", | |
| "supports_all_models": False, | |
| "supported_models": ["anthropic/claude-sonnet-4", "anthropic/claude-3.5-sonnet-20241022", "anthropic/claude-3-sonnet-20240229", "anthropic/claude-3-haiku-20240307", "anthropic/claude-3-opus-20240229"] | |
| }, | |
| "google": { | |
| "name": "Google AI Studio", | |
| "base_url": "https://generativelanguage.googleapis.com", | |
| "api_key_env": "GOOGLE_API_KEY", | |
| "description": "Direct access to Gemini models", | |
| "supports_all_models": False, | |
| "supported_models": ["google/gemini-2.5-pro-preview-05-06", "google/gemini-pro-vision"] | |
| } | |
| } | |
| # Default provider and model (can be None if no API key is set) | |
| DEFAULT_PROVIDER = None | |
| DEFAULT_MODEL = None | |
| def get_api_key(provider): | |
| """Get API key for specified provider""" | |
| return os.getenv(LLM_PROVIDERS[provider]["api_key_env"]) | |
| def get_available_providers(): | |
| """Get list of providers with valid API keys""" | |
| available = [] | |
| for provider_id, provider_info in LLM_PROVIDERS.items(): | |
| if get_api_key(provider_id): | |
| available.append(provider_id) | |
| return available | |
| def get_models_for_provider(provider_id): | |
| """Get available models for a specific provider""" | |
| available_models = {} | |
| for model_id, model_info in AVAILABLE_MODELS.items(): | |
| if provider_id in model_info.get("providers", []): | |
| available_models[model_id] = model_info | |
| return available_models | |
| def get_default_provider_and_model(): | |
| """Get default provider and model based on available API keys""" | |
| try: | |
| available_providers = get_available_providers() | |
| if not available_providers: | |
| return None, None | |
| # Prefer providers in order: anthropic, openrouter, google | |
| preferred_order = ["anthropic", "openrouter", "google"] | |
| selected_provider = None | |
| for provider in preferred_order: | |
| if provider in available_providers: | |
| selected_provider = provider | |
| break | |
| if not selected_provider: | |
| selected_provider = available_providers[0] | |
| # Get a recommended model for this provider | |
| available_models = get_models_for_provider(selected_provider) | |
| recommended_models = {k: v for k, v in available_models.items() if v.get("recommended", False)} | |
| if recommended_models: | |
| selected_model = list(recommended_models.keys())[0] | |
| elif available_models: | |
| selected_model = list(available_models.keys())[0] | |
| else: | |
| selected_model = None | |
| return selected_provider, selected_model | |
| except Exception: | |
| # If anything fails, return None values | |
| return None, None | |
| # Available models for soil analysis (recommended for structured outputs) | |
| AVAILABLE_MODELS = { | |
| # Claude Models (Excellent for technical analysis) | |
| "anthropic/claude-sonnet-4": { | |
| "name": "Claude-4.0 Sonnet", | |
| "description": "Latest Claude model with superior reasoning and technical analysis", | |
| "cost": "Medium", | |
| "recommended": True, | |
| "supports_images": True, | |
| "providers": ["openrouter", "anthropic"] | |
| }, | |
| "anthropic/claude-3.5-sonnet-20241022": { | |
| "name": "Claude-3.5 Sonnet", | |
| "description": "Previous Claude model, excellent reasoning and technical analysis", | |
| "cost": "Medium", | |
| "recommended": True, | |
| "supports_images": True, | |
| "providers": ["openrouter", "anthropic"] | |
| }, | |
| "anthropic/claude-3-sonnet-20240229": { | |
| "name": "Claude-3 Sonnet (Legacy)", | |
| "description": "Previous version, balanced performance", | |
| "cost": "Medium", | |
| "recommended": False, | |
| "supports_images": True, | |
| "providers": ["openrouter", "anthropic"] | |
| }, | |
| "anthropic/claude-3-haiku-20240307": { | |
| "name": "Claude-3 Haiku", | |
| "description": "Faster and cheaper, good for basic analysis", | |
| "cost": "Low", | |
| "recommended": False, | |
| "supports_images": True, | |
| "providers": ["openrouter", "anthropic"] | |
| }, | |
| "anthropic/claude-3-opus-20240229": { | |
| "name": "Claude-3 Opus", | |
| "description": "Most capable legacy model, best for complex analysis", | |
| "cost": "High", | |
| "recommended": True, | |
| "supports_images": True, | |
| "providers": ["openrouter", "anthropic"] | |
| }, | |
| # GPT Models (Good structured output) | |
| "openai/gpt-4-turbo": { | |
| "name": "GPT-4 Turbo", | |
| "description": "Fast and capable, good JSON output", | |
| "cost": "Medium", | |
| "recommended": True, | |
| "supports_images": True, | |
| "providers": ["openrouter"] | |
| }, | |
| "openai/gpt-3.5-turbo": { | |
| "name": "GPT-3.5 Turbo", | |
| "description": "Fast and cheap, basic analysis", | |
| "cost": "Low", | |
| "recommended": False, | |
| "supports_images": False, | |
| "providers": ["openrouter"] | |
| }, | |
| # Specialized Models | |
| "meta-llama/llama-3.1-70b-instruct": { | |
| "name": "Llama-3.1 70B", | |
| "description": "Open source, good performance", | |
| "cost": "Low", | |
| "recommended": False, | |
| "supports_images": False, | |
| "providers": ["openrouter"] | |
| }, | |
| "mistralai/mixtral-8x7b-instruct": { | |
| "name": "Mixtral 8x7B", | |
| "description": "Good multilingual support", | |
| "cost": "Low", | |
| "recommended": False, | |
| "supports_images": False, | |
| "providers": ["openrouter"] | |
| }, | |
| # xAI Models | |
| "x-ai/grok-3-beta": { | |
| "name": "xAI Grok 3", | |
| "description": "Latest xAI model with advanced reasoning capabilities (text-only)", | |
| "cost": "Medium", | |
| "recommended": True, | |
| "supports_images": False, | |
| "providers": ["openrouter"] | |
| }, | |
| # Google Models | |
| "google/gemini-2.5-pro-preview-05-06": { | |
| "name": "Gemini 2.5 Pro Preview", | |
| "description": "Latest Google Gemini model with advanced multimodal capabilities", | |
| "cost": "Medium", | |
| "recommended": True, | |
| "supports_images": True, | |
| "providers": ["openrouter", "google"] | |
| }, | |
| "google/gemini-pro-vision": { | |
| "name": "Gemini Pro Vision", | |
| "description": "Google's multimodal model optimized for vision tasks", | |
| "cost": "Medium", | |
| "recommended": False, | |
| "supports_images": True, | |
| "providers": ["openrouter", "google"] | |
| } | |
| } | |
| SOIL_TYPES = { | |
| "clay": ["soft clay", "medium clay", "stiff clay", "very stiff clay", "hard clay"], | |
| "sand": ["loose sand", "medium dense sand", "dense sand", "very dense sand"], | |
| "silt": ["soft silt", "medium silt", "stiff silt"], | |
| "gravel": ["loose gravel", "dense gravel"], | |
| "rock": ["weathered rock", "soft rock", "hard rock"] | |
| } | |
| STRENGTH_PARAMETERS = { | |
| "clay": "Su (kPa)", | |
| "sand": "SPT-N", | |
| "silt": "SPT-N", | |
| "gravel": "SPT-N", | |
| "rock": "UCS (MPa)" | |
| } |