OpenRouter embedding models fail due to LiteLLM missing provider route
## Problem
Agent Zero fails to initialize memory when the embedding model is configured to use **OpenRouter**. This is not a configuration mistake — it is a **LiteLLM limitation**.
LiteLLM supports OpenRouter for chat/completions, but **does not have a provider route for OpenRouter embeddings**. When Agent Zero calls `litellm.embedding()` with an OpenRouter model, LiteLLM either:
1. Throws `LLM Provider NOT provided` (if the model string lacks a recognized prefix)
2. Throws `Unmapped LLM provider for this endpoint` (if provider is explicitly set to `openrouter`)
This affects **any** OpenRouter embedding model, including:
- `nvidia/llama-nemotron-embed-vl-1b-v2:free`
- `sentence-transformers/all-MiniLM-L6-v2` (when served through OpenRouter)
- Any other OpenRouter-hosted embedding endpoint
## Error Examples
### Case 1: Provider = openrouter, model prefixed
```
litellm.exceptions.LiteLLMUnknownProvider: Unmapped LLM provider for this endpoint.
You passed model=openrouter/nvidia/llama-nemotron-embed-vl-1b-v2:free, custom_llm_provider=openrouter
```
### Case 2: Provider = openai (workaround attempt), no prefix
```
litellm.exceptions.BadRequestError: LLM Provider NOT provided.
You passed model=nvidia/llama-nemotron-embed-vl-1b-v2:free
```
## Root Cause
In `models.py`, `LiteLLMEmbeddingWrapper.__init__` constructs:
```python
self.model_name = f"{provider}/{model}" if provider != "openai" else model
```
Then calls:
```python
resp = embedding(model=self.model_name, input=[text], **self.kwargs)
```
LiteLLM's `get_llm_provider()` has no mapping for OpenRouter embeddings, so the call fails before reaching the API.
## Related Issues
- #797 — requested OpenRouter embedding support (closed as feature request)
- #1050 — same symptom, generic title, has PR #1070 (unclear if it addresses the LiteLLM root cause)
- #1076 — OpenRouter free models, related provider confusion
## Proposed Fix
Bypass LiteLLM for OpenRouter embeddings and call OpenRouter's OpenAI-compatible `/v1/embeddings` endpoint directly. This is the same approach many projects take when LiteLLM lacks a provider.
### Patch for `models.py`
Add a `_openrouter_embed()` helper and gate `embed_documents` / `embed_query`:
```python
def _openrouter_embed(self, texts: list) -> list:
import json
import urllib.request
api_key = self.kwargs.get("api_key", "")
if not api_key:
raise ValueError("OpenRouter API key not configured.")
url = "https://openrouter.ai/api/v1/embeddings"
model = self.model_name
if model.startswith("openrouter/"):
model = model[11:]
payload = json.dumps({"model": model, "input": texts}).encode("utf-8")
req = urllib.request.Request(url, data=payload, method="POST")
req.add_header("Authorization", f"Bearer {api_key}")
req.add_header("Content-Type", "application/json")
req.add_header("HTTP-Referer", "https://agent-zero.ai")
req.add_header("X-Title", "Agent Zero")
with urllib.request.urlopen(req, timeout=60) as resp:
result = json.loads(resp.read().decode("utf-8"))
return [d["embedding"] for d in result["data"]]
def _is_openrouter(self) -> bool:
return (
self.model_name.startswith("openrouter/")
or "openrouter.ai" in str(self.kwargs.get("api_base", ""))
)
def embed_documents(self, texts: list) -> list:
apply_rate_limiter_sync(self.a0_model_conf, " ".join(texts))
if self._is_openrouter():
return self._openrouter_embed(texts)
resp = embedding(model=self.model_name, input=texts, **self.kwargs)
...
def embed_query(self, text: str) -> list:
apply_rate_limiter_sync(self.a0_model_conf, text)
if self._is_openrouter():
return self._openrouter_embed([text])[0]
resp = embedding(model=self.model_name, input=[text], **self.kwargs)
...
```
## Environment
- Agent Zero version: v1.10 (Docker image `agent0ai/agent-zero:latest`)
- LiteLLM version: whatever ships in current image
- Host: Linux, Docker
## Workaround for Users (Until Fixed)
Apply the patch above inside the container, or switch to a **local** embedding model:
- Provider: `huggingface`
- Model: `sentence-transformers/all-MiniLM-L6-v2`
Local models avoid the LiteLLM provider problem entirely.
0 条评论