Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 146 additions & 0 deletions docs/my-website/docs/providers/xai.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# XAI

https://docs.x.ai/docs

:::tip

**We support ALL XAI models, just set `model=xai/<any-model-on-xai>` as a prefix when sending litellm requests**

:::

## API Key
```python
# env variable
os.environ['XAI_API_KEY']
```

## Sample Usage
```python
from litellm import completion
import os

os.environ['XAI_API_KEY'] = ""
response = completion(
model="xai/grok-beta",
messages=[
{
"role": "user",
"content": "What's the weather like in Boston today in Fahrenheit?",
}
],
max_tokens=10,
response_format={ "type": "json_object" },
seed=123,
stop=["\n\n"],
temperature=0.2,
top_p=0.9,
tool_choice="auto",
tools=[],
user="user",
)
print(response)
```

## Sample Usage - Streaming
```python
from litellm import completion
import os

os.environ['XAI_API_KEY'] = ""
response = completion(
model="xai/grok-beta",
messages=[
{
"role": "user",
"content": "What's the weather like in Boston today in Fahrenheit?",
}
],
stream=True,
max_tokens=10,
response_format={ "type": "json_object" },
seed=123,
stop=["\n\n"],
temperature=0.2,
top_p=0.9,
tool_choice="auto",
tools=[],
user="user",
)

for chunk in response:
print(chunk)
```


## Usage with LiteLLM Proxy Server

Here's how to call a XAI model with the LiteLLM Proxy Server

1. Modify the config.yaml

```yaml
model_list:
- model_name: my-model
litellm_params:
model: xai/<your-model-name> # add xai/ prefix to route as XAI provider
api_key: api-key # api key to send your model
```


2. Start the proxy

```bash
$ litellm --config /path/to/config.yaml
```

3. Send Request to LiteLLM Proxy Server

<Tabs>

<TabItem value="openai" label="OpenAI Python v1.0.0+">

```python
import openai
client = openai.OpenAI(
api_key="sk-1234", # pass litellm proxy key, if you're using virtual keys
base_url="http://0.0.0.0:4000" # litellm-proxy-base url
)

response = client.chat.completions.create(
model="my-model",
messages = [
{
"role": "user",
"content": "what llm are you"
}
],
)

print(response)
```
</TabItem>

<TabItem value="curl" label="curl">

```shell
curl --location 'http://0.0.0.0:4000/chat/completions' \
--header 'Authorization: Bearer sk-1234' \
--header 'Content-Type: application/json' \
--data '{
"model": "my-model",
"messages": [
{
"role": "user",
"content": "what llm are you"
}
],
}'
```
</TabItem>

</Tabs>


1 change: 1 addition & 0 deletions docs/my-website/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ const sidebars = {
"providers/watsonx",
"providers/predibase",
"providers/nvidia_nim",
"providers/xai",
"providers/cerebras",
"providers/volcano",
"providers/triton-inference-server",
Expand Down
4 changes: 4 additions & 0 deletions litellm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,7 @@ def add_known_models():
"app.empower.dev/api/v1",
"inference.friendli.ai/v1",
"api.sambanova.ai/v1",
"api.x.ai/v1",
]

# this is maintained for Exception Mapping
Expand All @@ -503,6 +504,7 @@ def add_known_models():
"deepinfra",
"perplexity",
"xinference",
"xai",
"together_ai",
"fireworks_ai",
"empower",
Expand Down Expand Up @@ -713,6 +715,7 @@ class LlmProviders(str, Enum):
OPENAI = "openai"
OPENAI_LIKE = "openai_like" # embedding only
JINA_AI = "jina_ai"
XAI = "xai"
CUSTOM_OPENAI = "custom_openai"
TEXT_COMPLETION_OPENAI = "text-completion-openai"
COHERE = "cohere"
Expand Down Expand Up @@ -1017,6 +1020,7 @@ class LlmProviders(str, Enum):
FireworksAIEmbeddingConfig,
)
from .llms.jina_ai.embedding.transformation import JinaAIEmbeddingConfig
from .llms.xai.chat.xai_transformation import XAIChatConfig
from .llms.volcengine import VolcEngineConfig
from .llms.text_completion_codestral import MistralTextCompletionConfig
from .llms.AzureOpenAI.azure import (
Expand Down
7 changes: 7 additions & 0 deletions litellm/litellm_core_utils/get_llm_provider_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,13 @@ def _get_openai_compatible_provider_info( # noqa: PLR0915
) = litellm.JinaAIEmbeddingConfig()._get_openai_compatible_provider_info(
api_base, api_key
)
elif custom_llm_provider == "xai":
(
api_base,
dynamic_api_key,
) = litellm.XAIChatConfig()._get_openai_compatible_provider_info(
api_base, api_key
)
elif custom_llm_provider == "voyage":
# voyage is openai compatible, we just need to set this to custom_openai and have the api_base be https://api.voyageai.com/v1
api_base = (
Expand Down
56 changes: 56 additions & 0 deletions litellm/llms/xai/chat/xai_transformation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import types
from typing import Literal, Optional, Tuple, Union

from litellm.secret_managers.main import get_secret_str

from ...OpenAI.chat.gpt_transformation import OpenAIGPTConfig

XAI_API_BASE = "https://api.x.ai/v1"


class XAIChatConfig(OpenAIGPTConfig):
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("XAI_API_BASE") or XAI_API_BASE # type: ignore
dynamic_api_key = api_key or get_secret_str("XAI_API_KEY")
return api_base, dynamic_api_key

def get_supported_openai_params(self, model: str) -> list:
return [
"frequency_penalty",
"logit_bias",
"logprobs",
"max_tokens",
"messages",
"model",
"n",
"presence_penalty",
"response_format",
"seed",
"stop",
"stream",
"stream_options",
"temperature",
"tool_choice",
"tools",
"top_logprobs",
"top_p",
"user",
]

def map_openai_params(
self,
non_default_params: dict,
optional_params: dict,
model: str,
drop_params: bool = False,
) -> dict:
supported_openai_params = self.get_supported_openai_params(model=model)
for param, value in non_default_params.items():
if param == "max_completion_tokens":
optional_params["max_tokens"] = value
elif param in supported_openai_params:
if value is not None:
optional_params[param] = value
return optional_params
11 changes: 11 additions & 0 deletions litellm/model_prices_and_context_window_backup.json
Original file line number Diff line number Diff line change
Expand Up @@ -1488,6 +1488,17 @@
"mode": "completion",
"source": "https://docs.mistral.ai/capabilities/code_generation/"
},
"xai/grok-beta": {
"max_tokens": 131072,
"max_input_tokens": 131072,
"max_output_tokens": 131072,
"input_cost_per_token": 0.000005,
"output_cost_per_token": 0.000015,
"litellm_provider": "xai",
"mode": "chat",
"supports_function_calling": true,
"supports_vision": true
},
"deepseek-coder": {
"max_tokens": 4096,
"max_input_tokens": 128000,
Expand Down
18 changes: 18 additions & 0 deletions litellm/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2669,6 +2669,7 @@ def get_optional_params( # noqa: PLR0915
and custom_llm_provider != "groq"
and custom_llm_provider != "nvidia_nim"
and custom_llm_provider != "cerebras"
and custom_llm_provider != "xai"
and custom_llm_provider != "ai21_chat"
and custom_llm_provider != "volcengine"
and custom_llm_provider != "deepseek"
Expand Down Expand Up @@ -3445,6 +3446,16 @@ def _map_and_modify_arg(supported_params: dict, provider: str, model: str):
optional_params=optional_params,
model=model,
)
elif custom_llm_provider == "xai":
supported_params = get_supported_openai_params(
model=model, custom_llm_provider=custom_llm_provider
)
_check_valid_arg(supported_params=supported_params)
optional_params = litellm.XAIChatConfig().map_openai_params(
model=model,
non_default_params=non_default_params,
optional_params=optional_params,
)
elif custom_llm_provider == "ai21_chat":
supported_params = get_supported_openai_params(
model=model, custom_llm_provider=custom_llm_provider
Expand Down Expand Up @@ -4173,6 +4184,8 @@ def get_supported_openai_params( # noqa: PLR0915
return litellm.nvidiaNimEmbeddingConfig.get_supported_openai_params()
elif custom_llm_provider == "cerebras":
return litellm.CerebrasConfig().get_supported_openai_params(model=model)
elif custom_llm_provider == "xai":
return litellm.XAIChatConfig().get_supported_openai_params(model=model)
elif custom_llm_provider == "ai21_chat":
return litellm.AI21ChatConfig().get_supported_openai_params(model=model)
elif custom_llm_provider == "volcengine":
Expand Down Expand Up @@ -5336,6 +5349,11 @@ def validate_environment( # noqa: PLR0915
keys_in_environment = True
else:
missing_keys.append("CEREBRAS_API_KEY")
elif custom_llm_provider == "xai":
if "XAI_API_KEY" in os.environ:
keys_in_environment = True
else:
missing_keys.append("XAI_API_KEY")
elif custom_llm_provider == "ai21_chat":
if "AI21_API_KEY" in os.environ:
keys_in_environment = True
Expand Down
11 changes: 11 additions & 0 deletions model_prices_and_context_window.json
Original file line number Diff line number Diff line change
Expand Up @@ -1488,6 +1488,17 @@
"mode": "completion",
"source": "https://docs.mistral.ai/capabilities/code_generation/"
},
"xai/grok-beta": {
"max_tokens": 131072,
"max_input_tokens": 131072,
"max_output_tokens": 131072,
"input_cost_per_token": 0.000005,
"output_cost_per_token": 0.000015,
"litellm_provider": "xai",
"mode": "chat",
"supports_function_calling": true,
"supports_vision": true
},
"deepseek-coder": {
"max_tokens": 4096,
"max_input_tokens": 128000,
Expand Down
Loading