fix(cohere): honor COHERE_API_BASE for embeddings

The cohere embedding branch in the dispatch passed the caller's api_base
straight through with no env fallback, so COHERE_API_BASE was silently
ignored for embeddings — the request went to the hardcoded
api.cohere.ai/v2/embed host. The rerank path (rerank_api/main.py) already
reads the same variable, and the databricks/hosted_vllm/openrouter
embedding branches follow the same convention; this branch was the
asymmetric one (same family as voyage's #49411).

Adds two respx regression tests: the env-routed gateway URL is used when
the variable is set, and the hardcoded default still applies when it is
not.

Signed-off-by: 郑润泽 <506166760@qq.com>
This commit is contained in:
郑润泽 2026-11-06 03:41:34 +08:00
parent 85bc58085e
commit 103adf68e3
2 changed files with 43 additions and 0 deletions

View file

@ -7196,6 +7196,10 @@ def embedding(
or get_secret_str("CO_API_KEY")
or litellm.api_key
)
# Honor COHERE_API_BASE like the rerank path (rerank_api/main.py) and
# the databricks/hosted_vllm embedding branches do; without this the
# gateway URL was silently ignored for embeddings.
api_base = api_base or litellm.api_base or get_secret_str("COHERE_API_BASE")
response = base_llm_http_handler.embedding(
model=model,

View file

@ -33,3 +33,42 @@ async def test_bedrock_cohere_embedding_sends_the_caller_timeout(
assert route.calls.last.request.extensions["timeout"]["read"] == 45
assert response.data[0]["embedding"] == [0.1, 0.2]
COHERE_DEFAULT_EMBED_URL: Final = "https://api.cohere.ai/v2/embed"
async def test_cohere_embedding_honors_cohere_api_base_env(
respx_mock: respx.MockRouter, monkeypatch: pytest.MonkeyPatch
) -> None:
"""`COHERE_API_BASE` must be honored for embeddings, like the rerank path and
the databricks/hosted_vllm embedding branches already do (#49411 family)."""
gateway: Final = "https://gateway.example.com/v1/embed"
monkeypatch.setattr(litellm, 'disable_aiohttp_transport', True)
monkeypatch.setenv("COHERE_API_BASE", gateway)
route: Final = respx_mock.post(gateway).mock(
return_value=httpx.Response(200, json=COHERE_EMBED_RESPONSE)
)
response: Final = await litellm.aembedding(
model="cohere/embed-english-v3.0", input=["hello"], api_key="mock-key"
)
assert route.calls.call_count == 1
assert response.data[0]["embedding"] == [0.1, 0.2]
async def test_cohere_embedding_keeps_the_default_url_without_the_env(
respx_mock: respx.MockRouter, monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.setattr(litellm, 'disable_aiohttp_transport', True)
monkeypatch.delenv("COHERE_API_BASE", raising=False)
route: Final = respx_mock.post(COHERE_DEFAULT_EMBED_URL).mock(
return_value=httpx.Response(200, json=COHERE_EMBED_RESPONSE)
)
response: Final = await litellm.aembedding(
model="cohere/embed-english-v3.0", input=["hello"], api_key="mock-key"
)
assert route.calls.call_count == 1
assert response.data[0]["embedding"] == [0.1, 0.2]