Skip to main content
Glama
aegntic

Obsidian Elite RAG MCP Server

openrouter.py6.64 kB
""" OpenRouter provider for just-prompt. """ import os import json import requests from typing import List, Dict, Any, Optional from datetime import datetime, timedelta import logging from dotenv import load_dotenv # Load environment variables load_dotenv() logger = logging.getLogger(__name__) # Global cache for models _cached_models = None _cache_timestamp = None _cache_duration = timedelta(hours=72) # Cache for 72 hours def _should_refresh_cache() -> bool: """Check if model cache should be refreshed.""" global _cached_models, _cache_timestamp if _cached_models is None or _cache_timestamp is None: return True return datetime.now() - _cache_timestamp > _cache_duration def _fetch_models() -> List[Dict[str, Any]]: """Fetch all models from OpenRouter API.""" api_key = os.getenv('OPENROUTER_API_KEY') if not api_key: return [] headers = { 'Authorization': f'Bearer {api_key}', 'HTTP-Referer': 'https://claude.ai', 'X-Title': 'just-prompt MCP' } try: response = requests.get('https://openrouter.ai/api/v1/models', headers=headers, timeout=10) response.raise_for_status() return response.json().get('data', []) except Exception as e: logger.error(f"Error fetching OpenRouter models: {e}") return [] def _filter_free_models(models: List[Dict[str, Any]]) -> List[str]: """Filter models to only free ones, prioritized by capability.""" free_models = [] for model in models: pricing = model.get('pricing', {}) prompt_price = float(pricing.get('prompt', '999')) completion_price = float(pricing.get('completion', '999')) # Check if model is free (price = 0) if prompt_price == 0 and completion_price == 0: free_models.append(model) # Sort by capability and recency def model_score(model): context_length = model.get('context_length', 0) model_id = model.get('id', '').lower() # Prioritize certain model families family_bonus = 0 if 'gpt-4' in model_id or 'o1' in model_id: family_bonus = 1000000 elif 'claude' in model_id: family_bonus = 900000 elif 'gemini' in model_id and ('pro' in model_id or '2.0' in model_id): family_bonus = 800000 elif 'llama' in model_id and ('70b' in model_id or '405b' in model_id): family_bonus = 700000 elif 'qwen' in model_id and ('72b' in model_id or '2.5' in model_id): family_bonus = 600000 elif 'mistral' in model_id: family_bonus = 500000 return context_length + family_bonus free_models.sort(key=model_score, reverse=True) return [model.get('id', '') for model in free_models if model.get('id')] def list_models() -> List[str]: """List all available OpenRouter models.""" global _cached_models, _cache_timestamp if _should_refresh_cache(): logger.info("Refreshing OpenRouter model cache...") models = _fetch_models() if models: _cached_models = [model.get('id', '') for model in models if model.get('id')] _cache_timestamp = datetime.now() logger.info(f"Found {len(_cached_models)} OpenRouter models") else: logger.warning("Failed to fetch models, using cached data") if not _cached_models: # Fallback to known models return [ "google/gemini-2.0-flash-exp", "meta-llama/llama-3.3-70b-instruct", "qwen/qwen-2.5-72b-instruct" ] return _cached_models def get_best_free_models(limit: int = 3) -> List[str]: """Get the best free models available.""" global _cached_models, _cache_timestamp if _should_refresh_cache(): logger.info("Refreshing OpenRouter model cache...") models = _fetch_models() if models: free_models = _filter_free_models(models) _cached_models = free_models _cache_timestamp = datetime.now() logger.info(f"Found {len(free_models)} free OpenRouter models") else: logger.warning("Failed to fetch models, using cached data") if not _cached_models: # Fallback to known good free models logger.info("Using fallback models") return [ "google/gemini-2.0-flash-exp", "meta-llama/llama-3.3-70b-instruct", "qwen/qwen-2.5-72b-instruct" ] return _cached_models[:limit] def prompt(text: str, model: str) -> str: """Send a prompt to OpenRouter model.""" api_key = os.getenv('OPENROUTER_API_KEY') if not api_key: raise ValueError("OPENROUTER_API_KEY environment variable not set") headers = { 'Authorization': f'Bearer {api_key}', 'HTTP-Referer': 'https://claude.ai', 'X-Title': 'just-prompt MCP', 'Content-Type': 'application/json' } payload = { "model": model, "messages": [{"role": "user", "content": text}] } try: response = requests.post( 'https://openrouter.ai/api/v1/chat/completions', headers=headers, json=payload, timeout=30 ) response.raise_for_status() result = response.json() return result['choices'][0]['message']['content'] except Exception as e: logger.error(f"Error generating response with OpenRouter model {model}: {e}") raise def get_auto_updated_default_models() -> str: """Get automatically updated default models from OpenRouter.""" api_key = os.getenv('OPENROUTER_API_KEY') if not api_key: logger.warning("No OPENROUTER_API_KEY found, using fallback models") return "openrouter:google/gemini-2.0-flash-exp,openrouter:meta-llama/llama-3.3-70b-instruct,openrouter:qwen/qwen-2.5-72b-instruct" try: best_models = get_best_free_models(3) # Format for just-prompt (add openrouter: prefix) formatted_models = [f"openrouter:{model}" for model in best_models] models_str = ",".join(formatted_models) logger.info(f"Auto-updated default models: {models_str}") return models_str except Exception as e: logger.error(f"Error getting auto-updated models: {e}") # Fallback to known good models return "openrouter:google/gemini-2.0-flash-exp,openrouter:meta-llama/llama-3.3-70b-instruct,openrouter:qwen/qwen-2.5-72b-instruct"

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/aegntic/aegntic-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server