From 1ea28ccf67abf49cd5fbb737d65c93495926374e Mon Sep 17 00:00:00 2001 From: joshualipman123 Date: Wed, 30 Jul 2025 10:01:05 -0700 Subject: [PATCH] Add Vercel AI Gateway provider support --- ...to_update_price_and_context_window_file.py | 53 +- docs/my-website/docs/index.md | 144 +- .../docs/providers/vercel_ai_gateway.md | 209 ++ docs/my-website/sidebars.js | 1 + litellm/__init__.py | 7 + litellm/constants.py | 3 + .../get_llm_provider_logic.py | 10 + .../get_supported_openai_params.py | 2 + .../vercel_ai_gateway/chat/transformation.py | 112 + .../llms/vercel_ai_gateway/common_utils.py | 5 + litellm/main.py | 64 + litellm/types/utils.py | 2 +- litellm/utils.py | 28 + model_prices_and_context_window.json | 3004 ++++++++++++++++- .../llm_translation/test_vercel_ai_gateway.py | 205 ++ .../test_vercel_ai_gateway_transformation.py | 112 + 16 files changed, 3689 insertions(+), 272 deletions(-) create mode 100644 docs/my-website/docs/providers/vercel_ai_gateway.md create mode 100644 litellm/llms/vercel_ai_gateway/chat/transformation.py create mode 100644 litellm/llms/vercel_ai_gateway/common_utils.py create mode 100644 tests/llm_translation/test_vercel_ai_gateway.py create mode 100644 tests/test_litellm/llms/vercel_ai_gateway/chat/test_vercel_ai_gateway_transformation.py diff --git a/.github/workflows/auto_update_price_and_context_window_file.py b/.github/workflows/auto_update_price_and_context_window_file.py index 3e0731b94b..cf0b513a6a 100644 --- a/.github/workflows/auto_update_price_and_context_window_file.py +++ b/.github/workflows/auto_update_price_and_context_window_file.py @@ -43,8 +43,8 @@ def write_to_file(file_path, data): # Print an error message if writing to file fails print("Error updating JSON file:", e) -# Update the existing models and add the missing models -def transform_remote_data(data): +# Update the existing models and add the missing models for OpenRouter +def transform_openrouter_data(data): transformed = {} for row in data: # Add the fields 'max_tokens' and 'input_cost_per_token' @@ -81,6 +81,27 @@ def transform_remote_data(data): return transformed +# Update the existing models and add the missing models for Vercel AI Gateway +def transform_vercel_ai_gateway_data(data): + transformed = {} + for row in data: + obj = { + "max_tokens": row["context_window"], + "input_cost_per_token": float(row["pricing"]["input"]), + "output_cost_per_token": float(row["pricing"]["output"]), + } + + obj['max_input_tokens'] = row["context_window"] + + obj.update({ + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }) + + transformed[f'vercel_ai_gateway/{row["id"]}'] = obj + + return transformed + # Load local data from a specified file def load_local_data(file_path): @@ -100,22 +121,32 @@ def load_local_data(file_path): def main(): local_file_path = "model_prices_and_context_window.json" # Path to the local data file - url = "https://openrouter.ai/api/v1/models" # URL to fetch remote data + openrouter_url = "https://openrouter.ai/api/v1/models" # URL to fetch OpenRouter data + vercel_ai_gateway_url = "https://ai-gateway.vercel.sh/v1/models" # URL to fetch Vercel AI Gateway data # Load local data from file local_data = load_local_data(local_file_path) - # Fetch remote data asynchronously - remote_data = asyncio.run(fetch_data(url)) - # Transform the fetched remote data - remote_data = transform_remote_data(remote_data) + + # Fetch OpenRouter data + openrouter_data = asyncio.run(fetch_data(openrouter_url)) + # Transform the fetched OpenRouter data + openrouter_data = transform_openrouter_data(openrouter_data) + + # Fetch Vercel AI Gateway data + vercel_data = asyncio.run(fetch_data(vercel_ai_gateway_url)) + # Transform the fetched Vercel AI Gateway data + vercel_data = transform_vercel_ai_gateway_data(vercel_data) + + # Combine both datasets + all_remote_data = {**openrouter_data, **vercel_data} - # If both local and remote data are available, synchronize and save - if local_data and remote_data: - sync_local_data_with_remote(local_data, remote_data) + # If both local and openrouter data are available, synchronize and save + if local_data and all_remote_data: + sync_local_data_with_remote(local_data, all_remote_data) write_to_file(local_file_path, local_data) else: print("Failed to fetch model data from either local file or URL.") # Entry point of the script if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/docs/my-website/docs/index.md b/docs/my-website/docs/index.md index 58cabc81b4..85226f126f 100644 --- a/docs/my-website/docs/index.md +++ b/docs/my-website/docs/index.md @@ -73,154 +73,20 @@ response = completion( ``` - + + ```python from litellm import completion import os ## set ENV variables -os.environ["ANTHROPIC_API_KEY"] = "your-api-key" +os.environ["VERCEL_AI_GATEWAY_API_KEY"] = "your-api-key" response = completion( - model="anthropic/claude-3-sonnet-20240229", - messages=[{ "content": "Hello, how are you?","role": "user"}] -) -``` - - - - -```python -from litellm import completion -import os - -## set ENV variables -os.environ["XAI_API_KEY"] = "your-api-key" - -response = completion( - model="xai/grok-2-latest", - messages=[{ "content": "Hello, how are you?","role": "user"}] -) -``` - - - -```python -from litellm import completion -import os - -# auth: run 'gcloud auth application-default' -os.environ["VERTEXAI_PROJECT"] = "hardy-device-386718" -os.environ["VERTEXAI_LOCATION"] = "us-central1" - -response = completion( - model="vertex_ai/gemini-1.5-pro", - messages=[{ "content": "Hello, how are you?","role": "user"}] -) -``` - - - - - -```python -from litellm import completion -import os - -## set ENV variables -os.environ["NVIDIA_NIM_API_KEY"] = "nvidia_api_key" -os.environ["NVIDIA_NIM_API_BASE"] = "nvidia_nim_endpoint_url" - -response = completion( - model="nvidia_nim/", - messages=[{ "content": "Hello, how are you?","role": "user"}] -) -``` - - - - - -```python -from litellm import completion -import os - -os.environ["HUGGINGFACE_API_KEY"] = "huggingface_api_key" - -# e.g. Call 'WizardLM/WizardCoder-Python-34B-V1.0' hosted on HF Inference endpoints -response = completion( - model="huggingface/WizardLM/WizardCoder-Python-34B-V1.0", + model="vercel_ai_gateway/openai/gpt-4o", messages=[{ "content": "Hello, how are you?","role": "user"}], - api_base="https://my-endpoint.huggingface.cloud" -) - -print(response) -``` - - - - - -```python -from litellm import completion -import os - -## set ENV variables -os.environ["AZURE_API_KEY"] = "" -os.environ["AZURE_API_BASE"] = "" -os.environ["AZURE_API_VERSION"] = "" - -# azure call -response = completion( - "azure/", - messages = [{ "content": "Hello, how are you?","role": "user"}] -) -``` - - - - - -```python -from litellm import completion - -response = completion( - model="ollama/llama2", - messages = [{ "content": "Hello, how are you?","role": "user"}], - api_base="http://localhost:11434" -) -``` - - - - -```python -from litellm import completion -import os - -## set ENV variables -os.environ["OPENROUTER_API_KEY"] = "openrouter_api_key" - -response = completion( - model="openrouter/google/palm-2-chat-bison", - messages = [{ "content": "Hello, how are you?","role": "user"}], -) -``` - - - - -```python -from litellm import completion -import os - -## set ENV variables. Visit https://novita.ai/settings/key-management to get your API key -os.environ["NOVITA_API_KEY"] = "novita-api-key" - -response = completion( - model="novita/deepseek/deepseek-r1", - messages=[{ "content": "Hello, how are you?","role": "user"}] + stream=True, ) ``` diff --git a/docs/my-website/docs/providers/vercel_ai_gateway.md b/docs/my-website/docs/providers/vercel_ai_gateway.md new file mode 100644 index 0000000000..e7b6400d6a --- /dev/null +++ b/docs/my-website/docs/providers/vercel_ai_gateway.md @@ -0,0 +1,209 @@ +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Vercel AI Gateway + +## Overview + +| Property | Details | +|-------|-------| +| Description | Vercel AI Gateway provides a unified interface to access multiple AI providers through a single endpoint, with built-in caching, rate limiting, and analytics. | +| Provider Route on LiteLLM | `vercel_ai_gateway/` | +| Link to Provider Doc | [Vercel AI Gateway Documentation ↗](https://vercel.com/docs/ai-gateway) | +| Base URL | `https://ai-gateway.vercel.sh/v1` | +| Supported Operations | `/chat/completions`, `/models` | + +
+
+ +https://vercel.com/docs/ai-gateway + +**We support ALL models available through Vercel AI Gateway, just set `vercel_ai_gateway/` as a prefix when sending completion requests** + +## Required Variables + +```python showLineNumbers title="Environment Variables" +os.environ["VERCEL_AI_GATEWAY_API_KEY"] = "" # your Vercel AI Gateway API key +# OR +os.environ["VERCEL_OIDC_TOKEN"] = "" # your Vercel OIDC token for authentication +``` + +## Usage - LiteLLM Python SDK + +### Non-streaming + +```python showLineNumbers title="Vercel AI Gateway Non-streaming Completion" +import os +import litellm +from litellm import completion + +os.environ["VERCEL_AI_GATEWAY_API_KEY"] = "your-api-key" + +messages = [{"content": "Hello, how are you?", "role": "user"}] + +# Vercel AI Gateway call +response = completion( + model="vercel_ai_gateway/openai/gpt-4o", + messages=messages +) + +print(response) +``` + +### Streaming + +```python showLineNumbers title="Vercel AI Gateway Streaming Completion" +import os +import litellm +from litellm import completion + +os.environ["VERCEL_AI_GATEWAY_API_KEY"] = "your-api-key" + +messages = [{"content": "Hello, how are you?", "role": "user"}] + +# Vercel AI Gateway call with streaming +response = completion( + model="vercel_ai_gateway/openai/gpt-4o", + messages=messages, + stream=True +) + +for chunk in response: + print(chunk) +``` + +## Usage - LiteLLM Proxy + +Add the following to your LiteLLM Proxy configuration file: + +```yaml showLineNumbers title="config.yaml" +model_list: + - model_name: gpt-4o-gateway + litellm_params: + model: vercel_ai_gateway/openai/gpt-4o + api_key: os.environ/VERCEL_AI_GATEWAY_API_KEY + + - model_name: claude-4-sonnet-gateway + litellm_params: + model: vercel_ai_gateway/anthropic/claude-4-sonnet + api_key: os.environ/VERCEL_AI_GATEWAY_API_KEY +``` + +Start your LiteLLM Proxy server: + +```bash showLineNumbers title="Start LiteLLM Proxy" +litellm --config config.yaml + +# RUNNING on http://0.0.0.0:4000 +``` + + + + +```python showLineNumbers title="Vercel AI Gateway via Proxy - Non-streaming" +from openai import OpenAI + +# Initialize client with your proxy URL +client = OpenAI( + base_url="http://localhost:4000", # Your proxy URL + api_key="your-proxy-api-key" # Your proxy API key +) + +# Non-streaming response +response = client.chat.completions.create( + model="gpt-4o-gateway", + messages=[{"role": "user", "content": "Hello, how are you?"}] +) + +print(response.choices[0].message.content) +``` + +```python showLineNumbers title="Vercel AI Gateway via Proxy - Streaming" +from openai import OpenAI + +# Initialize client with your proxy URL +client = OpenAI( + base_url="http://localhost:4000", # Your proxy URL + api_key="your-proxy-api-key" # Your proxy API key +) + +# Streaming response +response = client.chat.completions.create( + model="gpt-4o-gateway", + messages=[{"role": "user", "content": "Hello, how are you?"}], + stream=True +) + +for chunk in response: + if chunk.choices[0].delta.content is not None: + print(chunk.choices[0].delta.content, end="") +``` + + + + + +```python showLineNumbers title="Vercel AI Gateway via Proxy - LiteLLM SDK" +import litellm + +# Configure LiteLLM to use your proxy +response = litellm.completion( + model="litellm_proxy/gpt-4o-gateway", + messages=[{"role": "user", "content": "Hello, how are you?"}], + api_base="http://localhost:4000", + api_key="your-proxy-api-key" +) + +print(response.choices[0].message.content) +``` + +```python showLineNumbers title="Vercel AI Gateway via Proxy - LiteLLM SDK Streaming" +import litellm + +# Configure LiteLLM to use your proxy with streaming +response = litellm.completion( + model="litellm_proxy/gpt-4o-gateway", + messages=[{"role": "user", "content": "Hello, how are you?"}], + api_base="http://localhost:4000", + api_key="your-proxy-api-key", + stream=True +) + +for chunk in response: + if hasattr(chunk.choices[0], 'delta') and chunk.choices[0].delta.content is not None: + print(chunk.choices[0].delta.content, end="") +``` + + + + + +```bash showLineNumbers title="Vercel AI Gateway via Proxy - cURL" +curl http://localhost:4000/v1/chat/completions \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer your-proxy-api-key" \ + -d '{ + "model": "gpt-4o-gateway", + "messages": [{"role": "user", "content": "Hello, how are you?"}] + }' +``` + +```bash showLineNumbers title="Vercel AI Gateway via Proxy - cURL Streaming" +curl http://localhost:4000/v1/chat/completions \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer your-proxy-api-key" \ + -d '{ + "model": "gpt-4o-gateway", + "messages": [{"role": "user", "content": "Hello, how are you?"}], + "stream": true + }' +``` + + + + +For more detailed information on using the LiteLLM Proxy, see the [LiteLLM Proxy documentation](../providers/litellm_proxy). + +## Additional Resources + +- [Vercel AI Gateway Documentation](https://vercel.com/docs/ai-gateway) diff --git a/docs/my-website/sidebars.js b/docs/my-website/sidebars.js index 4c9e6d7927..df31dc10b0 100644 --- a/docs/my-website/sidebars.js +++ b/docs/my-website/sidebars.js @@ -451,6 +451,7 @@ const sidebars = { "providers/replicate", "providers/togetherai", "providers/v0", + "providers/vercel_ai_gateway", "providers/morph", "providers/lambda_ai", "providers/novita", diff --git a/litellm/__init__.py b/litellm/__init__.py index 412f552e9c..2d6d1b4225 100644 --- a/litellm/__init__.py +++ b/litellm/__init__.py @@ -209,6 +209,7 @@ vertex_location: Optional[str] = None predibase_tenant_id: Optional[str] = None togetherai_api_key: Optional[str] = None cloudflare_api_key: Optional[str] = None +vercel_ai_gateway_key: Optional[str] = None baseten_key: Optional[str] = None llama_api_key: Optional[str] = None aleph_alpha_key: Optional[str] = None @@ -433,6 +434,7 @@ mistral_chat_models: List = [] text_completion_codestral_models: List = [] anthropic_models: List = [] openrouter_models: List = [] +vercel_ai_gateway_models: List = [] datarobot_models: List = [] vertex_language_models: List = [] vertex_vision_models: List = [] @@ -549,6 +551,8 @@ def add_known_models(): empower_models.append(key) elif value.get("litellm_provider") == "openrouter": openrouter_models.append(key) + elif value.get("litellm_provider") == "vercel_ai_gateway": + vercel_ai_gateway_models.append(key) elif value.get("litellm_provider") == "datarobot": datarobot_models.append(key) elif value.get("litellm_provider") == "vertex_ai-text-models": @@ -718,6 +722,7 @@ model_list = ( + anthropic_models + replicate_models + openrouter_models + + vercel_ai_gateway_models + datarobot_models + huggingface_models + vertex_chat_models @@ -787,6 +792,7 @@ models_by_provider: dict = { "together_ai": together_ai_models, "baseten": baseten_models, "openrouter": openrouter_models, + "vercel_ai_gateway": vercel_ai_gateway_models, "datarobot": datarobot_models, "vertex_ai": vertex_chat_models + vertex_text_models @@ -1165,6 +1171,7 @@ from .llms.v0.chat.transformation import V0ChatConfig from .llms.morph.chat.transformation import MorphChatConfig from .llms.lambda_ai.chat.transformation import LambdaAIChatConfig from .llms.hyperbolic.chat.transformation import HyperbolicChatConfig +from .llms.vercel_ai_gateway.chat.transformation import VercelAIGatewayConfig from .main import * # type: ignore from .integrations import * from .llms.custom_httpx.async_client_cleanup import close_litellm_async_clients diff --git a/litellm/constants.py b/litellm/constants.py index b25e2ff0fb..1c4435d02f 100644 --- a/litellm/constants.py +++ b/litellm/constants.py @@ -281,6 +281,7 @@ LITELLM_CHAT_PROVIDERS = [ "v0", "morph", "lambda_ai", + "vercel_ai_gateway", ] LITELLM_EMBEDDING_PROVIDERS_SUPPORTING_INPUT_ARRAY_OF_TOKENS = [ @@ -413,6 +414,7 @@ openai_compatible_endpoints: List = [ "https://api.morphllm.com/v1", "https://api.lambda.ai/v1", "https://api.hyperbolic.xyz/v1", + "https://ai-gateway.vercel.sh/v1", ] @@ -454,6 +456,7 @@ openai_compatible_providers: List = [ "morph", "lambda_ai", "hyperbolic", + "vercel_ai_gateway", ] openai_text_completion_compatible_providers: List = ( [ # providers that support `/v1/completions` diff --git a/litellm/litellm_core_utils/get_llm_provider_logic.py b/litellm/litellm_core_utils/get_llm_provider_logic.py index 4e0a2efb0c..110e04eb72 100644 --- a/litellm/litellm_core_utils/get_llm_provider_logic.py +++ b/litellm/litellm_core_utils/get_llm_provider_logic.py @@ -246,6 +246,9 @@ def get_llm_provider( # noqa: PLR0915 elif endpoint == "https://api.hyperbolic.xyz/v1": custom_llm_provider = "hyperbolic" dynamic_api_key = get_secret_str("HYPERBOLIC_API_KEY") + elif endpoint == "https://ai-gateway.vercel.sh/v1": + custom_llm_provider = "vercel_ai_gateway" + dynamic_api_key = get_secret_str("VERCEL_AI_GATEWAY_API_KEY") if api_base is not None and not isinstance(api_base, str): raise Exception( @@ -718,6 +721,13 @@ def _get_openai_compatible_provider_info( # noqa: PLR0915 ) = litellm.HyperbolicChatConfig()._get_openai_compatible_provider_info( api_base, api_key ) + elif custom_llm_provider == "vercel_ai_gateway": + ( + api_base, + dynamic_api_key, + ) = litellm.VercelAIGatewayConfig()._get_openai_compatible_provider_info( + api_base, api_key + ) if api_base is not None and not isinstance(api_base, str): raise Exception("api base needs to be a string. api_base={}".format(api_base)) diff --git a/litellm/litellm_core_utils/get_supported_openai_params.py b/litellm/litellm_core_utils/get_supported_openai_params.py index f1901fa2ce..acb540fe5f 100644 --- a/litellm/litellm_core_utils/get_supported_openai_params.py +++ b/litellm/litellm_core_utils/get_supported_openai_params.py @@ -125,6 +125,8 @@ def get_supported_openai_params( # noqa: PLR0915 return litellm.AzureOpenAIConfig().get_supported_openai_params(model=model) elif custom_llm_provider == "openrouter": return litellm.OpenrouterConfig().get_supported_openai_params(model=model) + elif custom_llm_provider == "vercel_ai_gateway": + return litellm.VercelAIGatewayConfig().get_supported_openai_params(model=model) elif custom_llm_provider == "mistral" or custom_llm_provider == "codestral": # mistal and codestral api have the exact same params if request_type == "chat_completion": diff --git a/litellm/llms/vercel_ai_gateway/chat/transformation.py b/litellm/llms/vercel_ai_gateway/chat/transformation.py new file mode 100644 index 0000000000..f47b5f437e --- /dev/null +++ b/litellm/llms/vercel_ai_gateway/chat/transformation.py @@ -0,0 +1,112 @@ +""" +Support for OpenAI's `/v1/chat/completions` endpoint. + +Calls done in OpenAI/openai.py as Vercel AI Gateway is openai-compatible. + +Docs: https://vercel.com/docs/ai-gateway +""" + +from typing import Any, List, Optional, Tuple, Union + +import httpx + +from litellm.llms.base_llm.chat.transformation import BaseLLMException +from litellm.types.llms.openai import AllMessageValues +from litellm.secret_managers.main import get_secret_str +import litellm + +from ...openai.chat.gpt_transformation import OpenAIGPTConfig +from ..common_utils import VercelAIGatewayException + + +class VercelAIGatewayConfig(OpenAIGPTConfig): + @property + def custom_llm_provider(self) -> Optional[str]: + return "vercel_ai_gateway" + + def get_supported_openai_params(self, model: str) -> list: + base_params = super().get_supported_openai_params(model) + if "extra_body" not in base_params: + base_params.append("extra_body") + return base_params + + def _get_openai_compatible_provider_info( + self, api_base: Optional[str], api_key: Optional[str] + ) -> Tuple[Optional[str], Optional[str]]: + + api_base = ( + api_base + or get_secret_str("VERCEL_AI_GATEWAY_API_BASE") + or "https://ai-gateway.vercel.sh/v1" + ) + user_api_key = ( + api_key + or get_secret_str("VERCEL_AI_GATEWAY_API_KEY") + or get_secret_str("VERCEL_OIDC_TOKEN") + ) + return api_base, user_api_key + + def map_openai_params( + self, + non_default_params: dict, + optional_params: dict, + model: str, + drop_params: bool, + ) -> dict: + mapped_openai_params = super().map_openai_params( + non_default_params, optional_params, model, drop_params + ) + + # Vercel AI Gateway-only parameters + extra_body = {} + provider_options = non_default_params.pop("providerOptions", None) + + if provider_options is not None: + extra_body["providerOptions"] = provider_options + + mapped_openai_params["extra_body"] = extra_body # openai client supports `extra_body` param + return mapped_openai_params + + def transform_request( + self, + model: str, + messages: List[AllMessageValues], + optional_params: dict, + litellm_params: dict, + headers: dict, + ) -> dict: + """ + Transform the overall request to be sent to the API. + + Returns: + dict: The transformed request. Sent as the body of the API call. + """ + return super().transform_request( + model, messages, optional_params, litellm_params, headers + ) + + def get_error_class( + self, error_message: str, status_code: int, headers: Union[dict, httpx.Headers] + ) -> BaseLLMException: + return VercelAIGatewayException( + message=error_message, + status_code=status_code, + headers=headers, + ) + + def get_models( + self, api_key: Optional[str] = None, api_base: Optional[str] = None + ) -> List[str]: + api_base, _ = self._get_openai_compatible_provider_info(api_base, api_key) + + if api_base is None: + api_base = "https://ai-gateway.vercel.sh/v1" + + models_url = f"{api_base}/models" + response = litellm.module_level_client.get(url=models_url) + + if response.status_code != 200: + raise Exception(f"Failed to get models: {response.text}") + + models = response.json()["data"] + return [model["id"] for model in models] diff --git a/litellm/llms/vercel_ai_gateway/common_utils.py b/litellm/llms/vercel_ai_gateway/common_utils.py new file mode 100644 index 0000000000..93e792be05 --- /dev/null +++ b/litellm/llms/vercel_ai_gateway/common_utils.py @@ -0,0 +1,5 @@ +from litellm.llms.base_llm.chat.transformation import BaseLLMException + + +class VercelAIGatewayException(BaseLLMException): + pass diff --git a/litellm/main.py b/litellm/main.py index fb6204c5bf..bbede566dd 100644 --- a/litellm/main.py +++ b/litellm/main.py @@ -2561,6 +2561,70 @@ def completion( # type: ignore # noqa: PLR0915 logging.post_call( input=messages, api_key=openai.api_key, original_response=response ) + elif custom_llm_provider == "vercel_ai_gateway": + api_base = ( + api_base + or litellm.api_base + or get_secret_str("VERCEL_AI_GATEWAY_API_BASE") + or "https://ai-gateway.vercel.sh/v1" + ) + + api_key = ( + api_key + or litellm.api_key + or get_secret("VERCEL_AI_GATEWAY_API_KEY") + ) + + vercel_site_url = get_secret("VERCEL_SITE_URL") or "https://litellm.ai" + vercel_app_name = get_secret("VERCEL_APP_NAME") or "liteLLM" + + vercel_headers = { + "http-referer": vercel_site_url, + "x-title": vercel_app_name, + } + + _headers = headers or litellm.headers + if _headers: + vercel_headers.update(_headers) + + headers = vercel_headers + + ## Load Config + config = litellm.VercelAIGatewayConfig.get_config() + for k, v in config.items(): + if k == "extra_body": + # we use openai 'extra_body' to pass vercel specific params - providerOptions + if "extra_body" in optional_params: + optional_params[k].update(v) + else: + optional_params[k] = v + elif k not in optional_params: + optional_params[k] = v + + data = {"model": model, "messages": messages, **optional_params} + + ## COMPLETION CALL + response = base_llm_http_handler.completion( + model=model, + stream=stream, + messages=messages, + acompletion=acompletion, + api_base=api_base, + model_response=model_response, + optional_params=optional_params, + litellm_params=litellm_params, + custom_llm_provider="vercel_ai_gateway", + timeout=timeout, + headers=headers, + encoding=encoding, + api_key=api_key, + logging_obj=logging, # model call logging done inside the class as we make need to modify I/O to fit aleph alpha's requirements + client=client, + ) + ## LOGGING + logging.post_call( + input=messages, api_key=openai.api_key, original_response=response + ) elif ( custom_llm_provider == "together_ai" or ("togethercomputer" in model) diff --git a/litellm/types/utils.py b/litellm/types/utils.py index a3e3b9e2f2..f0bc2aa732 100644 --- a/litellm/types/utils.py +++ b/litellm/types/utils.py @@ -2319,7 +2319,7 @@ class LlmProviders(str, Enum): HYPERBOLIC = "hyperbolic" RECRAFT = "recraft" AUTO_ROUTER = "auto_router" - + VERCEL_AI_GATEWAY = "vercel_ai_gateway" # Create a set of all provider values for quick lookup LlmProvidersSet = {provider.value for provider in LlmProviders} diff --git a/litellm/utils.py b/litellm/utils.py index 9a618a49a1..f9bbb04b49 100644 --- a/litellm/utils.py +++ b/litellm/utils.py @@ -2328,6 +2328,9 @@ def register_model(model_cost: Union[str, dict]): # noqa: PLR0915 split_string = key.split("/", 1) if key not in litellm.openrouter_models: litellm.openrouter_models.append(split_string[1]) + elif value.get("litellm_provider") == "vercel_ai_gateway": + if key not in litellm.vercel_ai_gateway_models: + litellm.vercel_ai_gateway_models.append(key) elif value.get("litellm_provider") == "vertex_ai-text-models": if key not in litellm.vertex_text_models: litellm.vertex_text_models.append(key) @@ -3150,6 +3153,7 @@ def pre_process_optional_params( and custom_llm_provider != "bedrock" and custom_llm_provider != "ollama_chat" and custom_llm_provider != "openrouter" + and custom_llm_provider != "vercel_ai_gateway" and custom_llm_provider != "nebius" and custom_llm_provider not in litellm.openai_compatible_providers ): @@ -3826,6 +3830,17 @@ def get_optional_params( # noqa: PLR0915 else False ), ) + elif custom_llm_provider == "vercel_ai_gateway": + optional_params = litellm.VercelAIGatewayConfig().map_openai_params( + non_default_params=non_default_params, + optional_params=optional_params, + model=model, + drop_params=( + drop_params + if drop_params is not None and isinstance(drop_params, bool) + else False + ), + ) elif custom_llm_provider == "watsonx": optional_params = litellm.IBMWatsonXChatConfig().map_openai_params( @@ -5209,6 +5224,11 @@ def validate_environment( # noqa: PLR0915 keys_in_environment = True else: missing_keys.append("OPENROUTER_API_KEY") + elif custom_llm_provider == "vercel_ai_gateway": + if "VERCEL_AI_GATEWAY_API_KEY" in os.environ: + keys_in_environment = True + else: + missing_keys.append("VERCEL_AI_GATEWAY_API_KEY") elif custom_llm_provider == "datarobot": if "DATAROBOT_API_TOKEN" in os.environ: keys_in_environment = True @@ -5426,6 +5446,12 @@ def validate_environment( # noqa: PLR0915 keys_in_environment = True else: missing_keys.append("OPENROUTER_API_KEY") + ## vercel_ai_gateway + elif model in litellm.vercel_ai_gateway_models: + if "VERCEL_AI_GATEWAY_API_KEY" in os.environ: + keys_in_environment = True + else: + missing_keys.append("VERCEL_AI_GATEWAY_API_KEY") ## datarobot elif model in litellm.datarobot_models: if "DATAROBOT_API_TOKEN" in os.environ: @@ -6790,6 +6816,8 @@ class ProviderConfigManager: return litellm.TogetherAIConfig() elif litellm.LlmProviders.OPENROUTER == provider: return litellm.OpenrouterConfig() + elif litellm.LlmProviders.VERCEL_AI_GATEWAY == provider: + return litellm.VercelAIGatewayConfig() elif litellm.LlmProviders.DATAROBOT == provider: return litellm.DataRobotConfig() elif litellm.LlmProviders.GEMINI == provider: diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index f027d8ec3d..e81c724c3a 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -3750,7 +3750,7 @@ "max_input_tokens": 131072, "max_output_tokens": 131072, "input_cost_per_token": 3.3e-06, - "output_cost_per_token": 16.5e-06, + "output_cost_per_token": 1.65e-05, "litellm_provider": "azure_ai", "mode": "chat", "supports_function_calling": true, @@ -3764,7 +3764,7 @@ "max_input_tokens": 131072, "max_output_tokens": 131072, "input_cost_per_token": 3e-06, - "output_cost_per_token": 15e-06, + "output_cost_per_token": 1.5e-05, "litellm_provider": "azure_ai", "mode": "chat", "supports_function_calling": true, @@ -3777,7 +3777,7 @@ "max_tokens": 131072, "max_input_tokens": 131072, "max_output_tokens": 131072, - "input_cost_per_token": 0.25e-06, + "input_cost_per_token": 2.5e-07, "output_cost_per_token": 1.27e-06, "litellm_provider": "azure_ai", "mode": "chat", @@ -3792,7 +3792,7 @@ "max_tokens": 131072, "max_input_tokens": 131072, "max_output_tokens": 131072, - "input_cost_per_token": 0.275e-06, + "input_cost_per_token": 2.75e-07, "output_cost_per_token": 1.38e-06, "litellm_provider": "azure_ai", "mode": "chat", @@ -7337,12 +7337,12 @@ "max_audio_length_hours": 8.4, "max_audio_per_prompt": 1, "max_pdf_size_mb": 30, - "input_cost_per_token": 3.5e-07, + "input_cost_per_token": 3.5e-07, "input_cost_per_audio_token": 2.1e-06, "input_cost_per_image": 2.1e-06, "input_cost_per_video_per_second": 2.1e-06, "output_cost_per_token": 1.5e-06, - "output_cost_per_audio_token": 8.5e-06, + "output_cost_per_audio_token": 8.5e-06, "litellm_provider": "gemini", "mode": "chat", "rpm": 10, @@ -9174,7 +9174,7 @@ "max_input_tokens": 128000, "max_output_tokens": 2048, "input_cost_per_token": 5e-06, - "output_cost_per_token": 16e-06, + "output_cost_per_token": 1.6e-05, "litellm_provider": "vertex_ai-llama_models", "mode": "chat", "supports_system_messages": true, @@ -10430,12 +10430,12 @@ "supports_tool_choice": true }, "openrouter/deepseek/deepseek-r1-0528": { - "max_tokens": 8192, + "max_tokens": 163840, "max_input_tokens": 65336, "max_output_tokens": 8192, - "input_cost_per_token": 5e-07, + "input_cost_per_token": 2.72e-07, "input_cost_per_token_cache_hit": 1.4e-07, - "output_cost_per_token": 2.15e-06, + "output_cost_per_token": 2.72e-07, "litellm_provider": "openrouter", "mode": "chat", "supports_function_calling": true, @@ -10444,24 +10444,24 @@ "supports_tool_choice": true, "supports_prompt_caching": true }, - "openrouter/bytedance/ui-tars-1.5-7b":{ - "max_tokens": 2048, + "openrouter/bytedance/ui-tars-1.5-7b": { + "max_tokens": 128000, "max_input_tokens": 131072, "max_output_tokens": 2048, - "input_cost_per_token": 0.1e-06, - "output_cost_per_token": 0.2e-06, + "input_cost_per_token": 1e-07, + "output_cost_per_token": 2e-07, "litellm_provider": "openrouter", "mode": "chat", "source": "https://openrouter.ai/api/v1/models/bytedance/ui-tars-1.5-7b", "supports_tool_choice": true }, "openrouter/deepseek/deepseek-r1": { - "max_tokens": 8192, + "max_tokens": 163840, "max_input_tokens": 65336, - "max_output_tokens": 8192, - "input_cost_per_token": 5.5e-07, + "max_output_tokens": 163840, + "input_cost_per_token": 4e-07, "input_cost_per_token_cache_hit": 1.4e-07, - "output_cost_per_token": 2.19e-06, + "output_cost_per_token": 2e-06, "litellm_provider": "openrouter", "mode": "chat", "supports_function_calling": true, @@ -10471,11 +10471,11 @@ "supports_prompt_caching": true }, "openrouter/deepseek/deepseek-chat": { - "max_tokens": 8192, + "max_tokens": 163840, "max_input_tokens": 65536, "max_output_tokens": 8192, - "input_cost_per_token": 1.4e-07, - "output_cost_per_token": 2.8e-07, + "input_cost_per_token": 2.72e-07, + "output_cost_per_token": 2.72e-07, "litellm_provider": "openrouter", "supports_prompt_caching": true, "mode": "chat", @@ -10501,9 +10501,9 @@ "supports_tool_choice": true }, "openrouter/google/gemini-2.5-pro": { - "max_tokens": 8192, + "max_tokens": 1048576, "max_input_tokens": 1048576, - "max_output_tokens": 8192, + "max_output_tokens": 65536, "max_images_per_prompt": 3000, "max_videos_per_prompt": 10, "max_video_length": 1, @@ -10520,15 +10520,16 @@ "supports_vision": true, "supports_response_schema": true, "supports_audio_output": true, - "supports_tool_choice": true + "supports_tool_choice": true, + "input_cost_per_image": 0.00516 }, "openrouter/google/gemini-pro-1.5": { - "max_tokens": 8192, + "max_tokens": 2000000, "max_input_tokens": 1000000, "max_output_tokens": 8192, - "input_cost_per_token": 2.5e-06, - "output_cost_per_token": 7.5e-06, - "input_cost_per_image": 0.00265, + "input_cost_per_token": 1.25e-06, + "output_cost_per_token": 5e-06, + "input_cost_per_image": 0.0006575, "litellm_provider": "openrouter", "mode": "chat", "supports_function_calling": true, @@ -10536,7 +10537,7 @@ "supports_tool_choice": true }, "openrouter/google/gemini-2.0-flash-001": { - "max_tokens": 8192, + "max_tokens": 1048576, "max_input_tokens": 1048576, "max_output_tokens": 8192, "max_images_per_prompt": 3000, @@ -10555,12 +10556,13 @@ "supports_vision": true, "supports_response_schema": true, "supports_audio_output": true, - "supports_tool_choice": true + "supports_tool_choice": true, + "input_cost_per_image": 2.58e-05 }, "openrouter/google/gemini-2.5-flash": { - "max_tokens": 8192, + "max_tokens": 1048576, "max_input_tokens": 1048576, - "max_output_tokens": 8192, + "max_output_tokens": 65535, "max_images_per_prompt": 3000, "max_videos_per_prompt": 10, "max_video_length": 1, @@ -10577,12 +10579,13 @@ "supports_vision": true, "supports_response_schema": true, "supports_audio_output": true, - "supports_tool_choice": true + "supports_tool_choice": true, + "input_cost_per_image": 0.001238 }, "openrouter/mistralai/mixtral-8x22b-instruct": { "max_tokens": 65536, - "input_cost_per_token": 6.5e-07, - "output_cost_per_token": 6.5e-07, + "input_cost_per_token": 9e-07, + "output_cost_per_token": 9e-07, "litellm_provider": "openrouter", "mode": "chat", "supports_tool_choice": true @@ -10593,7 +10596,8 @@ "output_cost_per_token": 1.5e-05, "litellm_provider": "openrouter", "mode": "chat", - "supports_tool_choice": true + "supports_tool_choice": true, + "max_output_tokens": 4000 }, "openrouter/databricks/dbrx-instruct": { "max_tokens": 32768, @@ -10612,7 +10616,8 @@ "mode": "chat", "supports_function_calling": true, "supports_vision": true, - "supports_tool_choice": true + "supports_tool_choice": true, + "max_output_tokens": 4096 }, "openrouter/anthropic/claude-3-5-haiku": { "max_tokens": 200000, @@ -10650,7 +10655,7 @@ }, "openrouter/anthropic/claude-3.5-sonnet": { "supports_computer_use": true, - "max_tokens": 8192, + "max_tokens": 200000, "max_input_tokens": 200000, "max_output_tokens": 8192, "input_cost_per_token": 3e-06, @@ -10661,11 +10666,12 @@ "supports_vision": true, "tool_use_system_prompt_tokens": 159, "supports_assistant_prefill": true, - "supports_tool_choice": true + "supports_tool_choice": true, + "input_cost_per_image": 0.0048 }, "openrouter/anthropic/claude-3.5-sonnet:beta": { "supports_computer_use": true, - "max_tokens": 8192, + "max_tokens": 200000, "max_input_tokens": 200000, "max_output_tokens": 8192, "input_cost_per_token": 3e-06, @@ -10675,13 +10681,14 @@ "supports_function_calling": true, "supports_vision": true, "tool_use_system_prompt_tokens": 159, - "supports_tool_choice": true + "supports_tool_choice": true, + "input_cost_per_image": 0.0048 }, "openrouter/anthropic/claude-3.7-sonnet": { "supports_computer_use": true, - "max_tokens": 8192, + "max_tokens": 200000, "max_input_tokens": 200000, - "max_output_tokens": 8192, + "max_output_tokens": 64000, "input_cost_per_token": 3e-06, "output_cost_per_token": 1.5e-05, "input_cost_per_image": 0.0048, @@ -10696,9 +10703,9 @@ }, "openrouter/anthropic/claude-3.7-sonnet:beta": { "supports_computer_use": true, - "max_tokens": 8192, + "max_tokens": 200000, "max_input_tokens": 200000, - "max_output_tokens": 8192, + "max_output_tokens": 128000, "input_cost_per_token": 3e-06, "output_cost_per_token": 1.5e-05, "input_cost_per_image": 0.0048, @@ -10719,13 +10726,14 @@ "mode": "chat", "supports_function_calling": true, "supports_vision": true, - "supports_tool_choice": true + "supports_tool_choice": true, + "max_output_tokens": 4096 }, "openrouter/anthropic/claude-sonnet-4": { "supports_computer_use": true, - "max_tokens": 8192, + "max_tokens": 200000, "max_input_tokens": 200000, - "max_output_tokens": 8192, + "max_output_tokens": 64000, "input_cost_per_token": 3e-06, "output_cost_per_token": 1.5e-05, "input_cost_per_image": 0.0048, @@ -10739,25 +10747,26 @@ "supports_tool_choice": true }, "openrouter/mistralai/mistral-large": { - "max_tokens": 32000, - "input_cost_per_token": 8e-06, - "output_cost_per_token": 2.4e-05, + "max_tokens": 128000, + "input_cost_per_token": 2e-06, + "output_cost_per_token": 6e-06, "litellm_provider": "openrouter", "mode": "chat", "supports_tool_choice": true }, "openrouter/mistralai/mistral-small-3.1-24b-instruct": { - "max_tokens": 32000, - "input_cost_per_token": 1e-07, - "output_cost_per_token": 3e-07, + "max_tokens": 96000, + "input_cost_per_token": 2.7e-08, + "output_cost_per_token": 2.7e-08, "litellm_provider": "openrouter", "mode": "chat", - "supports_tool_choice": true + "supports_tool_choice": true, + "max_output_tokens": 96000 }, "openrouter/mistralai/mistral-small-3.2-24b-instruct": { - "max_tokens": 32000, - "input_cost_per_token": 1e-07, - "output_cost_per_token": 3e-07, + "max_tokens": 128000, + "input_cost_per_token": 5e-08, + "output_cost_per_token": 1e-07, "litellm_provider": "openrouter", "mode": "chat", "supports_tool_choice": true @@ -10815,14 +10824,15 @@ }, "openrouter/meta-llama/llama-3-70b-instruct": { "max_tokens": 8192, - "input_cost_per_token": 5.9e-07, - "output_cost_per_token": 7.9e-07, + "input_cost_per_token": 3e-07, + "output_cost_per_token": 4e-07, "litellm_provider": "openrouter", "mode": "chat", - "supports_tool_choice": true + "supports_tool_choice": true, + "max_output_tokens": 16384 }, "openrouter/openai/o1": { - "max_tokens": 100000, + "max_tokens": 200000, "max_input_tokens": 200000, "max_output_tokens": 100000, "input_cost_per_token": 1.5e-05, @@ -10836,14 +10846,15 @@ "supports_prompt_caching": true, "supports_system_messages": true, "supports_response_schema": true, - "supports_tool_choice": true + "supports_tool_choice": true, + "input_cost_per_image": 0.021675 }, "openrouter/openai/o1-mini": { - "max_tokens": 65536, + "max_tokens": 128000, "max_input_tokens": 128000, "max_output_tokens": 65536, - "input_cost_per_token": 3e-06, - "output_cost_per_token": 1.2e-05, + "input_cost_per_token": 1.1e-06, + "output_cost_per_token": 4.4e-06, "litellm_provider": "openrouter", "mode": "chat", "supports_function_calling": true, @@ -10852,11 +10863,11 @@ "supports_tool_choice": true }, "openrouter/openai/o1-mini-2024-09-12": { - "max_tokens": 65536, + "max_tokens": 128000, "max_input_tokens": 128000, "max_output_tokens": 65536, - "input_cost_per_token": 3e-06, - "output_cost_per_token": 1.2e-05, + "input_cost_per_token": 1.1e-06, + "output_cost_per_token": 4.4e-06, "litellm_provider": "openrouter", "mode": "chat", "supports_function_calling": true, @@ -10865,7 +10876,7 @@ "supports_tool_choice": true }, "openrouter/openai/o1-preview": { - "max_tokens": 32768, + "max_tokens": 128000, "max_input_tokens": 128000, "max_output_tokens": 32768, "input_cost_per_token": 1.5e-05, @@ -10878,7 +10889,7 @@ "supports_tool_choice": true }, "openrouter/openai/o1-preview-2024-09-12": { - "max_tokens": 32768, + "max_tokens": 128000, "max_input_tokens": 128000, "max_output_tokens": 32768, "input_cost_per_token": 1.5e-05, @@ -10891,9 +10902,9 @@ "supports_tool_choice": true }, "openrouter/openai/o3-mini": { - "max_tokens": 65536, + "max_tokens": 200000, "max_input_tokens": 128000, - "max_output_tokens": 65536, + "max_output_tokens": 100000, "input_cost_per_token": 1.1e-06, "output_cost_per_token": 4.4e-06, "litellm_provider": "openrouter", @@ -10905,9 +10916,9 @@ "supports_tool_choice": true }, "openrouter/openai/o3-mini-high": { - "max_tokens": 65536, + "max_tokens": 200000, "max_input_tokens": 128000, - "max_output_tokens": 65536, + "max_output_tokens": 100000, "input_cost_per_token": 1.1e-06, "output_cost_per_token": 4.4e-06, "litellm_provider": "openrouter", @@ -10919,9 +10930,9 @@ "supports_tool_choice": true }, "openrouter/openai/gpt-4o": { - "max_tokens": 4096, + "max_tokens": 128000, "max_input_tokens": 128000, - "max_output_tokens": 4096, + "max_output_tokens": 16384, "input_cost_per_token": 2.5e-06, "output_cost_per_token": 1e-05, "litellm_provider": "openrouter", @@ -10929,10 +10940,11 @@ "supports_function_calling": true, "supports_parallel_function_calling": true, "supports_vision": true, - "supports_tool_choice": true + "supports_tool_choice": true, + "input_cost_per_image": 0.003613 }, "openrouter/openai/gpt-4o-2024-05-13": { - "max_tokens": 4096, + "max_tokens": 128000, "max_input_tokens": 128000, "max_output_tokens": 4096, "input_cost_per_token": 5e-06, @@ -10942,7 +10954,8 @@ "supports_function_calling": true, "supports_parallel_function_calling": true, "supports_vision": true, - "supports_tool_choice": true + "supports_tool_choice": true, + "input_cost_per_image": 0.007225 }, "openrouter/openai/gpt-4-vision-preview": { "max_tokens": 130000, @@ -10956,28 +10969,31 @@ "supports_tool_choice": true }, "openrouter/openai/gpt-3.5-turbo": { - "max_tokens": 4095, - "input_cost_per_token": 1.5e-06, - "output_cost_per_token": 2e-06, + "max_tokens": 16385, + "input_cost_per_token": 5e-07, + "output_cost_per_token": 1.5e-06, "litellm_provider": "openrouter", "mode": "chat", - "supports_tool_choice": true + "supports_tool_choice": true, + "max_output_tokens": 4096 }, "openrouter/openai/gpt-3.5-turbo-16k": { - "max_tokens": 16383, + "max_tokens": 16385, "input_cost_per_token": 3e-06, "output_cost_per_token": 4e-06, "litellm_provider": "openrouter", "mode": "chat", - "supports_tool_choice": true + "supports_tool_choice": true, + "max_output_tokens": 4096 }, "openrouter/openai/gpt-4": { - "max_tokens": 8192, + "max_tokens": 8191, "input_cost_per_token": 3e-05, "output_cost_per_token": 6e-05, "litellm_provider": "openrouter", "mode": "chat", - "supports_tool_choice": true + "supports_tool_choice": true, + "max_output_tokens": 4096 }, "openrouter/anthropic/claude-instant-v1": { "max_tokens": 100000, @@ -10998,7 +11014,7 @@ "supports_tool_choice": true }, "openrouter/anthropic/claude-3-opus": { - "max_tokens": 4096, + "max_tokens": 200000, "max_input_tokens": 200000, "max_output_tokens": 4096, "input_cost_per_token": 1.5e-05, @@ -11008,7 +11024,8 @@ "supports_function_calling": true, "supports_vision": true, "tool_use_system_prompt_tokens": 395, - "supports_tool_choice": true + "supports_tool_choice": true, + "input_cost_per_image": 0.024 }, "openrouter/google/palm-2-chat-bison": { "max_tokens": 25804, @@ -11060,16 +11077,17 @@ }, "openrouter/mancer/weaver": { "max_tokens": 8000, - "input_cost_per_token": 5.625e-06, - "output_cost_per_token": 5.625e-06, + "input_cost_per_token": 1.5e-06, + "output_cost_per_token": 1.5e-06, "litellm_provider": "openrouter", "mode": "chat", - "supports_tool_choice": true + "supports_tool_choice": true, + "max_output_tokens": 1000 }, "openrouter/gryphe/mythomax-l2-13b": { - "max_tokens": 8192, - "input_cost_per_token": 1.875e-06, - "output_cost_per_token": 1.875e-06, + "max_tokens": 4096, + "input_cost_per_token": 6e-08, + "output_cost_per_token": 6e-08, "litellm_provider": "openrouter", "mode": "chat", "supports_tool_choice": true @@ -11084,62 +11102,66 @@ }, "openrouter/undi95/remm-slerp-l2-13b": { "max_tokens": 6144, - "input_cost_per_token": 1.875e-06, - "output_cost_per_token": 1.875e-06, + "input_cost_per_token": 7e-07, + "output_cost_per_token": 1e-06, "litellm_provider": "openrouter", "mode": "chat", "supports_tool_choice": true }, "openrouter/pygmalionai/mythalion-13b": { "max_tokens": 4096, - "input_cost_per_token": 1.875e-06, - "output_cost_per_token": 1.875e-06, + "input_cost_per_token": 8e-07, + "output_cost_per_token": 1.2e-06, "litellm_provider": "openrouter", "mode": "chat", - "supports_tool_choice": true + "supports_tool_choice": true, + "max_output_tokens": 4096 }, "openrouter/mistralai/mistral-7b-instruct": { - "max_tokens": 8192, - "input_cost_per_token": 1.3e-07, - "output_cost_per_token": 1.3e-07, + "max_tokens": 32768, + "input_cost_per_token": 2.8e-08, + "output_cost_per_token": 5.4e-08, "litellm_provider": "openrouter", "mode": "chat", - "supports_tool_choice": true + "supports_tool_choice": true, + "max_output_tokens": 16384 }, "openrouter/mistralai/mistral-7b-instruct:free": { - "max_tokens": 8192, + "max_tokens": 32768, "input_cost_per_token": 0.0, "output_cost_per_token": 0.0, "litellm_provider": "openrouter", "mode": "chat", - "supports_tool_choice": true + "supports_tool_choice": true, + "max_output_tokens": 16384 }, "openrouter/qwen/qwen-2.5-coder-32b-instruct": { - "max_tokens": 33792, + "max_tokens": 32768, "max_input_tokens": 33792, - "max_output_tokens": 33792, - "input_cost_per_token": 1.8e-07, - "output_cost_per_token": 1.8e-07, + "max_output_tokens": 16384, + "input_cost_per_token": 6e-08, + "output_cost_per_token": 1.5e-07, "litellm_provider": "openrouter", "mode": "chat", "supports_tool_choice": true }, "openrouter/qwen/qwen-vl-plus": { - "max_tokens": 8192, + "max_tokens": 7500, "max_input_tokens": 8192, - "max_output_tokens": 2048, - "input_cost_per_token": 0.21e-06, - "output_cost_per_token": 0.63e-06, + "max_output_tokens": 1500, + "input_cost_per_token": 2.1e-07, + "output_cost_per_token": 6.3e-07, "litellm_provider": "openrouter", "mode": "chat", - "supports_tool_choice": true + "supports_tool_choice": true, + "input_cost_per_image": 0.0002688 }, "openrouter/qwen/qwen3-coder": { - "max_tokens": 1000000, + "max_tokens": 262144, "max_input_tokens": 1000000, "max_output_tokens": 1000000, - "input_cost_per_token": 1e-06, - "output_cost_per_token": 5e-06, + "input_cost_per_token": 3e-07, + "output_cost_per_token": 1.2e-06, "litellm_provider": "openrouter", "source": "https://openrouter.ai/qwen/qwen3-coder", "mode": "chat", @@ -14713,7 +14735,7 @@ "max_tokens": 131072, "max_input_tokens": 131072, "max_output_tokens": 16384, - "input_cost_per_token": 0.6e-06, + "input_cost_per_token": 6e-07, "output_cost_per_token": 2.5e-06, "litellm_provider": "fireworks_ai", "mode": "chat", @@ -17395,5 +17417,2745 @@ "supports_vision": false, "supports_system_messages": true, "supports_tool_choice": false + }, + "openrouter/mistralai/mixtral-8x7b-instruct": { + "max_tokens": 32768, + "input_cost_per_token": 8e-08, + "max_output_tokens": 16384, + "output_cost_per_token": 2.4e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/amazon/nova-lite": { + "max_tokens": 300000, + "input_cost_per_token": 6e-08, + "output_cost_per_token": 2.4e-07, + "max_input_tokens": 300000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/openai/gpt-4-turbo-preview": { + "max_tokens": 128000, + "input_cost_per_token": 1e-05, + "max_output_tokens": 4096, + "output_cost_per_token": 3e-05, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/anthropic/claude-3.5-sonnet-20240620": { + "max_tokens": 200000, + "input_cost_per_token": 3e-06, + "max_output_tokens": 8192, + "output_cost_per_token": 1.5e-05, + "input_cost_per_image": 0.0048, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/anthracite-org/magnum-v4-72b": { + "max_tokens": 16384, + "input_cost_per_token": 2.5e-06, + "max_output_tokens": 1024, + "output_cost_per_token": 3e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/neversleep/llama-3.1-lumimaid-8b": { + "max_tokens": 32768, + "input_cost_per_token": 1.8e-07, + "output_cost_per_token": 1e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/mistralai/mistral-medium-3": { + "max_tokens": 131072, + "input_cost_per_token": 4e-07, + "output_cost_per_token": 2e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/nousresearch/hermes-2-pro-llama-3-8b": { + "max_tokens": 131072, + "input_cost_per_token": 2.5e-08, + "max_output_tokens": 131072, + "output_cost_per_token": 4e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/cognitivecomputations/dolphin3.0-r1-mistral-24b:free": { + "max_tokens": 32768, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/cohere/command-r-08-2024": { + "max_tokens": 128000, + "input_cost_per_token": 1.5e-07, + "max_output_tokens": 4000, + "output_cost_per_token": 6e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/mistralai/mistral-small-24b-instruct-2501:free": { + "max_tokens": 32768, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/qwen/qwen-turbo": { + "max_tokens": 1000000, + "input_cost_per_token": 5e-08, + "max_output_tokens": 8192, + "output_cost_per_token": 2e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/inflection/inflection-3-productivity": { + "max_tokens": 8000, + "input_cost_per_token": 2.5e-06, + "max_output_tokens": 1024, + "output_cost_per_token": 1e-05, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/google/gemini-2.5-flash": { + "max_tokens": 1000000, + "input_cost_per_token": 3e-07, + "output_cost_per_token": 2.5e-06, + "max_input_tokens": 1000000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/meta-llama/llama-3.1-405b-instruct:free": { + "max_tokens": 65536, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/vercel/v0-1.5-md": { + "max_tokens": 128000, + "input_cost_per_token": 3e-06, + "output_cost_per_token": 1.5e-05, + "max_input_tokens": 128000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "vercel_ai_gateway/openai/o3": { + "max_tokens": 200000, + "input_cost_per_token": 2e-06, + "output_cost_per_token": 8e-06, + "max_input_tokens": 200000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/google/gemini-2.5-pro-preview-05-06": { + "max_tokens": 1048576, + "input_cost_per_token": 1.25e-06, + "max_output_tokens": 65535, + "output_cost_per_token": 1e-05, + "input_cost_per_image": 0.00516, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/inception/mercury-coder-small": { + "max_tokens": 32000, + "input_cost_per_token": 2.5e-07, + "output_cost_per_token": 1e-06, + "max_input_tokens": 32000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/meta-llama/llama-3.2-3b-instruct": { + "max_tokens": 20000, + "input_cost_per_token": 3e-09, + "max_output_tokens": 20000, + "output_cost_per_token": 6e-09, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/sao10k/fimbulvetr-11b-v2": { + "max_tokens": 4096, + "input_cost_per_token": 8e-07, + "max_output_tokens": 4096, + "output_cost_per_token": 1.2e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/deepseek/deepseek-r1-distill-llama-70b": { + "max_tokens": 131072, + "input_cost_per_token": 7.5e-07, + "output_cost_per_token": 9.9e-07, + "max_input_tokens": 131072, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "vercel_ai_gateway/mistral/pixtral-12b": { + "max_tokens": 128000, + "input_cost_per_token": 1.5e-07, + "output_cost_per_token": 1.5e-07, + "max_input_tokens": 128000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/infermatic/mn-inferor-12b": { + "max_tokens": 16384, + "input_cost_per_token": 8e-07, + "max_output_tokens": 4096, + "output_cost_per_token": 1.2e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/sao10k/l3.3-euryale-70b": { + "max_tokens": 131072, + "input_cost_per_token": 6.5e-07, + "output_cost_per_token": 7.5e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/mistralai/mistral-nemo:free": { + "max_tokens": 131072, + "input_cost_per_token": 0.0, + "max_output_tokens": 128000, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/mistralai/mistral-small-3.2-24b-instruct:free": { + "max_tokens": 96000, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/meta-llama/llama-guard-4-12b": { + "max_tokens": 163840, + "input_cost_per_token": 5e-08, + "output_cost_per_token": 5e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/microsoft/phi-4": { + "max_tokens": 16384, + "input_cost_per_token": 6e-08, + "output_cost_per_token": 1.4e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/z-ai/glm-4.5": { + "max_tokens": 131072, + "input_cost_per_token": 2e-07, + "output_cost_per_token": 2e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/microsoft/phi-3.5-mini-128k-instruct": { + "max_tokens": 128000, + "input_cost_per_token": 1e-07, + "output_cost_per_token": 1e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/qwen/qwen3-14b:free": { + "max_tokens": 40960, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/scb10x/llama3.1-typhoon2-70b-instruct": { + "max_tokens": 8192, + "input_cost_per_token": 8.8e-07, + "output_cost_per_token": 8.8e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/alpindale/goliath-120b": { + "max_tokens": 6144, + "input_cost_per_token": 9e-06, + "output_cost_per_token": 1.1e-05, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/moonshotai/kimi-k2:free": { + "max_tokens": 32768, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/nvidia/llama-3.3-nemotron-super-49b-v1": { + "max_tokens": 131072, + "input_cost_per_token": 1.3e-07, + "output_cost_per_token": 4e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/deepseek/deepseek-r1": { + "max_tokens": 64000, + "input_cost_per_token": 5.5e-07, + "output_cost_per_token": 2.19e-06, + "max_input_tokens": 64000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/arcee-ai/virtuoso-large": { + "max_tokens": 131072, + "input_cost_per_token": 7.5e-07, + "max_output_tokens": 64000, + "output_cost_per_token": 1.2e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/mistralai/magistral-small-2506": { + "max_tokens": 40000, + "input_cost_per_token": 5e-07, + "max_output_tokens": 40000, + "output_cost_per_token": 1.5e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/moonshotai/kimi-k2": { + "max_tokens": 32768, + "input_cost_per_token": 8.78e-08, + "output_cost_per_token": 8.78e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/qwen/qwen3-30b-a3b": { + "max_tokens": 40960, + "input_cost_per_token": 8e-08, + "max_output_tokens": 40960, + "output_cost_per_token": 2.9e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/openai/gpt-4.1": { + "max_tokens": 1047576, + "input_cost_per_token": 2e-06, + "max_output_tokens": 32768, + "output_cost_per_token": 8e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/aion-labs/aion-1.0-mini": { + "max_tokens": 131072, + "input_cost_per_token": 7e-07, + "max_output_tokens": 32768, + "output_cost_per_token": 1.4e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/qwen/qwen3-coder:free": { + "max_tokens": 262144, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/liquid/lfm-3b": { + "max_tokens": 32768, + "input_cost_per_token": 2e-08, + "output_cost_per_token": 2e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/anthropic/claude-4-opus": { + "max_tokens": 200000, + "input_cost_per_token": 1.5e-05, + "output_cost_per_token": 7.5e-05, + "max_input_tokens": 200000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/google/gemma-3n-e4b-it:free": { + "max_tokens": 8192, + "input_cost_per_token": 0.0, + "max_output_tokens": 2048, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/meta/llama-3-8b": { + "max_tokens": 8192, + "input_cost_per_token": 5e-08, + "output_cost_per_token": 8e-08, + "max_input_tokens": 8192, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/deepseek/deepseek-r1-0528-qwen3-8b:free": { + "max_tokens": 131072, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/google/gemini-flash-1.5-8b": { + "max_tokens": 1000000, + "input_cost_per_token": 3.75e-08, + "max_output_tokens": 8192, + "output_cost_per_token": 1.5e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/cohere/command-r-03-2024": { + "max_tokens": 128000, + "input_cost_per_token": 5e-07, + "max_output_tokens": 4000, + "output_cost_per_token": 1.5e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/google/gemini-2.0-flash-lite-001": { + "max_tokens": 1048576, + "input_cost_per_token": 7.5e-08, + "max_output_tokens": 8192, + "output_cost_per_token": 3e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/meta-llama/llama-3.2-3b-instruct:free": { + "max_tokens": 131072, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/arcee-ai/maestro-reasoning": { + "max_tokens": 131072, + "input_cost_per_token": 9e-07, + "max_output_tokens": 32000, + "output_cost_per_token": 3.3e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/mistral/ministral-3b": { + "max_tokens": 128000, + "input_cost_per_token": 4e-08, + "output_cost_per_token": 4e-08, + "max_input_tokens": 128000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/google/gemini-2.5-flash-lite-preview-06-17": { + "max_tokens": 1048576, + "input_cost_per_token": 1e-07, + "max_output_tokens": 65535, + "output_cost_per_token": 4e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/sao10k/l3-lunaris-8b": { + "max_tokens": 8192, + "input_cost_per_token": 2e-08, + "output_cost_per_token": 5e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/meta/llama-4-maverick": { + "max_tokens": 131072, + "input_cost_per_token": 2e-07, + "output_cost_per_token": 6e-07, + "max_input_tokens": 131072, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/microsoft/mai-ds-r1": { + "max_tokens": 163840, + "input_cost_per_token": 3.02e-07, + "output_cost_per_token": 3.02e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/morph/morph-v3-large": { + "max_tokens": 32000, + "input_cost_per_token": 1.2e-06, + "max_output_tokens": 16000, + "output_cost_per_token": 2.7e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/deepseek/deepseek-v3": { + "max_tokens": 128000, + "input_cost_per_token": 9e-07, + "output_cost_per_token": 9e-07, + "max_input_tokens": 128000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/qwen/qwen3-8b:free": { + "max_tokens": 40960, + "input_cost_per_token": 0.0, + "max_output_tokens": 40960, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/qwen/qwen-2.5-72b-instruct": { + "max_tokens": 32768, + "input_cost_per_token": 1.01e-07, + "output_cost_per_token": 1.01e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/x-ai/grok-4": { + "max_tokens": 256000, + "input_cost_per_token": 3e-06, + "output_cost_per_token": 1.5e-05, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/thedrummer/unslopnemo-12b": { + "max_tokens": 32768, + "input_cost_per_token": 4e-07, + "output_cost_per_token": 4e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/qwen/qwen2.5-vl-32b-instruct": { + "max_tokens": 128000, + "input_cost_per_token": 2e-07, + "output_cost_per_token": 6e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/qwen/qwen-2-72b-instruct": { + "max_tokens": 32768, + "input_cost_per_token": 9e-07, + "max_output_tokens": 4096, + "output_cost_per_token": 9e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/openai/gpt-4.1-mini": { + "max_tokens": 1047576, + "input_cost_per_token": 4e-07, + "max_output_tokens": 32768, + "output_cost_per_token": 1.6e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/nousresearch/nous-hermes-2-mixtral-8x7b-dpo": { + "max_tokens": 32768, + "input_cost_per_token": 6e-07, + "max_output_tokens": 2048, + "output_cost_per_token": 6e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/rekaai/reka-flash-3": { + "max_tokens": 32768, + "input_cost_per_token": 1.3e-08, + "output_cost_per_token": 1.3e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/qwen/qwen-2.5-7b-instruct": { + "max_tokens": 32768, + "input_cost_per_token": 4e-08, + "max_output_tokens": 16384, + "output_cost_per_token": 1e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/ai21/jamba-1.6-large": { + "max_tokens": 256000, + "input_cost_per_token": 2e-06, + "max_output_tokens": 4096, + "output_cost_per_token": 8e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/meta-llama/llama-3.1-405b-instruct": { + "max_tokens": 32768, + "input_cost_per_token": 8e-07, + "max_output_tokens": 16384, + "output_cost_per_token": 8e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/mistralai/devstral-small-2505": { + "max_tokens": 32768, + "input_cost_per_token": 3e-08, + "output_cost_per_token": 3e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/openai/gpt-4-0314": { + "max_tokens": 8191, + "input_cost_per_token": 3e-05, + "max_output_tokens": 4096, + "output_cost_per_token": 6e-05, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/shisa-ai/shisa-v2-llama3.3-70b": { + "max_tokens": 32768, + "input_cost_per_token": 3e-08, + "output_cost_per_token": 3e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/meta/llama-3.1-8b": { + "max_tokens": 128000, + "input_cost_per_token": 5e-08, + "output_cost_per_token": 8e-08, + "max_input_tokens": 128000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/openai/gpt-4o-mini-search-preview": { + "max_tokens": 128000, + "input_cost_per_token": 1.5e-07, + "max_output_tokens": 16384, + "output_cost_per_token": 6e-07, + "input_cost_per_image": 0.000217, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/meta-llama/llama-3.2-11b-vision-instruct": { + "max_tokens": 131072, + "input_cost_per_token": 4.9e-08, + "max_output_tokens": 16384, + "output_cost_per_token": 4.9e-08, + "input_cost_per_image": 7.948e-05, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/deepseek/deepseek-chat-v3-0324:free": { + "max_tokens": 32768, + "input_cost_per_token": 0.0, + "max_output_tokens": 16384, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/minimax/minimax-m1": { + "max_tokens": 1000000, + "input_cost_per_token": 3e-07, + "max_output_tokens": 40000, + "output_cost_per_token": 1.65e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/google/gemma-3-12b-it:free": { + "max_tokens": 96000, + "input_cost_per_token": 0.0, + "max_output_tokens": 8192, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/openai/gpt-3.5-turbo-instruct": { + "max_tokens": 4095, + "input_cost_per_token": 1.5e-06, + "max_output_tokens": 4096, + "output_cost_per_token": 2e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/sao10k/l3-euryale-70b": { + "max_tokens": 8192, + "input_cost_per_token": 1.48e-06, + "max_output_tokens": 8192, + "output_cost_per_token": 1.48e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/meta-llama/llama-guard-2-8b": { + "max_tokens": 8192, + "input_cost_per_token": 2e-07, + "output_cost_per_token": 2e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/openai/gpt-4o-mini": { + "max_tokens": 128000, + "input_cost_per_token": 1.5e-07, + "max_output_tokens": 16384, + "output_cost_per_token": 6e-07, + "input_cost_per_image": 0.000217, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/deepseek/deepseek-v3-base": { + "max_tokens": 163840, + "input_cost_per_token": 3.02e-07, + "output_cost_per_token": 3.02e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/deepseek/deepseek-r1-0528:free": { + "max_tokens": 163840, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/moonshotai/kimi-vl-a3b-thinking:free": { + "max_tokens": 131072, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/qwen/qwen3-30b-a3b:free": { + "max_tokens": 40960, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/mistralai/devstral-medium": { + "max_tokens": 131072, + "input_cost_per_token": 4e-07, + "output_cost_per_token": 2e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/qwen/qwen3-235b-a22b-thinking-2507": { + "max_tokens": 262144, + "input_cost_per_token": 1.179e-07, + "output_cost_per_token": 1.179e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/meta-llama/llama-3.1-70b-instruct": { + "max_tokens": 131072, + "input_cost_per_token": 1e-07, + "max_output_tokens": 16384, + "output_cost_per_token": 2.8e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/nvidia/llama-3.1-nemotron-70b-instruct": { + "max_tokens": 131072, + "input_cost_per_token": 1.2e-07, + "max_output_tokens": 131072, + "output_cost_per_token": 3e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/openai/gpt-4o-search-preview": { + "max_tokens": 128000, + "input_cost_per_token": 2.5e-06, + "max_output_tokens": 16384, + "output_cost_per_token": 1e-05, + "input_cost_per_image": 0.003613, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/microsoft/wizardlm-2-8x22b": { + "max_tokens": 65536, + "input_cost_per_token": 4.8e-07, + "max_output_tokens": 65536, + "output_cost_per_token": 4.8e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/perplexity/sonar-reasoning-pro": { + "max_tokens": 128000, + "input_cost_per_token": 2e-06, + "output_cost_per_token": 8e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/anthropic/claude-3.7-sonnet:thinking": { + "max_tokens": 200000, + "input_cost_per_token": 3e-06, + "max_output_tokens": 64000, + "output_cost_per_token": 1.5e-05, + "input_cost_per_image": 0.0048, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/qwen/qwen2.5-vl-72b-instruct:free": { + "max_tokens": 32768, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/google/gemma-3-27b-it:free": { + "max_tokens": 96000, + "input_cost_per_token": 0.0, + "max_output_tokens": 8192, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/mistralai/mistral-saba": { + "max_tokens": 32768, + "input_cost_per_token": 2e-07, + "output_cost_per_token": 6e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/cohere/command-a": { + "max_tokens": 256000, + "input_cost_per_token": 2.5e-06, + "output_cost_per_token": 1e-05, + "max_input_tokens": 256000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/nvidia/llama-3.1-nemotron-ultra-253b-v1": { + "max_tokens": 131072, + "input_cost_per_token": 6e-07, + "output_cost_per_token": 1.8e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/x-ai/grok-2-1212": { + "max_tokens": 131072, + "input_cost_per_token": 2e-06, + "output_cost_per_token": 1e-05, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/x-ai/grok-2-vision-1212": { + "max_tokens": 32768, + "input_cost_per_token": 2e-06, + "output_cost_per_token": 1e-05, + "input_cost_per_image": 0.0036, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/mistralai/mistral-large-2407": { + "max_tokens": 131072, + "input_cost_per_token": 2e-06, + "output_cost_per_token": 6e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/cognitivecomputations/dolphin3.0-r1-mistral-24b": { + "max_tokens": 32768, + "input_cost_per_token": 1.3e-08, + "output_cost_per_token": 1.3e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/openai/gpt-4o-mini": { + "max_tokens": 128000, + "input_cost_per_token": 1.5e-07, + "output_cost_per_token": 6e-07, + "max_input_tokens": 128000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/openai/o4-mini": { + "max_tokens": 200000, + "input_cost_per_token": 1.1e-06, + "max_output_tokens": 100000, + "output_cost_per_token": 4.4e-06, + "input_cost_per_image": 0.0008415, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/qwen/qwen3-4b:free": { + "max_tokens": 40960, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/qwen/qwq-32b:free": { + "max_tokens": 32768, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/amazon/nova-micro": { + "max_tokens": 128000, + "input_cost_per_token": 3.5e-08, + "output_cost_per_token": 1.4e-07, + "max_input_tokens": 128000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/qwen/qwen-2.5-72b-instruct:free": { + "max_tokens": 32768, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/nousresearch/hermes-3-llama-3.1-405b": { + "max_tokens": 131072, + "input_cost_per_token": 7e-07, + "max_output_tokens": 16384, + "output_cost_per_token": 8e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/neversleep/noromaid-20b": { + "max_tokens": 8192, + "input_cost_per_token": 1.25e-06, + "max_output_tokens": 2048, + "output_cost_per_token": 2e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/thudm/glm-z1-32b:free": { + "max_tokens": 32768, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/mistralai/mistral-large-2411": { + "max_tokens": 131072, + "input_cost_per_token": 2e-06, + "output_cost_per_token": 6e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/arcee-ai/coder-large": { + "max_tokens": 32768, + "input_cost_per_token": 5e-07, + "output_cost_per_token": 8e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/cohere/command-r7b-12-2024": { + "max_tokens": 128000, + "input_cost_per_token": 3.75e-08, + "max_output_tokens": 4000, + "output_cost_per_token": 1.5e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/thedrummer/anubis-pro-105b-v1": { + "max_tokens": 131072, + "input_cost_per_token": 5e-07, + "max_output_tokens": 131072, + "output_cost_per_token": 1e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/inception/mercury-coder": { + "max_tokens": 32000, + "input_cost_per_token": 2.5e-07, + "output_cost_per_token": 1e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/deepseek/deepseek-r1-distill-qwen-14b": { + "max_tokens": 64000, + "input_cost_per_token": 1.5e-07, + "max_output_tokens": 32000, + "output_cost_per_token": 1.5e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/aion-labs/aion-rp-llama-3.1-8b": { + "max_tokens": 32768, + "input_cost_per_token": 2e-07, + "max_output_tokens": 32768, + "output_cost_per_token": 2e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/z-ai/glm-4.5-air:free": { + "max_tokens": 131072, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/nvidia/llama-3.1-nemotron-ultra-253b-v1:free": { + "max_tokens": 131072, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/meta/llama-3.3-70b": { + "max_tokens": 128000, + "input_cost_per_token": 7.2e-07, + "output_cost_per_token": 7.2e-07, + "max_input_tokens": 128000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/deepseek/deepseek-r1-distill-qwen-14b:free": { + "max_tokens": 64000, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/arliai/qwq-32b-arliai-rpr-v1:free": { + "max_tokens": 32768, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/perplexity/sonar-reasoning": { + "max_tokens": 127000, + "input_cost_per_token": 1e-06, + "output_cost_per_token": 5e-06, + "max_input_tokens": 127000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/agentica-org/deepcoder-14b-preview:free": { + "max_tokens": 96000, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/mistralai/devstral-small-2505:free": { + "max_tokens": 32768, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/perplexity/sonar-pro": { + "max_tokens": 200000, + "input_cost_per_token": 3e-06, + "max_output_tokens": 8000, + "output_cost_per_token": 1.5e-05, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/openai/gpt-3.5-turbo": { + "max_tokens": 4096, + "input_cost_per_token": 5e-07, + "output_cost_per_token": 1.5e-06, + "max_input_tokens": 4096, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/arliai/qwq-32b-arliai-rpr-v1": { + "max_tokens": 32768, + "input_cost_per_token": 1.5e-08, + "output_cost_per_token": 1.5e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/google/gemma-3n-e4b-it": { + "max_tokens": 32768, + "input_cost_per_token": 2e-08, + "output_cost_per_token": 4e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/anthropic/claude-3-haiku": { + "max_tokens": 200000, + "input_cost_per_token": 2.5e-07, + "output_cost_per_token": 1.25e-06, + "max_input_tokens": 200000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/eleutherai/llemma_7b": { + "max_tokens": 4096, + "input_cost_per_token": 8e-07, + "max_output_tokens": 4096, + "output_cost_per_token": 1.2e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/google/gemma-3-4b-it:free": { + "max_tokens": 32768, + "input_cost_per_token": 0.0, + "max_output_tokens": 8192, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/mistralai/mistral-small-3.1-24b-instruct:free": { + "max_tokens": 128000, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/deepseek/deepseek-r1:free": { + "max_tokens": 163840, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/qwen/qwen3-14b": { + "max_tokens": 40960, + "input_cost_per_token": 6e-08, + "output_cost_per_token": 2.4e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/qwen/qwen2.5-vl-72b-instruct": { + "max_tokens": 32000, + "input_cost_per_token": 2.5e-07, + "output_cost_per_token": 7.5e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/perplexity/sonar": { + "max_tokens": 127072, + "input_cost_per_token": 1e-06, + "output_cost_per_token": 1e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/google/gemma-2-9b-it:free": { + "max_tokens": 8192, + "input_cost_per_token": 0.0, + "max_output_tokens": 8192, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/openai/o3-mini": { + "max_tokens": 200000, + "input_cost_per_token": 1.1e-06, + "output_cost_per_token": 4.4e-06, + "max_input_tokens": 200000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/mistralai/codestral-2501": { + "max_tokens": 262144, + "input_cost_per_token": 3e-07, + "output_cost_per_token": 9e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/anthropic/claude-3.5-haiku-20241022": { + "max_tokens": 200000, + "input_cost_per_token": 8e-07, + "max_output_tokens": 8192, + "output_cost_per_token": 4e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/openai/gpt-4-turbo": { + "max_tokens": 128000, + "input_cost_per_token": 1e-05, + "output_cost_per_token": 3e-05, + "max_input_tokens": 128000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/neversleep/llama-3-lumimaid-70b": { + "max_tokens": 8192, + "input_cost_per_token": 4e-06, + "max_output_tokens": 4096, + "output_cost_per_token": 6e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/thedrummer/anubis-70b-v1.1": { + "max_tokens": 131072, + "input_cost_per_token": 5e-07, + "max_output_tokens": 131072, + "output_cost_per_token": 8e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/meta/llama-3.2-3b": { + "max_tokens": 128000, + "input_cost_per_token": 1.5e-07, + "output_cost_per_token": 1.5e-07, + "max_input_tokens": 128000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "vercel_ai_gateway/xai/grok-2": { + "max_tokens": 131072, + "input_cost_per_token": 2e-06, + "output_cost_per_token": 1e-05, + "max_input_tokens": 131072, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "vercel_ai_gateway/google/gemini-2.0-flash": { + "max_tokens": 1048576, + "input_cost_per_token": 1.5e-07, + "output_cost_per_token": 6e-07, + "max_input_tokens": 1048576, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "vercel_ai_gateway/mistral/mistral-saba-24b": { + "max_tokens": 32768, + "input_cost_per_token": 7.9e-07, + "output_cost_per_token": 7.9e-07, + "max_input_tokens": 32768, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/openai/gpt-4o-2024-11-20": { + "max_tokens": 128000, + "input_cost_per_token": 2.5e-06, + "max_output_tokens": 16384, + "output_cost_per_token": 1e-05, + "input_cost_per_image": 0.003613, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/qwen/qwen3-8b": { + "max_tokens": 128000, + "input_cost_per_token": 3.5e-08, + "max_output_tokens": 20000, + "output_cost_per_token": 1.38e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/deepseek/deepseek-r1-distill-qwen-1.5b": { + "max_tokens": 131072, + "input_cost_per_token": 1.8e-07, + "max_output_tokens": 32768, + "output_cost_per_token": 1.8e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/deepseek/deepseek-r1-0528-qwen3-8b": { + "max_tokens": 32000, + "input_cost_per_token": 1e-08, + "output_cost_per_token": 2e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/perplexity/sonar": { + "max_tokens": 127000, + "input_cost_per_token": 1e-06, + "output_cost_per_token": 1e-06, + "max_input_tokens": 127000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/x-ai/grok-3-mini-beta": { + "max_tokens": 131072, + "input_cost_per_token": 3e-07, + "output_cost_per_token": 5e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/openai/gpt-4.1": { + "max_tokens": 1047576, + "input_cost_per_token": 2e-06, + "output_cost_per_token": 8e-06, + "max_input_tokens": 1047576, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "vercel_ai_gateway/meta/llama-3.1-70b": { + "max_tokens": 128000, + "input_cost_per_token": 7.2e-07, + "output_cost_per_token": 7.2e-07, + "max_input_tokens": 128000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "vercel_ai_gateway/xai/grok-2-vision": { + "max_tokens": 32768, + "input_cost_per_token": 2e-06, + "output_cost_per_token": 1e-05, + "max_input_tokens": 32768, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "vercel_ai_gateway/perplexity/sonar-pro": { + "max_tokens": 200000, + "input_cost_per_token": 3e-06, + "output_cost_per_token": 1.5e-05, + "max_input_tokens": 200000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/google/gemma-3n-e2b-it:free": { + "max_tokens": 8192, + "input_cost_per_token": 0.0, + "max_output_tokens": 2048, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/openai/o1": { + "max_tokens": 200000, + "input_cost_per_token": 1.5e-05, + "output_cost_per_token": 6e-05, + "max_input_tokens": 200000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/anthracite-org/magnum-v2-72b": { + "max_tokens": 32768, + "input_cost_per_token": 3e-06, + "output_cost_per_token": 3e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/qwen/qwen3-235b-a22b:free": { + "max_tokens": 131072, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/qwen/qwen3-235b-a22b": { + "max_tokens": 40960, + "input_cost_per_token": 1.3e-07, + "max_output_tokens": 40960, + "output_cost_per_token": 6e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/anthropic/claude-4-sonnet": { + "max_tokens": 200000, + "input_cost_per_token": 3e-06, + "output_cost_per_token": 1.5e-05, + "max_input_tokens": 200000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "vercel_ai_gateway/mistral/magistral-small": { + "max_tokens": 128000, + "input_cost_per_token": 5e-07, + "output_cost_per_token": 1.5e-06, + "max_input_tokens": 128000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/moonshotai/kimi-dev-72b:free": { + "max_tokens": 131072, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/thudm/glm-4.1v-9b-thinking": { + "max_tokens": 65536, + "input_cost_per_token": 3.5e-08, + "max_output_tokens": 8000, + "output_cost_per_token": 1.38e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/perplexity/sonar-reasoning-pro": { + "max_tokens": 127000, + "input_cost_per_token": 2e-06, + "output_cost_per_token": 8e-06, + "max_input_tokens": 127000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/cohere/command": { + "max_tokens": 4096, + "input_cost_per_token": 1e-06, + "max_output_tokens": 4000, + "output_cost_per_token": 2e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/perplexity/r1-1776": { + "max_tokens": 128000, + "input_cost_per_token": 2e-06, + "output_cost_per_token": 8e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/openai/o1-pro": { + "max_tokens": 200000, + "input_cost_per_token": 0.00015, + "max_output_tokens": 100000, + "output_cost_per_token": 0.0006, + "input_cost_per_image": 0.21675, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/google/gemma-2-9b": { + "max_tokens": 8192, + "input_cost_per_token": 2e-07, + "output_cost_per_token": 2e-07, + "max_input_tokens": 8192, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/qwen/qwen-max": { + "max_tokens": 32768, + "input_cost_per_token": 1.6e-06, + "max_output_tokens": 8192, + "output_cost_per_token": 6.4e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/rekaai/reka-flash-3:free": { + "max_tokens": 32768, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/qwen/qwen-plus": { + "max_tokens": 131072, + "input_cost_per_token": 4e-07, + "max_output_tokens": 8192, + "output_cost_per_token": 1.2e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/meta/llama-3.2-1b": { + "max_tokens": 128000, + "input_cost_per_token": 1e-07, + "output_cost_per_token": 1e-07, + "max_input_tokens": 128000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/qwen/qwen-2.5-vl-7b-instruct": { + "max_tokens": 32768, + "input_cost_per_token": 2e-07, + "output_cost_per_token": 2e-07, + "input_cost_per_image": 0.0001445, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/thedrummer/skyfall-36b-v2": { + "max_tokens": 16384, + "input_cost_per_token": 1.512e-08, + "output_cost_per_token": 1.512e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/x-ai/grok-3-beta": { + "max_tokens": 131072, + "input_cost_per_token": 3e-06, + "output_cost_per_token": 1.5e-05, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/liquid/lfm-7b": { + "max_tokens": 32768, + "input_cost_per_token": 1e-08, + "output_cost_per_token": 1e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/mistralai/mistral-nemo": { + "max_tokens": 32000, + "input_cost_per_token": 7.5e-09, + "output_cost_per_token": 5e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/mistralai/ministral-3b": { + "max_tokens": 131072, + "input_cost_per_token": 4e-08, + "output_cost_per_token": 4e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/mistral/mistral-large": { + "max_tokens": 32000, + "input_cost_per_token": 2e-06, + "output_cost_per_token": 6e-06, + "max_input_tokens": 32000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/baidu/ernie-4.5-300b-a47b": { + "max_tokens": 123000, + "input_cost_per_token": 2.8e-07, + "max_output_tokens": 12000, + "output_cost_per_token": 1.1e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/cognitivecomputations/dolphin-mixtral-8x22b": { + "max_tokens": 16000, + "input_cost_per_token": 9e-07, + "max_output_tokens": 8192, + "output_cost_per_token": 9e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/deepseek/deepseek-r1-distill-llama-70b": { + "max_tokens": 131072, + "input_cost_per_token": 5e-08, + "output_cost_per_token": 5e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/cognitivecomputations/dolphin-mistral-24b-venice-edition:free": { + "max_tokens": 32768, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/thudm/glm-4-32b:free": { + "max_tokens": 32768, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/google/gemma-2-27b-it": { + "max_tokens": 8192, + "input_cost_per_token": 6.5e-07, + "output_cost_per_token": 6.5e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/microsoft/phi-3-medium-128k-instruct": { + "max_tokens": 128000, + "input_cost_per_token": 1e-06, + "output_cost_per_token": 1e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/meta/llama-3-70b": { + "max_tokens": 8192, + "input_cost_per_token": 5.9e-07, + "output_cost_per_token": 7.9e-07, + "max_input_tokens": 8192, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "vercel_ai_gateway/openai/gpt-4.1-nano": { + "max_tokens": 1047576, + "input_cost_per_token": 1e-07, + "output_cost_per_token": 4e-07, + "max_input_tokens": 1047576, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/tencent/hunyuan-a13b-instruct:free": { + "max_tokens": 32768, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/meta-llama/llama-3.2-11b-vision-instruct:free": { + "max_tokens": 131072, + "input_cost_per_token": 0.0, + "max_output_tokens": 2048, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/undi95/toppy-m-7b": { + "max_tokens": 4096, + "input_cost_per_token": 8e-07, + "max_output_tokens": 4096, + "output_cost_per_token": 1.2e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/microsoft/phi-4-reasoning-plus": { + "max_tokens": 32768, + "input_cost_per_token": 7e-08, + "output_cost_per_token": 3.5e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/openai/gpt-3.5-turbo-0613": { + "max_tokens": 4095, + "input_cost_per_token": 1e-06, + "max_output_tokens": 4096, + "output_cost_per_token": 2e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/meta/llama-3.2-90b": { + "max_tokens": 128000, + "input_cost_per_token": 7.2e-07, + "output_cost_per_token": 7.2e-07, + "max_input_tokens": 128000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/openai/gpt-4.1-nano": { + "max_tokens": 1047576, + "input_cost_per_token": 1e-07, + "max_output_tokens": 32768, + "output_cost_per_token": 4e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/deepseek/deepseek-r1-distill-qwen-32b": { + "max_tokens": 131072, + "input_cost_per_token": 7.5e-08, + "max_output_tokens": 16384, + "output_cost_per_token": 1.5e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/tencent/hunyuan-a13b-instruct": { + "max_tokens": 32768, + "input_cost_per_token": 3e-08, + "output_cost_per_token": 3e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/alibaba/qwen-3-235b": { + "max_tokens": 40960, + "input_cost_per_token": 2e-07, + "output_cost_per_token": 6e-07, + "max_input_tokens": 40960, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/cohere/command-r-plus-08-2024": { + "max_tokens": 128000, + "input_cost_per_token": 2.5e-06, + "max_output_tokens": 4000, + "output_cost_per_token": 1e-05, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/openai/gpt-4.1-mini": { + "max_tokens": 1047576, + "input_cost_per_token": 4e-07, + "output_cost_per_token": 1.6e-06, + "max_input_tokens": 1047576, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/sophosympatheia/midnight-rose-70b": { + "max_tokens": 4096, + "input_cost_per_token": 8e-07, + "max_output_tokens": 2048, + "output_cost_per_token": 8e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/inception/mercury": { + "max_tokens": 32000, + "input_cost_per_token": 2.5e-07, + "max_output_tokens": 16000, + "output_cost_per_token": 1e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/meta-llama/llama-3.2-1b-instruct": { + "max_tokens": 131072, + "input_cost_per_token": 5e-09, + "max_output_tokens": 16384, + "output_cost_per_token": 1e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/mistral/ministral-8b": { + "max_tokens": 128000, + "input_cost_per_token": 1e-07, + "output_cost_per_token": 1e-07, + "max_input_tokens": 128000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/openai/gpt-4o-2024-08-06": { + "max_tokens": 128000, + "input_cost_per_token": 2.5e-06, + "max_output_tokens": 16384, + "output_cost_per_token": 1e-05, + "input_cost_per_image": 0.003613, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/featherless/qwerky-72b:free": { + "max_tokens": 32768, + "input_cost_per_token": 0.0, + "max_output_tokens": 4096, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/inflection/inflection-3-pi": { + "max_tokens": 8000, + "input_cost_per_token": 2.5e-06, + "max_output_tokens": 1024, + "output_cost_per_token": 1e-05, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/cognitivecomputations/dolphin3.0-mistral-24b:free": { + "max_tokens": 32768, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/anthropic/claude-3.5-haiku:beta": { + "max_tokens": 200000, + "input_cost_per_token": 8e-07, + "max_output_tokens": 8192, + "output_cost_per_token": 4e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/cohere/command-r": { + "max_tokens": 128000, + "input_cost_per_token": 5e-07, + "max_output_tokens": 4000, + "output_cost_per_token": 1.5e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/nousresearch/deephermes-3-mistral-24b-preview": { + "max_tokens": 32768, + "input_cost_per_token": 1.41e-07, + "output_cost_per_token": 1.41e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/meta-llama/llama-3.1-8b-instruct": { + "max_tokens": 131072, + "input_cost_per_token": 1.5e-08, + "max_output_tokens": 16384, + "output_cost_per_token": 2e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/openai/gpt-4o:extended": { + "max_tokens": 128000, + "input_cost_per_token": 6e-06, + "max_output_tokens": 64000, + "output_cost_per_token": 1.8e-05, + "input_cost_per_image": 0.007225, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/openai/o3-pro": { + "max_tokens": 200000, + "input_cost_per_token": 2e-05, + "max_output_tokens": 100000, + "output_cost_per_token": 8e-05, + "input_cost_per_image": 0.0153, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/thedrummer/rocinante-12b": { + "max_tokens": 32768, + "input_cost_per_token": 2e-07, + "output_cost_per_token": 5e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/x-ai/grok-3": { + "max_tokens": 131072, + "input_cost_per_token": 3e-06, + "output_cost_per_token": 1.5e-05, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/cohere/command-r-plus": { + "max_tokens": 128000, + "input_cost_per_token": 2.5e-06, + "output_cost_per_token": 1e-05, + "max_input_tokens": 128000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/z-ai/glm-4.5-air": { + "max_tokens": 128000, + "input_cost_per_token": 2e-07, + "max_output_tokens": 96000, + "output_cost_per_token": 1.1e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/google/gemma-3-27b-it": { + "max_tokens": 131072, + "input_cost_per_token": 9e-08, + "max_output_tokens": 16384, + "output_cost_per_token": 1.7e-07, + "input_cost_per_image": 2.56e-05, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/mistral/devstral-small": { + "max_tokens": 128000, + "input_cost_per_token": 7e-08, + "output_cost_per_token": 2.8e-07, + "max_input_tokens": 128000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/meta-llama/llama-3.2-90b-vision-instruct": { + "max_tokens": 131072, + "input_cost_per_token": 1.2e-06, + "max_output_tokens": 2048, + "output_cost_per_token": 1.2e-06, + "input_cost_per_image": 0.001734, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/mistral/codestral": { + "max_tokens": 256000, + "input_cost_per_token": 3e-07, + "output_cost_per_token": 9e-07, + "max_input_tokens": 256000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/qwen/qwen2.5-vl-32b-instruct:free": { + "max_tokens": 8192, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/sarvamai/sarvam-m:free": { + "max_tokens": 32768, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/alibaba/qwen-3-30b": { + "max_tokens": 40960, + "input_cost_per_token": 1e-07, + "output_cost_per_token": 3e-07, + "max_input_tokens": 40960, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "vercel_ai_gateway/amazon/nova-pro": { + "max_tokens": 300000, + "input_cost_per_token": 8e-07, + "output_cost_per_token": 3.2e-06, + "max_input_tokens": 300000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/openai/o3": { + "max_tokens": 200000, + "input_cost_per_token": 2e-06, + "max_output_tokens": 100000, + "output_cost_per_token": 8e-06, + "input_cost_per_image": 0.00153, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/perplexity/sonar-reasoning": { + "max_tokens": 127000, + "input_cost_per_token": 1e-06, + "output_cost_per_token": 5e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/mistral/magistral-medium": { + "max_tokens": 128000, + "input_cost_per_token": 2e-06, + "output_cost_per_token": 5e-06, + "max_input_tokens": 128000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/opengvlab/internvl3-14b": { + "max_tokens": 12288, + "input_cost_per_token": 2e-07, + "output_cost_per_token": 4e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/mistralai/magistral-medium-2506:thinking": { + "max_tokens": 40960, + "input_cost_per_token": 2e-06, + "max_output_tokens": 40000, + "output_cost_per_token": 5e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/deepseek/deepseek-r1-distill-llama-8b": { + "max_tokens": 32000, + "input_cost_per_token": 4e-08, + "max_output_tokens": 32000, + "output_cost_per_token": 4e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/mistral/mixtral-8x22b-instruct": { + "max_tokens": 2048, + "input_cost_per_token": 1.2e-06, + "output_cost_per_token": 1.2e-06, + "max_input_tokens": 2048, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "vercel_ai_gateway/meta/llama-4-scout": { + "max_tokens": 131072, + "input_cost_per_token": 1e-07, + "output_cost_per_token": 3e-07, + "max_input_tokens": 131072, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/amazon/nova-micro-v1": { + "max_tokens": 128000, + "input_cost_per_token": 3.5e-08, + "max_output_tokens": 5120, + "output_cost_per_token": 1.4e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/thudm/glm-4-32b": { + "max_tokens": 32000, + "input_cost_per_token": 2.4e-07, + "max_output_tokens": 32000, + "output_cost_per_token": 2.4e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/qwen/qwen3-235b-a22b-2507:free": { + "max_tokens": 262144, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/nousresearch/hermes-3-llama-3.1-70b": { + "max_tokens": 131072, + "input_cost_per_token": 1e-07, + "output_cost_per_token": 2.8e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/microsoft/phi-3-mini-128k-instruct": { + "max_tokens": 128000, + "input_cost_per_token": 1e-07, + "output_cost_per_token": 1e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/openai/gpt-4o": { + "max_tokens": 128000, + "input_cost_per_token": 2.5e-06, + "output_cost_per_token": 1e-05, + "max_input_tokens": 128000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/anthropic/claude-3.5-haiku": { + "max_tokens": 200000, + "input_cost_per_token": 8e-07, + "max_output_tokens": 8192, + "output_cost_per_token": 4e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/anthropic/claude-opus-4": { + "max_tokens": 200000, + "input_cost_per_token": 1.5e-05, + "max_output_tokens": 32000, + "output_cost_per_token": 7.5e-05, + "input_cost_per_image": 0.024, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/google/gemini-2.5-pro-preview": { + "max_tokens": 1048576, + "input_cost_per_token": 1.25e-06, + "max_output_tokens": 65536, + "output_cost_per_token": 1e-05, + "input_cost_per_image": 0.00516, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/anthropic/claude-3-opus": { + "max_tokens": 200000, + "input_cost_per_token": 1.5e-05, + "output_cost_per_token": 7.5e-05, + "max_input_tokens": 200000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/moonshotai/kimi-vl-a3b-thinking": { + "max_tokens": 131072, + "input_cost_per_token": 3.8e-08, + "output_cost_per_token": 3.8e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/morph/morph-v3-large": { + "max_tokens": 32768, + "input_cost_per_token": 9e-07, + "output_cost_per_token": 1.9e-06, + "max_input_tokens": 32768, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/meta-llama/llama-3-8b-instruct": { + "max_tokens": 8192, + "input_cost_per_token": 3e-08, + "max_output_tokens": 16384, + "output_cost_per_token": 6e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/google/gemma-2-9b-it": { + "max_tokens": 8192, + "input_cost_per_token": 4e-09, + "max_output_tokens": 8192, + "output_cost_per_token": 4e-09, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/qwen/qwen-vl-max": { + "max_tokens": 7500, + "input_cost_per_token": 8e-07, + "max_output_tokens": 1500, + "output_cost_per_token": 3.2e-06, + "input_cost_per_image": 0.001024, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/ai21/jamba-1.6-mini": { + "max_tokens": 256000, + "input_cost_per_token": 2e-07, + "max_output_tokens": 4096, + "output_cost_per_token": 4e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/morph/morph-v3-fast": { + "max_tokens": 32768, + "input_cost_per_token": 8e-07, + "output_cost_per_token": 1.2e-06, + "max_input_tokens": 32768, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/google/gemini-2.5-pro-exp-03-25": { + "max_tokens": 1048576, + "input_cost_per_token": 0.0, + "max_output_tokens": 65535, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/sarvamai/sarvam-m": { + "max_tokens": 32768, + "input_cost_per_token": 2.2e-08, + "output_cost_per_token": 2.2e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/openai/o4-mini-high": { + "max_tokens": 200000, + "input_cost_per_token": 1.1e-06, + "max_output_tokens": 100000, + "output_cost_per_token": 4.4e-06, + "input_cost_per_image": 0.0008415, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/meta-llama/llama-4-maverick": { + "max_tokens": 1048576, + "input_cost_per_token": 1.5e-07, + "max_output_tokens": 16384, + "output_cost_per_token": 6e-07, + "input_cost_per_image": 0.0006684, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/xai/grok-3-fast": { + "max_tokens": 131072, + "input_cost_per_token": 5e-06, + "output_cost_per_token": 2.5e-05, + "max_input_tokens": 131072, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "vercel_ai_gateway/xai/grok-3": { + "max_tokens": 131072, + "input_cost_per_token": 3e-06, + "output_cost_per_token": 1.5e-05, + "max_input_tokens": 131072, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/anthropic/claude-3-haiku:beta": { + "max_tokens": 200000, + "input_cost_per_token": 2.5e-07, + "max_output_tokens": 4096, + "output_cost_per_token": 1.25e-06, + "input_cost_per_image": 0.0004, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/cohere/command-r-plus-04-2024": { + "max_tokens": 128000, + "input_cost_per_token": 3e-06, + "max_output_tokens": 4000, + "output_cost_per_token": 1.5e-05, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/qwen/qwen3-235b-a22b-2507": { + "max_tokens": 262144, + "input_cost_per_token": 1.2e-07, + "max_output_tokens": 262144, + "output_cost_per_token": 5.9e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/anthropic/claude-3.5-haiku": { + "max_tokens": 200000, + "input_cost_per_token": 8e-07, + "output_cost_per_token": 4e-06, + "max_input_tokens": 200000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "vercel_ai_gateway/openai/o4-mini": { + "max_tokens": 200000, + "input_cost_per_token": 1.1e-06, + "output_cost_per_token": 4.4e-06, + "max_input_tokens": 200000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/google/gemini-flash-1.5": { + "max_tokens": 1000000, + "input_cost_per_token": 7.5e-08, + "max_output_tokens": 8192, + "output_cost_per_token": 3e-07, + "input_cost_per_image": 4e-05, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/deepseek/deepseek-chat-v3-0324": { + "max_tokens": 163840, + "input_cost_per_token": 2.5e-07, + "max_output_tokens": 163840, + "output_cost_per_token": 8.5e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/tngtech/deepseek-r1t2-chimera": { + "max_tokens": 163840, + "input_cost_per_token": 3.02e-07, + "output_cost_per_token": 3.02e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/minimax/minimax-01": { + "max_tokens": 1000192, + "input_cost_per_token": 2e-07, + "max_output_tokens": 1000192, + "output_cost_per_token": 1.1e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/thedrummer/valkyrie-49b-v1": { + "max_tokens": 131072, + "input_cost_per_token": 6.5e-07, + "max_output_tokens": 131072, + "output_cost_per_token": 1e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/mistralai/mistral-7b-instruct-v0.3": { + "max_tokens": 32768, + "input_cost_per_token": 2.8e-08, + "max_output_tokens": 16384, + "output_cost_per_token": 5.4e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/meta-llama/llama-3.3-70b-instruct": { + "max_tokens": 131072, + "input_cost_per_token": 3.8e-08, + "max_output_tokens": 16384, + "output_cost_per_token": 1.2e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/mistralai/magistral-medium-2506": { + "max_tokens": 40960, + "input_cost_per_token": 2e-06, + "max_output_tokens": 40000, + "output_cost_per_token": 5e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/alibaba/qwen-3-32b": { + "max_tokens": 40960, + "input_cost_per_token": 1e-07, + "output_cost_per_token": 3e-07, + "max_input_tokens": 40960, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/microsoft/mai-ds-r1:free": { + "max_tokens": 163840, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/x-ai/grok-vision-beta": { + "max_tokens": 8192, + "input_cost_per_token": 5e-06, + "output_cost_per_token": 1.5e-05, + "input_cost_per_image": 0.009, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/mistralai/mistral-small-24b-instruct-2501": { + "max_tokens": 32768, + "input_cost_per_token": 3e-08, + "output_cost_per_token": 3e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/aion-labs/aion-1.0": { + "max_tokens": 131072, + "input_cost_per_token": 4e-06, + "max_output_tokens": 32768, + "output_cost_per_token": 8e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/x-ai/grok-3-mini": { + "max_tokens": 131072, + "input_cost_per_token": 3e-07, + "output_cost_per_token": 5e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/google/gemma-3-4b-it": { + "max_tokens": 131072, + "input_cost_per_token": 2e-08, + "output_cost_per_token": 4e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/amazon/nova-lite-v1": { + "max_tokens": 300000, + "input_cost_per_token": 6e-08, + "max_output_tokens": 5120, + "output_cost_per_token": 2.4e-07, + "input_cost_per_image": 9e-05, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/mistralai/pixtral-large-2411": { + "max_tokens": 131072, + "input_cost_per_token": 2e-06, + "output_cost_per_token": 6e-06, + "input_cost_per_image": 0.002888, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/cohere/command-a": { + "max_tokens": 32768, + "input_cost_per_token": 2e-06, + "output_cost_per_token": 8e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/sao10k/l3.1-euryale-70b": { + "max_tokens": 32768, + "input_cost_per_token": 6.5e-07, + "output_cost_per_token": 7.5e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/mistralai/mistral-tiny": { + "max_tokens": 32768, + "input_cost_per_token": 2.5e-07, + "output_cost_per_token": 2.5e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/cohere/command-r": { + "max_tokens": 128000, + "input_cost_per_token": 1.5e-07, + "output_cost_per_token": 6e-07, + "max_input_tokens": 128000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/liquid/lfm-40b": { + "max_tokens": 65536, + "input_cost_per_token": 1.5e-07, + "max_output_tokens": 65536, + "output_cost_per_token": 1.5e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/z-ai/glm-4-32b": { + "max_tokens": 128000, + "input_cost_per_token": 1e-07, + "output_cost_per_token": 1e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/google/gemini-2.0-flash-lite": { + "max_tokens": 1048576, + "input_cost_per_token": 7.5e-08, + "output_cost_per_token": 3e-07, + "max_input_tokens": 1048576, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/alfredpros/codellama-7b-instruct-solidity": { + "max_tokens": 4096, + "input_cost_per_token": 8e-07, + "max_output_tokens": 4096, + "output_cost_per_token": 1.2e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/xai/grok-3-mini": { + "max_tokens": 131072, + "input_cost_per_token": 3e-07, + "output_cost_per_token": 5e-07, + "max_input_tokens": 131072, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/openai/gpt-4o-mini-2024-07-18": { + "max_tokens": 128000, + "input_cost_per_token": 1.5e-07, + "max_output_tokens": 16384, + "output_cost_per_token": 6e-07, + "input_cost_per_image": 0.007225, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/perplexity/sonar-deep-research": { + "max_tokens": 128000, + "input_cost_per_token": 2e-06, + "output_cost_per_token": 8e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/mistralai/mistral-7b-instruct-v0.1": { + "max_tokens": 2824, + "input_cost_per_token": 1.1e-07, + "output_cost_per_token": 1.9e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/openai/gpt-3.5-turbo-instruct": { + "max_tokens": 4096, + "input_cost_per_token": 1.5e-06, + "output_cost_per_token": 2e-06, + "max_input_tokens": 4096, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/deepseek/deepseek-r1-distill-qwen-7b": { + "max_tokens": 131072, + "input_cost_per_token": 1e-07, + "output_cost_per_token": 2e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/meta/llama-3.2-11b": { + "max_tokens": 128000, + "input_cost_per_token": 1.6e-07, + "output_cost_per_token": 1.6e-07, + "max_input_tokens": 128000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/mistralai/mistral-small": { + "max_tokens": 32768, + "input_cost_per_token": 2e-07, + "output_cost_per_token": 6e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/openai/gpt-4-1106-preview": { + "max_tokens": 128000, + "input_cost_per_token": 1e-05, + "max_output_tokens": 4096, + "output_cost_per_token": 3e-05, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/tngtech/deepseek-r1t2-chimera:free": { + "max_tokens": 163840, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/google/gemini-2.5-pro": { + "max_tokens": 1048576, + "input_cost_per_token": 2.5e-06, + "output_cost_per_token": 1e-05, + "max_input_tokens": 1048576, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "vercel_ai_gateway/mistral/pixtral-large": { + "max_tokens": 128000, + "input_cost_per_token": 2e-06, + "output_cost_per_token": 6e-06, + "max_input_tokens": 128000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "vercel_ai_gateway/xai/grok-4": { + "max_tokens": 256000, + "input_cost_per_token": 3e-06, + "output_cost_per_token": 1.5e-05, + "max_input_tokens": 256000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/thudm/glm-z1-32b": { + "max_tokens": 32768, + "input_cost_per_token": 3e-08, + "output_cost_per_token": 3e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/anthropic/claude-3.5-sonnet-20240620:beta": { + "max_tokens": 200000, + "input_cost_per_token": 3e-06, + "max_output_tokens": 8192, + "output_cost_per_token": 1.5e-05, + "input_cost_per_image": 0.0048, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/mistralai/devstral-small": { + "max_tokens": 128000, + "input_cost_per_token": 7e-08, + "output_cost_per_token": 2.8e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/arcee-ai/spotlight": { + "max_tokens": 131072, + "input_cost_per_token": 1.8e-07, + "max_output_tokens": 65537, + "output_cost_per_token": 1.8e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/alibaba/qwen-3-14b": { + "max_tokens": 40960, + "input_cost_per_token": 8e-08, + "output_cost_per_token": 2.4e-07, + "max_input_tokens": 40960, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/openai/codex-mini": { + "max_tokens": 200000, + "input_cost_per_token": 1.5e-06, + "max_output_tokens": 100000, + "output_cost_per_token": 6e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/raifle/sorcererlm-8x22b": { + "max_tokens": 16000, + "input_cost_per_token": 4.5e-06, + "output_cost_per_token": 4.5e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/qwen/qwq-32b": { + "max_tokens": 131072, + "input_cost_per_token": 7.5e-08, + "output_cost_per_token": 1.5e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/google/gemini-2.5-flash-lite": { + "max_tokens": 1048576, + "input_cost_per_token": 1e-07, + "max_output_tokens": 65535, + "output_cost_per_token": 4e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/alibaba/qwen3-coder": { + "max_tokens": 262144, + "input_cost_per_token": 4e-07, + "output_cost_per_token": 1.6e-06, + "max_input_tokens": 262144, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/nousresearch/deephermes-3-llama-3-8b-preview:free": { + "max_tokens": 131072, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/google/gemma-3-12b-it": { + "max_tokens": 96000, + "input_cost_per_token": 3e-08, + "max_output_tokens": 8192, + "output_cost_per_token": 3e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/openrouter/auto": { + "max_tokens": 2000000, + "input_cost_per_token": -1.0, + "output_cost_per_token": -1.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/anthropic/claude-3-opus:beta": { + "max_tokens": 200000, + "input_cost_per_token": 1.5e-05, + "max_output_tokens": 4096, + "output_cost_per_token": 7.5e-05, + "input_cost_per_image": 0.024, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/qwen/qwen-2.5-coder-32b-instruct:free": { + "max_tokens": 32768, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/zai/glm-4.5-air": { + "max_tokens": 128000, + "input_cost_per_token": 2e-07, + "output_cost_per_token": 1.1e-06, + "max_input_tokens": 128000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/deepseek/deepseek-prover-v2": { + "max_tokens": 163840, + "input_cost_per_token": 5e-07, + "output_cost_per_token": 2.18e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/meta-llama/llama-guard-3-8b": { + "max_tokens": 131072, + "input_cost_per_token": 2e-08, + "output_cost_per_token": 6e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/mistralai/pixtral-12b": { + "max_tokens": 32768, + "input_cost_per_token": 1e-07, + "output_cost_per_token": 1e-07, + "input_cost_per_image": 0.0001445, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/meta-llama/llama-3.1-405b": { + "max_tokens": 32768, + "input_cost_per_token": 2e-06, + "output_cost_per_token": 2e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/vercel/v0-1.0-md": { + "max_tokens": 128000, + "input_cost_per_token": 3e-06, + "output_cost_per_token": 1.5e-05, + "max_input_tokens": 128000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "vercel_ai_gateway/zai/glm-4.5": { + "max_tokens": 128000, + "input_cost_per_token": 6e-07, + "output_cost_per_token": 2.2e-06, + "max_input_tokens": 128000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "vercel_ai_gateway/xai/grok-3-mini-fast": { + "max_tokens": 131072, + "input_cost_per_token": 6e-07, + "output_cost_per_token": 4e-06, + "max_input_tokens": 131072, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/nothingiisreal/mn-celeste-12b": { + "max_tokens": 16384, + "input_cost_per_token": 8e-07, + "max_output_tokens": 4096, + "output_cost_per_token": 1.2e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/tngtech/deepseek-r1t-chimera:free": { + "max_tokens": 163840, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/qwen/qwen3-32b": { + "max_tokens": 40960, + "input_cost_per_token": 2.7e-08, + "output_cost_per_token": 2.7e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/meta-llama/llama-4-scout": { + "max_tokens": 1048576, + "input_cost_per_token": 8e-08, + "max_output_tokens": 1048576, + "output_cost_per_token": 3e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/meta-llama/llama-3.3-70b-instruct:free": { + "max_tokens": 65536, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/microsoft/phi-4-multimodal-instruct": { + "max_tokens": 131072, + "input_cost_per_token": 5e-08, + "output_cost_per_token": 1e-07, + "input_cost_per_image": 0.00017685, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/deepseek/deepseek-r1-distill-llama-70b:free": { + "max_tokens": 8192, + "input_cost_per_token": 0.0, + "max_output_tokens": 4096, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/anthropic/claude-3.5-sonnet": { + "max_tokens": 200000, + "input_cost_per_token": 3e-06, + "output_cost_per_token": 1.5e-05, + "max_input_tokens": 200000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "vercel_ai_gateway/moonshotai/kimi-k2": { + "max_tokens": 131072, + "input_cost_per_token": 5.5e-07, + "output_cost_per_token": 2.2e-06, + "max_input_tokens": 131072, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/google/gemini-2.0-flash-exp:free": { + "max_tokens": 1048576, + "input_cost_per_token": 0.0, + "max_output_tokens": 8192, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/openai/gpt-4-turbo": { + "max_tokens": 128000, + "input_cost_per_token": 1e-05, + "max_output_tokens": 4096, + "output_cost_per_token": 3e-05, + "input_cost_per_image": 0.01445, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/qwen/qwq-32b-preview": { + "max_tokens": 32768, + "input_cost_per_token": 2e-07, + "output_cost_per_token": 2e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/agentica-org/deepcoder-14b-preview": { + "max_tokens": 96000, + "input_cost_per_token": 1.5e-08, + "output_cost_per_token": 1.5e-08, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/mistralai/mistral-7b-instruct-v0.2": { + "max_tokens": 32768, + "input_cost_per_token": 2e-07, + "output_cost_per_token": 2e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/morph/morph-v2": { + "max_tokens": 32000, + "input_cost_per_token": 1.2e-06, + "max_output_tokens": 16000, + "output_cost_per_token": 2.7e-06, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/shisa-ai/shisa-v2-llama3.3-70b:free": { + "max_tokens": 32768, + "input_cost_per_token": 0.0, + "output_cost_per_token": 0.0, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/mistralai/ministral-8b": { + "max_tokens": 128000, + "input_cost_per_token": 1e-07, + "output_cost_per_token": 1e-07, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "vercel_ai_gateway/mistral/mistral-small": { + "max_tokens": 32000, + "input_cost_per_token": 1e-07, + "output_cost_per_token": 3e-07, + "max_input_tokens": 32000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "vercel_ai_gateway/anthropic/claude-3.7-sonnet": { + "max_tokens": 200000, + "input_cost_per_token": 3e-06, + "output_cost_per_token": 1.5e-05, + "max_input_tokens": 200000, + "litellm_provider": "vercel_ai_gateway", + "mode": "chat" + }, + "openrouter/openai/chatgpt-4o-latest": { + "max_tokens": 128000, + "input_cost_per_token": 5e-06, + "max_output_tokens": 16384, + "output_cost_per_token": 1.5e-05, + "input_cost_per_image": 0.007225, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/amazon/nova-pro-v1": { + "max_tokens": 300000, + "input_cost_per_token": 8e-07, + "max_output_tokens": 5120, + "output_cost_per_token": 3.2e-06, + "input_cost_per_image": 0.0012, + "litellm_provider": "openrouter", + "mode": "chat" + }, + "openrouter/morph/morph-v3-fast": { + "max_tokens": 32000, + "input_cost_per_token": 1.2e-06, + "max_output_tokens": 16000, + "output_cost_per_token": 2.7e-06, + "litellm_provider": "openrouter", + "mode": "chat" } -} +} \ No newline at end of file diff --git a/tests/llm_translation/test_vercel_ai_gateway.py b/tests/llm_translation/test_vercel_ai_gateway.py new file mode 100644 index 0000000000..05e03dbe4a --- /dev/null +++ b/tests/llm_translation/test_vercel_ai_gateway.py @@ -0,0 +1,205 @@ +""" +Tests for vercel_ai_gateway provider integration +""" +import os +from unittest import mock + +import pytest + +import litellm +from litellm import completion +from litellm.llms.vercel_ai_gateway.chat.transformation import VercelAIGatewayConfig + + +def test_vercel_ai_gateway_config_initialization(): + """Test VercelAIGatewayConfig initializes correctly""" + config = VercelAIGatewayConfig() + assert config.custom_llm_provider == "vercel_ai_gateway" + +def test_get_llm_provider_vercel_ai_gateway(): + """Test that get_llm_provider correctly identifies vercel_ai_gateway""" + from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider + + # Test with vercel_ai_gateway/provider/model-name format + model, provider, api_key, api_base = get_llm_provider("vercel_ai_gateway/openai/gpt-4o") + assert model == "openai/gpt-4o" + assert provider == "vercel_ai_gateway" + + # Test with api_base containing vercel ai gateway endpoint + model, provider, api_key, api_base = get_llm_provider( + "gpt-4o", api_base="https://ai-gateway.vercel.sh/v1" + ) + assert model == "gpt-4o" + assert provider == "vercel_ai_gateway" + assert api_base == "https://ai-gateway.vercel.sh/v1" + + +def test_vercel_ai_gateway_in_provider_lists(): + """Test that vercel_ai_gateway is registered in all necessary provider lists""" + assert "vercel_ai_gateway" in litellm.openai_compatible_providers + assert "vercel_ai_gateway" in litellm.provider_list + assert "https://ai-gateway.vercel.sh/v1" in litellm.openai_compatible_endpoints + + +@pytest.mark.asyncio +async def test_vercel_ai_gateway_completion_call(): + """Test completion call with vercel_ai_gateway provider (requires VERCEL_AI_GATEWAY_API_KEY)""" + # Skip if no API key is available + if not os.getenv("VERCEL_AI_GATEWAY_API_KEY"): + pytest.skip("VERCEL_AI_GATEWAY_API_KEY not set") + + try: + response = await litellm.acompletion( + model="vercel_ai_gateway/openai/gpt-3.5-turbo", + messages=[{"role": "user", "content": "Hello, this is a test"}], + max_tokens=20, + ) + assert response.choices[0].message.content + assert response.model + assert response.usage + except Exception as e: + # If the API key is invalid or there's a network issue, that's okay + # The important thing is that the provider was recognized + if "vercel_ai_gateway" not in str(e) and "provider" not in str(e).lower(): + # Re-raise if it's not a provider-related error + raise + + +@pytest.mark.asyncio +async def test_vercel_ai_gateway_with_oidc_token(): + """Test completion call with vercel_ai_gateway provider using VERCEL_OIDC_TOKEN""" + # Skip if no OIDC token is available + if not os.getenv("VERCEL_OIDC_TOKEN"): + pytest.skip("VERCEL_OIDC_TOKEN not set") + + try: + response = await litellm.acompletion( + model="vercel_ai_gateway/openai/gpt-3.5-turbo", + messages=[{"role": "user", "content": "Hello, this is a test"}], + max_tokens=20, + ) + assert response.choices[0].message.content + assert response.model + assert response.usage + except Exception as e: + # If the OIDC token is invalid or there's a network issue, that's okay + # The important thing is that the provider was recognized + if "vercel_ai_gateway" not in str(e) and "provider" not in str(e).lower(): + # Re-raise if it's not a provider-related error + raise + + +def test_vercel_ai_gateway_supported_params(): + """Test that vercel_ai_gateway returns the supported parameters""" + config = VercelAIGatewayConfig() + supported_params = config.get_supported_openai_params("vercel_ai_gateway/openai/gpt-3.5-turbo") + + # vercel_ai_gateway should include all base OpenAI params plus extra_body + expected_base_params = [ + "frequency_penalty", + "logit_bias", + "logprobs", + "top_logprobs", + "max_tokens", + "max_completion_tokens", + "modalities", + "prediction", + "n", + "presence_penalty", + "seed", + "stop", + "stream", + "stream_options", + "temperature", + "top_p", + "tools", + "tool_choice", + "function_call", + "functions", + "max_retries", + "extra_headers", + "parallel_tool_calls", + "audio", + "web_search_options", + "extra_body" + ] + + for param in expected_base_params: + assert param in supported_params, f"Expected parameter '{param}' not found in supported params" + + assert "extra_body" in supported_params + + +def test_vercel_ai_gateway_sync_completion(): + """Test synchronous completion call""" + if not os.getenv("VERCEL_AI_GATEWAY_API_KEY"): + pytest.skip("VERCEL_AI_GATEWAY_API_KEY not set") + + try: + response = completion( + model="vercel_ai_gateway/openai/gpt-3.5-turbo", + messages=[{"role": "user", "content": "Hello"}], + max_tokens=20, + ) + assert response.choices[0].message.content + assert response.model + assert response.usage + except Exception as e: + if "vercel_ai_gateway" not in str(e) and "provider" not in str(e).lower(): + raise + + +def test_vercel_ai_gateway_with_provider_options(): + """Test vercel_ai_gateway with providerOptions parameter""" + if not os.getenv("VERCEL_AI_GATEWAY_API_KEY"): + pytest.skip("VERCEL_AI_GATEWAY_API_KEY not set") + + try: + response = completion( + model="vercel_ai_gateway/openai/gpt-3.5-turbo", + messages=[{"role": "user", "content": "Hello"}], + providerOptions={"gateway": {"order": ["azure", "openai"]}}, + max_tokens=20, + ) + assert response.choices[0].message.content + assert response.model + assert response.usage + except Exception as e: + if "vercel_ai_gateway" not in str(e) and "provider" not in str(e).lower(): + raise + + +def test_vercel_ai_gateway_models_endpoint(): + """Test the get_models functionality""" + config = VercelAIGatewayConfig() + + with mock.patch("litellm.module_level_client.get") as mock_get: + mock_response = mock.MagicMock() + mock_response.status_code = 200 + mock_response.json.return_value = { + "data": [ + {"id": "openai/gpt-4o"}, + {"id": "openai/gpt-3.5-turbo"}, + {"id": "anthropic/claude-4-sonnet"} + ] + } + mock_get.return_value = mock_response + + models = config.get_models() + + assert models == ["openai/gpt-4o", "openai/gpt-3.5-turbo", "anthropic/claude-4-sonnet"] + mock_get.assert_called_once_with(url="https://ai-gateway.vercel.sh/v1/models") + + +def test_vercel_ai_gateway_models_endpoint_failure(): + """Test the get_models functionality with failure""" + config = VercelAIGatewayConfig() + + with mock.patch("litellm.module_level_client.get") as mock_get: + mock_response = mock.MagicMock() + mock_response.status_code = 404 + mock_response.text = "Not found" + mock_get.return_value = mock_response + + with pytest.raises(Exception, match="Failed to get models: Not found"): + config.get_models() diff --git a/tests/test_litellm/llms/vercel_ai_gateway/chat/test_vercel_ai_gateway_transformation.py b/tests/test_litellm/llms/vercel_ai_gateway/chat/test_vercel_ai_gateway_transformation.py new file mode 100644 index 0000000000..2121473d95 --- /dev/null +++ b/tests/test_litellm/llms/vercel_ai_gateway/chat/test_vercel_ai_gateway_transformation.py @@ -0,0 +1,112 @@ +import os +import sys +from unittest.mock import patch + +import pytest + +sys.path.insert( + 0, os.path.abspath("../../../../..") +) # Adds the parent directory to the system path + +from litellm.llms.vercel_ai_gateway.chat.transformation import ( + VercelAIGatewayConfig, +) +from litellm.llms.vercel_ai_gateway.common_utils import VercelAIGatewayException + + +def test_vercel_ai_gateway_extra_body_transformation(): + """Test that providerOptions is correctly moved to extra_body""" + transformed_request = VercelAIGatewayConfig().transform_request( + model="vercel_ai_gateway/openai/gpt-4o", + messages=[{"role": "user", "content": "Hello, world!"}], + optional_params={ + "extra_body": { + "providerOptions": { + "gateway": {"order": ["azure", "openai"]} + } + } + }, + litellm_params={}, + headers={}, + ) + + assert transformed_request["extra_body"]["providerOptions"]["gateway"]["order"] == ["azure", "openai"] + assert transformed_request["messages"] == [ + {"role": "user", "content": "Hello, world!"} + ] + + +def test_vercel_ai_gateway_provider_options_mapping(): + """Test that providerOptions from non_default_params is moved to extra_body""" + config = VercelAIGatewayConfig() + + non_default_params = { + "providerOptions": { + "gateway": {"order": ["azure", "openai"]} + } + } + optional_params = {} + model = "vercel_ai_gateway/openai/gpt-4o" + + result = config.map_openai_params( + non_default_params, optional_params, model, drop_params=False + ) + + assert result["extra_body"]["providerOptions"]["gateway"]["order"] == ["azure", "openai"] + assert "providerOptions" not in result + + +def test_vercel_ai_gateway_get_supported_openai_params(): + """Test that extra_body is included in supported params""" + config = VercelAIGatewayConfig() + supported_params = config.get_supported_openai_params("vercel_ai_gateway/openai/gpt-4o") + + assert "extra_body" in supported_params + assert "temperature" in supported_params + assert "max_tokens" in supported_params + assert "stream" in supported_params + + +def test_vercel_ai_gateway_get_openai_compatible_provider_info(): + """Test provider info retrieval with environment variables""" + config = VercelAIGatewayConfig() + + with patch.dict( + "os.environ", + { + "VERCEL_AI_GATEWAY_API_BASE": "https://env.vercel.sh/v1", + "VERCEL_AI_GATEWAY_API_KEY": "env_api_key", + }, + ): + api_base, api_key = config._get_openai_compatible_provider_info(None, None) + assert api_base == "https://env.vercel.sh/v1" + assert api_key == "env_api_key" + + +def test_vercel_ai_gateway_error_class(): + """Test error class creation""" + config = VercelAIGatewayConfig() + + error_message = "Test error" + status_code = 400 + headers = {"Content-Type": "application/json"} + + error_class = config.get_error_class(error_message, status_code, headers) + + assert isinstance(error_class, VercelAIGatewayException) + assert error_class.message == error_message + assert error_class.status_code == status_code + assert error_class.headers == headers + + +def test_vercel_ai_gateway_exception_inheritance(): + """Test that VercelAIGatewayException inherits from BaseLLMException""" + from litellm.llms.base_llm.chat.transformation import BaseLLMException + + exception = VercelAIGatewayException( + message="test", + status_code=500, + headers={} + ) + + assert isinstance(exception, BaseLLMException)