File size: 3,074 Bytes
79e83ae
4caa52c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79e83ae
4caa52c
79e83ae
4caa52c
79e83ae
 
4caa52c
79e83ae
 
 
 
4caa52c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import os
from typing import Optional

# A comprehensive map of provider names to their base URLs.
PROVIDER_URL_MAP = {
    "perplexity": "https://api.perplexity.ai",
    "anyscale": "https://api.endpoints.anyscale.com/v1",
    "deepinfra": "https://api.deepinfra.com/v1/openai",
    "mistral": "https://api.mistral.ai/v1",
    "groq": "https://api.groq.com/openai/v1",
    "nvidia_nim": "https://integrate.api.nvidia.com/v1",
    "cerebras": "https://api.cerebras.ai/v1",
    "sambanova": "https://api.sambanova.ai/v1",
    "ai21_chat": "https://api.ai21.com/studio/v1",
    "codestral": "https://codestral.mistral.ai/v1",
    "text-completion-codestral": "https://codestral.mistral.ai/v1",
    "empower": "https://app.empower.dev/api/v1",
    "deepseek": "https://api.deepseek.com/v1",
    "friendliai": "https://api.friendli.ai/serverless/v1",
    "galadriel": "https://api.galadriel.com/v1",
    "meta_llama": "https://api.llama.com/compat/v1",
    "featherless_ai": "https://api.featherless.ai/v1",
    "nscale": "https://api.nscale.com/v1",
    "openai": "https://api.openai.com/v1",
    "gemini": "https://generativelanguage.googleapis.com/v1beta",
    "anthropic": "https://api.anthropic.com/v1",
    "cohere": "https://api.cohere.ai/v1",
    "bedrock": "https://bedrock-runtime.us-east-1.amazonaws.com",
    "openrouter": "https://openrouter.ai/api/v1",
}

def get_provider_endpoint(provider: str, model_name: str, incoming_path: str) -> Optional[str]:
    """
    Constructs the full provider endpoint URL based on the provider and incoming request path.
    Supports both hardcoded providers and custom OpenAI-compatible providers via environment variables.
    """
    # First, check the hardcoded map
    base_url = PROVIDER_URL_MAP.get(provider)

    # If not found, check for custom provider via environment variable
    if not base_url:
        api_base_env = f"{provider.upper()}_API_BASE"
        base_url = os.getenv(api_base_env)
        if not base_url:
            return None

    # Determine the specific action from the incoming path (e.g., 'chat/completions')
    action = incoming_path.split('/v1/', 1)[-1] if '/v1/' in incoming_path else incoming_path

    # --- Provider-specific endpoint structures ---
    if provider == "gemini":
        if action == "chat/completions":
            return f"{base_url}/models/{model_name}:generateContent"
        elif action == "embeddings":
            return f"{base_url}/models/{model_name}:embedContent"
    
    elif provider == "anthropic":
        if action == "chat/completions":
            return f"{base_url}/messages"

    elif provider == "cohere":
        if action == "chat/completions":
            return f"{base_url}/chat"
        elif action == "embeddings":
            return f"{base_url}/embed"

    # Default for OpenAI-compatible providers
    # Most of these have /v1 in the base URL already, so we just append the action.
    if base_url.endswith(("/v1", "/v1/openai")):
        return f"{base_url}/{action}"
    
    # Fallback for other cases
    return f"{base_url}/v1/{action}"