Spaces:
Sleeping
Sleeping
| import logging | |
| from typing import Dict, Any | |
| from abc import ABC, abstractmethod | |
| import httpx | |
| logger = logging.getLogger("model_providers") | |
| class BaseProvider(ABC): | |
| def __init__(self, config: Dict[str, Any]): | |
| self.config = config | |
| self.api_key = config.get("api_key") | |
| self.base_url = config.get("base_url") | |
| self.models = config.get("models", []) | |
| self.default_model = config.get("default_model") | |
| async def generate(self, model: str, prompt: str, **kwargs) -> Dict[str, Any]: | |
| pass | |
| def get_cost(self, model: str, tokens_prompt: int, tokens_completion: int) -> float: | |
| return (tokens_prompt + tokens_completion) * 0.000002 | |
| async def _openai_compatible_generate( | |
| base_url: str, | |
| api_key: str, | |
| model: str, | |
| prompt: str, | |
| extra_headers: Dict[str, str] = None, | |
| **kwargs, | |
| ) -> Dict[str, Any]: | |
| """ | |
| Shared implementation for any provider exposing an OpenAI-compatible | |
| /chat/completions endpoint (Groq, Cerebras, OpenRouter all qualify). | |
| """ | |
| headers = { | |
| "Authorization": f"Bearer {api_key}", | |
| "Content-Type": "application/json", | |
| } | |
| if extra_headers: | |
| headers.update(extra_headers) | |
| payload = { | |
| "model": model, | |
| "messages": [{"role": "user", "content": prompt}], | |
| "max_tokens": kwargs.get("max_tokens", 1024), | |
| "temperature": kwargs.get("temperature", 0.7), | |
| } | |
| async with httpx.AsyncClient(timeout=60.0) as client: | |
| response = await client.post( | |
| f"{base_url}/chat/completions", | |
| headers=headers, | |
| json=payload, | |
| ) | |
| response.raise_for_status() | |
| data = response.json() | |
| choice = data["choices"][0]["message"]["content"] | |
| usage = data.get("usage", {}) | |
| return { | |
| "text": choice, | |
| "tokens_prompt": usage.get("prompt_tokens", 0), | |
| "tokens_completion": usage.get("completion_tokens", 0), | |
| "cost": 0.0, | |
| } | |
| class GroqClient(BaseProvider): | |
| BASE_URL = "https://api.groq.com/openai/v1" | |
| async def generate(self, model: str, prompt: str, **kwargs) -> Dict[str, Any]: | |
| return await _openai_compatible_generate( | |
| self.BASE_URL, self.api_key, model, prompt, **kwargs | |
| ) | |
| class CerebrasClient(BaseProvider): | |
| BASE_URL = "https://api.cerebras.ai/v1" | |
| async def generate(self, model: str, prompt: str, **kwargs) -> Dict[str, Any]: | |
| return await _openai_compatible_generate( | |
| self.BASE_URL, self.api_key, model, prompt, **kwargs | |
| ) | |
| class OpenRouterClient(BaseProvider): | |
| BASE_URL = "https://openrouter.ai/api/v1" | |
| async def generate(self, model: str, prompt: str, **kwargs) -> Dict[str, Any]: | |
| return await _openai_compatible_generate( | |
| self.BASE_URL, | |
| self.api_key, | |
| model, | |
| prompt, | |
| extra_headers={"HTTP-Referer": "https://dolor3v.studio"}, | |
| **kwargs, | |
| ) | |
| class HuggingFaceClient(BaseProvider): | |
| BASE_URL = "https://api-inference.huggingface.co/models" | |
| async def generate(self, model: str, prompt: str, **kwargs) -> Dict[str, Any]: | |
| headers = { | |
| "Authorization": f"Bearer {self.api_key}", | |
| "Content-Type": "application/json", | |
| } | |
| payload = { | |
| "inputs": prompt, | |
| "parameters": { | |
| "max_new_tokens": kwargs.get("max_tokens", 1024), | |
| "temperature": kwargs.get("temperature", 0.7), | |
| }, | |
| } | |
| async with httpx.AsyncClient(timeout=60.0) as client: | |
| response = await client.post( | |
| f"{self.BASE_URL}/{model}", | |
| headers=headers, | |
| json=payload, | |
| ) | |
| response.raise_for_status() | |
| data = response.json() | |
| text = "" | |
| if isinstance(data, list) and data: | |
| text = data[0].get("generated_text", "") | |
| elif isinstance(data, dict): | |
| text = data.get("generated_text", "") | |
| return { | |
| "text": text, | |
| "tokens_prompt": 0, | |
| "tokens_completion": 0, | |
| "cost": 0.0, | |
| } | |
| PROVIDER_CLASSES = { | |
| "groq": GroqClient, | |
| "cerebras": CerebrasClient, | |
| "openrouter": OpenRouterClient, | |
| "huggingface": HuggingFaceClient, | |
| } | |