SaitejaMothukuri's picture
Deploy semantic-cache
8186ed2 verified
Raw
History Blame Contribute Delete
2.1 kB
"""OpenRouter embeddings — batched, L2-normalized float32 vectors.
Uses a raw HTTP POST rather than the OpenAI SDK: OpenRouter's embeddings
response is not fully SDK-shaped, so the SDK parser raises "No embedding data
received". The raw path (same as the sibling RAG project) is reliable.
"""
from __future__ import annotations
import json
import os
import urllib.error
import urllib.request
import numpy as np
from ._openrouter import BASE_URL, _HEADERS, get_api_key
DEFAULT_EMBED_MODEL = "nvidia/llama-nemotron-embed-vl-1b-v2:free"
EMBED_DIM = 2048 # llama-nemotron-embed-vl-1b-v2
def get_embed_model() -> str:
return os.environ.get("OPENROUTER_EMBED_MODEL", DEFAULT_EMBED_MODEL).strip()
def _post(inputs, api_key: str, model: str) -> list[list[float]]:
body = json.dumps({"model": model, "input": list(inputs)}).encode()
req = urllib.request.Request(
f"{BASE_URL}/embeddings",
data=body,
headers={
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
**_HEADERS,
},
method="POST",
)
try:
with urllib.request.urlopen(req, timeout=120) as resp:
data = json.loads(resp.read())
except urllib.error.HTTPError as exc:
detail = exc.read()[:300].decode("utf-8", "ignore")
raise RuntimeError(f"OpenRouter embeddings HTTP {exc.code}: {detail}") from exc
# Preserve request order (OpenAI-compatible responses carry an index).
rows = sorted(data["data"], key=lambda d: d.get("index", 0))
return [r["embedding"] for r in rows]
def embed_texts(texts, api_key=None, model=None) -> np.ndarray:
api_key = api_key or get_api_key()
if not api_key:
raise RuntimeError("OPENROUTER_API_KEY is not set. See the README.")
vecs = _post(texts, api_key, model or get_embed_model())
arr = np.asarray(vecs, dtype=np.float32)
norms = np.linalg.norm(arr, axis=1, keepdims=True)
norms[norms == 0] = 1.0
return arr / norms
def embed_one(text: str, **kw) -> np.ndarray:
return embed_texts([text], **kw)[0]