Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export PRIME_API_KEY=...


### Model Providers
We currently support most major clients (OpenAI, Anthropic), as well as the router platforms (OpenRouter, Portkey, LiteLLM). For local models, we recommend using vLLM (which interfaces with the [OpenAI client](https://github.com/alexzhang13/rlm/blob/main/rlm/clients/openai.py)). To view or add support for more clients, start by looking at [`rlm/clients/`](https://github.com/alexzhang13/rlm/tree/main/rlm/clients).
We currently support most major clients (OpenAI, Anthropic), as well as the router platforms (OpenRouter, Portkey). For local models, we recommend using vLLM (which interfaces with the [OpenAI client](https://github.com/alexzhang13/rlm/blob/main/rlm/clients/openai.py)). To view or add support for more clients, start by looking at [`rlm/clients/`](https://github.com/alexzhang13/rlm/tree/main/rlm/clients).

## Relevant Reading
* **[Dec '25]** [Recursive Language Models arXiv](https://arxiv.org/abs/2512.24601)
Expand Down
4 changes: 2 additions & 2 deletions docs/api/rlm.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ RLM(
#### `backend`
{: .no_toc }

**Type:** `Literal["openai", "portkey", "openrouter", "vllm", "litellm", "anthropic"]`
**Type:** `Literal["openai", "portkey", "openrouter", "vllm", "anthropic"]`
**Default:** `"openai"`

The LM provider backend to use for the root model.
Expand Down Expand Up @@ -104,7 +104,7 @@ Configuration passed to the LM client. Required fields vary by backend:
| `portkey` | `model_name`, `api_key` | `base_url` |
| `openrouter` | `model_name` | `api_key` |
| `vllm` | `model_name`, `base_url` | — |
| `litellm` | `model_name` | varies by provider |


```python
backend_kwargs = {
Expand Down
2 changes: 1 addition & 1 deletion docs/src/app/api/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ print(result.response)`} />
[<code key="2" className="text-sm">"anthropic"</code>, "Anthropic API"],
[<code key="3" className="text-sm">"portkey"</code>, "Portkey AI gateway"],
[<code key="4" className="text-sm">"openrouter"</code>, "OpenRouter"],
[<code key="5" className="text-sm">"litellm"</code>, "LiteLLM (multi-provider)"],

[<code key="6" className="text-sm">"vllm"</code>, "Local vLLM server"],
]}
/>
Expand Down
16 changes: 1 addition & 15 deletions docs/src/app/backends/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default function BackendsPage() {

<p className="text-muted-foreground mb-6">
<p>
RLMs natively support a wide range of language model providers, including <code>OpenAI</code>, <code>Anthropic</code>, <code>Portkey</code>, <code>OpenRouter</code>, and <code>LiteLLM</code>. Additional providers can be supported with minimal effort. The <code>backend_kwargs</code> are named arguments passed directly to the backend client.
RLMs natively support a wide range of language model providers, including <code>OpenAI</code>, <code>Anthropic</code>, <code>Portkey</code>, and <code>OpenRouter</code>. Additional providers can be supported with minimal effort. The <code>backend_kwargs</code> are named arguments passed directly to the backend client.
</p>
</p>

Expand Down Expand Up @@ -64,20 +64,6 @@ export default function BackendsPage() {

<hr className="my-8 border-border" />

<h2 className="text-2xl font-semibold mb-4">LiteLLM</h2>
<p className="text-muted-foreground mb-4">
<a href="https://docs.litellm.ai/docs/" className="text-primary underline font-medium" target="_blank" rel="noopener noreferrer">LiteLLM</a> is a universal interface for 100+ model providers, with support for local models and custom endpoints.
</p>
<CodeBlock code={`rlm = RLM(
backend="litellm",
backend_kwargs={
"model_name": "gpt-5-mini",
},
)
# Set provider API keys in environment`} />

<hr className="my-8 border-border" />

<h2 className="text-2xl font-semibold mb-4">vLLM (Local)</h2>
<p className="text-muted-foreground mb-4">Local model serving.</p>
<CodeBlock language="bash" code={`# Start vLLM server
Expand Down
6 changes: 1 addition & 5 deletions rlm/clients/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,6 @@ def get_client(

backend_kwargs.setdefault("base_url", "https://ai-gateway.vercel.sh/v1")
return OpenAIClient(**backend_kwargs)
elif backend == "litellm":
from rlm.clients.litellm import LiteLLMClient

return LiteLLMClient(**backend_kwargs)
elif backend == "anthropic":
from rlm.clients.anthropic import AnthropicClient

Expand All @@ -59,5 +55,5 @@ def get_client(
return AzureOpenAIClient(**backend_kwargs)
else:
raise ValueError(
f"Unknown backend: {backend}. Supported backends: ['openai', 'vllm', 'portkey', 'openrouter', 'litellm', 'anthropic', 'azure_openai', 'gemini', 'vercel']"
f"Unknown backend: {backend}. Supported backends: ['openai', 'vllm', 'portkey', 'openrouter', 'anthropic', 'azure_openai', 'gemini', 'vercel']"
)
105 changes: 0 additions & 105 deletions rlm/clients/litellm.py

This file was deleted.

1 change: 0 additions & 1 deletion rlm/core/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
"openrouter",
"vercel",
"vllm",
"litellm",
"anthropic",
"azure_openai",
"gemini",
Expand Down
26 changes: 0 additions & 26 deletions tests/clients/test_timeout.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,32 +140,6 @@ def test_timeout_passed_to_client(self):
assert async_call_kwargs["timeout"] == 120.0


class TestLiteLLMClientTimeout:
"""Tests for LiteLLM client timeout."""

def test_timeout_passed_to_completion(self):
"""Timeout should be passed to litellm.completion call."""
pytest.importorskip("litellm")
from rlm.clients.litellm import LiteLLMClient

mock_response = MagicMock()
mock_response.choices = [MagicMock()]
mock_response.choices[0].message.content = "Hello"
mock_response.usage.prompt_tokens = 10
mock_response.usage.completion_tokens = 5
mock_response.usage.total_tokens = 15

with patch(
"rlm.clients.litellm.litellm.completion", return_value=mock_response
) as mock_completion:
client = LiteLLMClient(model_name="gpt-4o", timeout=120.0)
client.completion("Hello")

mock_completion.assert_called_once()
call_kwargs = mock_completion.call_args[1]
assert call_kwargs["timeout"] == 120.0


class TestGeminiClientTimeout:
"""Tests for Gemini client timeout."""

Expand Down
16 changes: 0 additions & 16 deletions tests/test_imports.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,6 @@ def test_portkey_client_import(self):

assert PortkeyClient is not None

def test_litellm_client_import(self):
"""Test LiteLLMClient import."""
pytest.importorskip("litellm")
from rlm.clients.litellm import LiteLLMClient

assert LiteLLMClient is not None

def test_get_client_function(self):
"""Test get_client function import."""
from rlm.clients import get_client
Expand Down Expand Up @@ -322,7 +315,6 @@ def test_no_circular_imports(self):
("rlm.clients.openai", "openai"),
("rlm.clients.anthropic", "anthropic"),
("rlm.clients.portkey", "portkey_ai"),
("rlm.clients.litellm", "litellm"),
("rlm.environments.modal_repl", "modal"),
("rlm.environments.prime_repl", "prime_sandboxes"),
]
Expand Down Expand Up @@ -463,14 +455,6 @@ def test_all_client_classes_importable(self):
except Exception:
pass

try:
pytest.importorskip("litellm")
from rlm.clients.litellm import LiteLLMClient

assert isinstance(LiteLLMClient, type)
except Exception:
pass

def test_all_environment_classes_importable(self):
"""Test that all environment classes can be imported."""
from rlm.environments.base_env import BaseEnv, IsolatedEnv, NonIsolatedEnv
Expand Down
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading