mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-07 08:26:10 +00:00
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:
parent
3f1bda57e2
commit
2a1df4c587
8 changed files with 277 additions and 0 deletions
186
docs/my-website/docs/providers/openclaw.md
Normal file
186
docs/my-website/docs/providers/openclaw.md
Normal 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
|
||||
```
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
83
litellm/llms/openclaw/chat/transformation.py
Normal file
83
litellm/llms/openclaw/chat/transformation.py
Normal 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,
|
||||
)
|
||||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue