litellm_feat(provider): add OpenClaw as LLM provider

OpenClaw is an AI agent framework that exposes an OpenAI-compatible
HTTP endpoint. This adds native support for OpenClaw with:

- New provider: openclaw/<agent-id> (e.g., openclaw/main)
- Environment variables: OPENCLAW_API_BASE, OPENCLAW_API_KEY
- Session persistence via user field
- Streaming support (SSE)
- Full documentation with SDK and proxy examples

Usage:
```python
import litellm

response = litellm.completion(
    model="openclaw/main",
    api_base="http://localhost:18789",
    api_key="gateway-token",
    messages=[{"role": "user", "content": "Hello!"}]
)
```

Docs: https://docs.openclaw.ai
This commit is contained in:
shin-bot-litellm 2026-01-31 07:27:15 +00:00
parent 3f1bda57e2
commit 2a1df4c587
8 changed files with 277 additions and 0 deletions

View file

@ -0,0 +1,186 @@
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
# OpenClaw
[OpenClaw](https://openclaw.ai) is an AI agent framework that exposes an OpenAI-compatible HTTP endpoint. It allows you to interact with AI agents that have access to tools, memory, and custom configurations.
## Key Features
- **Agent Targeting**: Route requests to specific agents via the model field (`openclaw/main`, `openclaw/research`)
- **Session Persistence**: Maintain conversation context across requests using the `user` field
- **Full Tool Access**: Agents can execute code, browse the web, manage files, and more
- **Streaming Support**: Real-time SSE streaming responses
## Quick Start
```python
import litellm
response = litellm.completion(
model="openclaw/main", # Target the 'main' agent
api_base="http://localhost:18789",
api_key="your-gateway-token",
messages=[{"role": "user", "content": "Hello!"}]
)
print(response.choices[0].message.content)
```
## Environment Variables
```bash
export OPENCLAW_API_BASE="http://localhost:18789" # Gateway URL
export OPENCLAW_API_KEY="your-gateway-token" # Auth token
```
## Usage
### SDK Usage
<Tabs>
<TabItem value="sdk" label="SDK">
```python
import litellm
# Basic completion
response = litellm.completion(
model="openclaw/main",
messages=[{"role": "user", "content": "What can you do?"}]
)
# Streaming
response = litellm.completion(
model="openclaw/main",
messages=[{"role": "user", "content": "Tell me a story"}],
stream=True
)
for chunk in response:
print(chunk.choices[0].delta.content or "", end="")
# With session persistence (same user = same conversation)
response = litellm.completion(
model="openclaw/main",
messages=[{"role": "user", "content": "Remember my name is Alice"}],
user="alice-session-123"
)
```
</TabItem>
<TabItem value="proxy" label="LiteLLM Proxy">
1. Add to your `config.yaml`:
```yaml
model_list:
- model_name: openclaw-main
litellm_params:
model: openclaw/main
api_base: http://localhost:18789
api_key: os.environ/OPENCLAW_API_KEY
- model_name: openclaw-research
litellm_params:
model: openclaw/research
api_base: http://localhost:18789
api_key: os.environ/OPENCLAW_API_KEY
```
2. Start the proxy:
```bash
litellm --config config.yaml
```
3. Make requests:
```bash
curl http://localhost:4000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-1234" \
-d '{
"model": "openclaw-main",
"messages": [{"role": "user", "content": "Hello!"}]
}'
```
</TabItem>
</Tabs>
## Targeting Different Agents
OpenClaw can run multiple agents with different configurations. Target them via the model field:
```python
# Main agent (default)
litellm.completion(model="openclaw/main", ...)
# Research agent with web search tools
litellm.completion(model="openclaw/research", ...)
# Custom agent
litellm.completion(model="openclaw/my-custom-agent", ...)
```
## Supported Parameters
| Parameter | Type | Description |
|-----------|------|-------------|
| `model` | string | Agent to target: `openclaw/<agent-id>` |
| `messages` | array | Conversation messages |
| `stream` | boolean | Enable SSE streaming |
| `temperature` | float | Sampling temperature |
| `max_tokens` | integer | Maximum tokens to generate |
| `user` | string | Session key for conversation persistence |
| `tools` | array | Tool definitions (agents have built-in tools) |
| `tool_choice` | string/object | Tool selection preference |
## OpenClaw Setup
To use OpenClaw with LiteLLM:
1. Install and start OpenClaw:
```bash
npm install -g openclaw
openclaw gateway
```
2. Enable the HTTP endpoint in your OpenClaw config:
```json
{
"gateway": {
"http": {
"endpoints": {
"chatCompletions": { "enabled": true }
}
}
}
}
```
3. Configure authentication (optional but recommended):
```bash
export OPENCLAW_GATEWAY_TOKEN="your-secure-token"
```
For more details, see the [OpenClaw documentation](https://docs.openclaw.ai).
## Troubleshooting
### Connection Refused
Ensure the OpenClaw gateway is running and the API base URL is correct:
```bash
curl http://localhost:18789/health
```
### Authentication Failed
Verify your gateway token matches the one configured in OpenClaw:
```bash
openclaw gateway status
```
### Agent Not Found
Check available agents:
```bash
openclaw agents list
```

View file

@ -1426,6 +1426,7 @@ if TYPE_CHECKING:
from .llms.llamafile.chat.transformation import LlamafileChatConfig as _LlamafileChatConfig
from .llms.lm_studio.chat.transformation import LMStudioChatConfig as _LMStudioChatConfig
from .llms.lm_studio.embed.transformation import LmStudioEmbeddingConfig as _LmStudioEmbeddingConfig
from .llms.openclaw.chat.transformation import OpenClawChatConfig as _OpenClawChatConfig
from .llms.watsonx.embed.transformation import IBMWatsonXEmbeddingConfig as _IBMWatsonXEmbeddingConfig
from .llms.vertex_ai.gemini.vertex_and_google_ai_studio_gemini import VertexGeminiConfig as _VertexGeminiConfig
@ -1444,6 +1445,7 @@ if TYPE_CHECKING:
LlamafileChatConfig: Type[_LlamafileChatConfig]
LMStudioChatConfig: Type[_LMStudioChatConfig]
LmStudioEmbeddingConfig: Type[_LmStudioEmbeddingConfig]
OpenClawChatConfig: Type[_OpenClawChatConfig]
IBMWatsonXEmbeddingConfig: Type[_IBMWatsonXEmbeddingConfig]
VertexAIConfig: Type[_VertexGeminiConfig] # Alias for VertexGeminiConfig

View file

@ -1022,6 +1022,7 @@ _LLM_CONFIGS_IMPORT_MAP = {
"VLLMConfig": (".llms.vllm.completion.transformation", "VLLMConfig"),
"DeepSeekChatConfig": (".llms.deepseek.chat.transformation", "DeepSeekChatConfig"),
"LMStudioChatConfig": (".llms.lm_studio.chat.transformation", "LMStudioChatConfig"),
"OpenClawChatConfig": (".llms.openclaw.chat.transformation", "OpenClawChatConfig"),
"LmStudioEmbeddingConfig": (
".llms.lm_studio.embed.transformation",
"LmStudioEmbeddingConfig",

View file

@ -415,6 +415,7 @@ LITELLM_CHAT_PROVIDERS = [
"hosted_vllm",
"llamafile",
"lm_studio",
"openclaw",
"galadriel",
"gradient_ai",
"github_copilot", # GitHub Copilot Chat API
@ -619,6 +620,7 @@ openai_compatible_providers: List = [
"hosted_vllm",
"llamafile",
"lm_studio",
"openclaw",
"galadriel",
"github_copilot", # GitHub Copilot Chat API
"chatgpt", # ChatGPT subscription API

View file

@ -0,0 +1,83 @@
"""
Translate from OpenAI's `/v1/chat/completions` to OpenClaw's `/v1/chat/completions`
OpenClaw is an AI agent framework that exposes an OpenAI-compatible HTTP endpoint.
https://docs.openclaw.ai
Key features:
- Target specific agents via model field: `openclaw/main`, `openclaw/research`
- Session persistence via `user` field
- Streaming support (SSE)
"""
from typing import List, Optional, Tuple
from litellm.secret_managers.main import get_secret_str
from ...openai.chat.gpt_transformation import OpenAIGPTConfig
class OpenClawChatConfig(OpenAIGPTConfig):
"""
OpenClaw configuration for chat completions.
OpenClaw agents are targeted via the model field:
- `openclaw/main` -> main agent
- `openclaw/research` -> research agent
- `openclaw/<agent-id>` -> any configured agent
Environment variables:
- OPENCLAW_API_BASE: Gateway URL (e.g., http://localhost:18789)
- OPENCLAW_API_KEY: Gateway auth token
"""
def get_supported_openai_params(self, model: str) -> List[str]:
"""OpenClaw supports standard OpenAI params plus user for session persistence."""
return [
"stream",
"stop",
"temperature",
"top_p",
"max_tokens",
"max_completion_tokens",
"presence_penalty",
"frequency_penalty",
"logit_bias",
"user", # Used for session key derivation
"n",
"tools",
"tool_choice",
"response_format",
]
def _get_openai_compatible_provider_info(
self, api_base: Optional[str], api_key: Optional[str]
) -> Tuple[Optional[str], Optional[str]]:
"""
Get OpenClaw API base and key from environment or parameters.
OpenClaw requires an auth token when gateway.auth.mode is set.
"""
api_base = api_base or get_secret_str("OPENCLAW_API_BASE")
dynamic_api_key = api_key or get_secret_str("OPENCLAW_API_KEY") or ""
return api_base, dynamic_api_key
def map_openai_params(
self,
non_default_params: dict,
optional_params: dict,
model: str,
drop_params: bool,
) -> dict:
"""
Map OpenAI params to OpenClaw format.
OpenClaw is fully OpenAI-compatible, so minimal transformation needed.
The model field can include agent targeting: openclaw/main -> agent:main
"""
return super().map_openai_params(
non_default_params=non_default_params,
optional_params=optional_params,
model=model,
drop_params=drop_params,
)

View file

@ -4813,6 +4813,7 @@ def embedding( # noqa: PLR0915
custom_llm_provider == "openai_like"
or custom_llm_provider == "llamafile"
or custom_llm_provider == "lm_studio"
or custom_llm_provider == "openclaw"
):
api_base = (
api_base or litellm.api_base or get_secret_str("OPENAI_LIKE_API_BASE")

View file

@ -3107,6 +3107,7 @@ class LlmProviders(str, Enum):
POE = "poe"
CHUTES = "chutes"
XIAOMI_MIMO = "xiaomi_mimo"
OPENCLAW = "openclaw"
# Create a set of all provider values for quick lookup

View file

@ -7832,6 +7832,7 @@ class ProviderConfigManager:
LlmProviders.HOSTED_VLLM: (lambda: litellm.HostedVLLMChatConfig(), False),
LlmProviders.LLAMAFILE: (lambda: litellm.LlamafileChatConfig(), False),
LlmProviders.LM_STUDIO: (lambda: litellm.LMStudioChatConfig(), False),
LlmProviders.OPENCLAW: (lambda: litellm.OpenClawChatConfig(), False),
LlmProviders.GALADRIEL: (lambda: litellm.GaladrielChatConfig(), False),
LlmProviders.REPLICATE: (lambda: litellm.ReplicateConfig(), False),
LlmProviders.HUGGINGFACE: (lambda: litellm.HuggingFaceChatConfig(), False),