ITADN

OpenRouter embedding models fail due to LiteLLM missing provider route

#1597Openjarmen423 创建于 2026-05-02
J
jarmen423commented
## 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 条评论