fix(azure): forward api_version to aembedding() for Azure AI Foundry v1 endpoints - #24911
Conversation
…v1 endpoints When aembedding=True, api_version was not passed to self.aembedding(), causing get_azure_openai_client() to receive None instead of "v1". This made _is_azure_v1_api_version() return False, so AsyncAzureOpenAI was selected instead of AsyncOpenAI, constructing the wrong request URL and returning 404. Fixes BerriAI#24848 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Greptile SummaryThis PR fixes a silent parameter drop in the async embedding path for Azure AI Foundry:
Confidence Score: 5/5Safe to merge — the fix is minimal, correct, and well-tested with mock-only unit tests. Only a single P2 finding (incorrect sys.path depth in the test file) remains, which does not affect test execution or production behavior. The bug fix itself is a straightforward one-liner with proper regression coverage. No files require special attention.
|
| Filename | Overview |
|---|---|
| litellm/llms/azure/azure.py | One-line fix: adds api_version=api_version to the self.aembedding() call so the async embedding path selects the correct OpenAI client for Azure AI Foundry v1 endpoints. Change is correct and minimal. |
| tests/litellm/llms/azure/test_azure_embedding.py | New mock-only test file with 4 tests covering the regression, client type selection, base URL, and all v1 api_version variants. Minor issue: sys.path insert uses 5 .. instead of the correct 4. |
| tests/litellm/llms/azure/init.py | Empty package init file, no issues. |
Sequence Diagram
sequenceDiagram
participant Caller
participant Embed as embedding()
participant AEmbed as aembedding()
participant GetClient as get_azure_openai_client()
participant IsV1 as _is_azure_v1_api_version()
Caller->>Embed: "aembedding=True, api_version=v1"
Note over Embed: BEFORE FIX: api_version was dropped
Embed->>AEmbed: "...args, api_version=v1 (fix)"
AEmbed->>GetClient: "api_version=v1, _is_async=True"
GetClient->>IsV1: "api_version=v1"
IsV1-->>GetClient: "True"
GetClient-->>AEmbed: "AsyncOpenAI (not AsyncAzureOpenAI)"
AEmbed-->>Caller: "EmbeddingResponse"
Reviews (1): Last reviewed commit: "fix(azure): forward api_version to aembe..." | Re-trigger Greptile
| sys.path.insert( | ||
| 0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../../..")) | ||
| ) |
There was a problem hiding this comment.
sys.path depth is one level too deep
The path insert navigates 5 levels up from the file's directory (tests/litellm/llms/azure/), landing in the parent of the repo root rather than the repo root itself. Comparing with tests/litellm/llms/openai_like/test_assemblyai_provider.py — which sits at the same nesting depth and correctly uses "../../../.." (4 levels) — this should also use 4 .. segments:
| sys.path.insert( | |
| 0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../../..")) | |
| ) | |
| sys.path.insert( | |
| 0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../..")) | |
| ) |
In practice pytest's rootdir detection keeps the tests passing regardless, but the intent is wrong and could confuse future readers or fail in unusual invocation contexts.
012f470
into
BerriAI:litellm_oss_staging_04_01_2026
…v1 endpoints (#24911) When aembedding=True, api_version was not passed to self.aembedding(), causing get_azure_openai_client() to receive None instead of "v1". This made _is_azure_v1_api_version() return False, so AsyncAzureOpenAI was selected instead of AsyncOpenAI, constructing the wrong request URL and returning 404. Fixes #24848 Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…v1 endpoints (#24911) When aembedding=True, api_version was not passed to self.aembedding(), causing get_azure_openai_client() to receive None instead of "v1". This made _is_azure_v1_api_version() return False, so AsyncAzureOpenAI was selected instead of AsyncOpenAI, constructing the wrong request URL and returning 404. Fixes #24848 Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…v1 endpoints (BerriAI#24911) When aembedding=True, api_version was not passed to self.aembedding(), causing get_azure_openai_client() to receive None instead of "v1". This made _is_azure_v1_api_version() return False, so AsyncAzureOpenAI was selected instead of AsyncOpenAI, constructing the wrong request URL and returning 404. Fixes BerriAI#24848 Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…v1 endpoints (BerriAI#24911) When aembedding=True, api_version was not passed to self.aembedding(), causing get_azure_openai_client() to receive None instead of "v1". This made _is_azure_v1_api_version() return False, so AsyncAzureOpenAI was selected instead of AsyncOpenAI, constructing the wrong request URL and returning 404. Fixes BerriAI#24848
What
Fixes a silent parameter drop in the async embedding path for Azure AI Foundry.
Root Cause
In
BaseAzureLLM.embedding(), whenaembedding=True, the call toself.aembedding()was missingapi_version=api_version. This meantget_azure_openai_client()receivedNoneinstead of"v1", causing_is_azure_v1_api_version()to returnFalseandAsyncAzureOpenAIto be selected instead ofAsyncOpenAI. The wrong client constructs Azure-specific URLs that don't exist on AI Foundry endpoints, resulting in a 404ResourceNotFound.The sync path was unaffected — it passed
api_versiondirectly toget_azure_openai_client(). Only the async path (which the proxy always uses) had this bug.Fix
One-line fix in
litellm/llms/azure/azure.py: addapi_version=api_versionto theself.aembedding()call.Tests
Added
tests/litellm/llms/azure/test_azure_embedding.pywith:api_versionis forwarded throughembedding()→aembedding()get_azure_openai_client()returnsAsyncOpenAI(notAsyncAzureOpenAI) forapi_version="v1"/openai/v1/base URL is used for v1 clients"v1","latest","preview")Fixes #24848