fix(proxy): recognize *.cognitiveservices.azure.com as OpenAI-compatible in pass-through cost tracking - #29726
Conversation
|
Too many files changed for review. ( |
1e1d075 to
245ecec
Compare
Congrats! CodSpeed is installed 🎉
You will start to see performance impacts in the reports once the benchmarks are run from your default branch.
|
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Azure OpenAI resources created via the newer "Azure AI Foundry" /
Cognitive Services pathway live on `*.cognitiveservices.azure.com`
subdomains, not the older `openai.azure.com`. Both are valid Azure
OpenAI surfaces in production today.
The OpenAI pass-through cost-tracking handler hard-codes only the older
hostname in five places (four `is_openai_*_route` methods on
OpenAIPassthroughLoggingHandler, plus is_openai_route on
PassThroughEndpointLogging). As a result, calls from newer Azure
deployments are silently classified as "not an OpenAI route", the
dispatch into the cost-tracking handler is skipped, and tokens/cost
never get extracted into LiteLLM_SpendLogs — the row gets written with
prompt_tokens=0, completion_tokens=0, spend=0, model='unknown'.
Reproduced 2026-06-04 against a real Azure OpenAI deployment on
`*.cognitiveservices.azure.com` proxied through LiteLLM v1.88.0.
Fix: factor the hostname check into a single helper
`_is_openai_compatible_host` listing all three recognized surfaces
(api.openai.com, openai.azure.com, cognitiveservices.azure.com), and
have all five call sites delegate to it. Purely additive — never
weakens recognition for the originally-supported hostnames.
Adds a test
`test_is_openai_route_recognizes_cognitiveservices_azure_com` that
exercises all four `is_openai_*_route` static methods against
`*.cognitiveservices.azure.com` URLs (positive cases per route + a
small cross-route negative to confirm route-specific path matching
still works on the new hostname).
Out of scope for this PR (separate followup):
- `openai_passthrough_handler` calls chat/completions
`transform_response` on Responses API payloads (`output:` not
`choices:`), which throws inside the dispatch and drops the
SpendLogs row entirely. Recognized + tracked separately.
245ecec to
99084ae
Compare
|
Heads-up the
Let me know if you'd like me to rebase to a new branch! |
|
The failure (run #26991540029, job 79652555702) is three tests in
All three fail with the same root cause — HuggingFace Hub rate-limited the tokenizer download: This PR's scope doesn't touch tokenizers, HuggingFace, or that test file at all. My diff is only in:
Zero overlap with If a CI re-run after the HF Hub backoff clears doesn't get it green, happy to help triage further — but I don't think there's anything to fix on my side. (Possible long-term suggestion for the maintainers — separate from this PR — would be to mock or pre-cache the HF tokenizer responses in CI to avoid this flake class, since it'll trip any contributor whose PR happens to overlap with a busy CI window. Happy to open a separate issue for that if useful.) |
The auth-and-jwt job's previous failure was a transient HuggingFace Hub 429 rate-limit hitting tokenizer downloads in tests/proxy_unit_tests/test_custom_tokenizer_bug.py (unrelated to this PR's scope — see prior comment). Empty commit to re-run all checks; no code change.
|
Closing in favor of #29730 — same diff, but opened directly against `litellm_oss_branch` from the start so the `Verify PR source branch` check (sticky from this PR's initial `main` targeting) doesn't shadow real CI signal. Discussion + maintainer review can continue there. |
Summary
Azure OpenAI resources created via the newer "Azure AI Foundry" / Cognitive Services pathway live on `*.cognitiveservices.azure.com` subdomains, not the older `openai.azure.com`. Both are valid Azure OpenAI surfaces in production today.
The OpenAI pass-through cost-tracking handler hard-codes only the older hostname in five places:
As a result, calls from newer Azure deployments are silently classified as "not an OpenAI route", the dispatch into the cost-tracking handler is skipped, and tokens / cost never get extracted into `LiteLLM_SpendLogs` — the row is written with `prompt_tokens=0, completion_tokens=0, spend=0, model='unknown'`.
Reproducer
Verified 2026-06-04 against a real Azure OpenAI deployment on `*.cognitiveservices.azure.com` proxied through LiteLLM v1.88.0.
Fix
Factor the hostname check into a single helper `_is_openai_compatible_host` listing all three recognized surfaces (`api.openai.com`, `openai.azure.com`, `cognitiveservices.azure.com`), and have all five call sites delegate to it.
Purely additive — never weakens recognition for the originally-supported hostnames. Every test case that passed before continues to pass.
Tests
Adds `test_is_openai_route_recognizes_cognitiveservices_azure_com` that exercises all four `is_openai__route` static methods against `.cognitiveservices.azure.com` URLs:
All 24 tests in `test_openai_passthrough_logging_handler.py` pass locally including the new one.
Checklist
Out of scope for this PR
Tracked separately: `openai_passthrough_handler` calls chat/completions `transform_response` on Responses API payloads (which use `output:` not `choices:`), throws inside the dispatch, and drops the SpendLogs row entirely. The right fix is to use the existing `OpenAIResponsesAPIConfig.transform_response_api_response` for the `is_responses` branch — happy to follow up with a separate PR.