test(e2e): add live batches suite across providers and routing scenarios - #30958
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
| wrong token sum, or mispriced model fails this test. | ||
| """ | ||
| from litellm.batches.batch_utils import _handle_completed_batch | ||
| from litellm.types.utils import LiteLLMBatch |
There was a problem hiding this comment.
This has been added as a replacement for gap of e2e testing for batch polling and cost tracking
Greptile SummaryAdds a live e2e Batches API suite under
Confidence Score: 4/5The three bundled production fixes are all correct and well-tested; the main risk is the router registration reorder in proxy_server.py, which changes route-match priority for provider-prefixed batch and files paths. The upsert, data-URL, and completion_window fixes are targeted and each has a matching unit test. The router reorder is the change most likely to surprise existing users: moving batches_router and openai_files_router before llm_passthrough_router means /{provider}/v1/batches and /{provider}/v1/files are now matched by the LiteLLM handler before the raw passthrough, altering behaviour for callers who relied on the passthrough path for those routes. litellm/proxy/proxy_server.py (router registration order), tests/e2e/batches/capabilities.py (Azure raw_model vs. deployed model name)
|
| Filename | Overview |
|---|---|
| litellm/proxy/proxy_server.py | Moves batches_router and openai_files_router registration to before llm_passthrough_router/pass_through_router; changes FastAPI route-match priority so provider-prefix batch/files paths now hit the LiteLLM handler instead of the raw passthrough (behavioral change for existing callers). |
| enterprise/litellm_enterprise/proxy/hooks/managed_files.py | Changes DB write from create to upsert on unified_file_id, with a separate update_data dict that correctly excludes immutable fields (unified_file_id, created_by, team_id); prevents duplicate-key failures when batch output re-stores the same unified file. |
| litellm/litellm_core_utils/prompt_templates/image_handling.py | Adds the data-URL short-circuit (data:…;base64, early return) to both convert_url_to_base64 and async_convert_url_to_base64, making the two paths consistent and preventing impossible HTTP fetches on inline image data. |
| litellm/llms/vertex_ai/batches/transformation.py | Corrects completion_window from 24hrs to 24h to match the Literal[24h] type in LiteLLMBatch; the unit test mock and the transformation are now in sync. |
| tests/e2e/batches/test_batches_e2e.py | New parametrized lifecycle test covering four routing scenarios across all providers; CREATED_BATCH_STATUSES correctly excludes terminal states. |
| tests/e2e/batches/capabilities.py | Declarative provider x scenario matrix with id-shape classifiers; Azure raw_model / gateway deployment name mismatch noted in prior review thread. |
| tests/e2e/gateway/litellm-config.yml | Adds four batch model entries and three files_settings blocks; Bedrock s3_region_name is hardcoded to us-west-2 (noted in prior thread) while all credentials are env-var driven. |
Reviews (22): Last reviewed commit: "fix: update managed file metadata on ups..." | Re-trigger Greptile
|
Generated by Claude Code |
|
bugbot run Generated by Claude Code |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
Autofix Details
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Async image URL passthrough missing
- Added the same data URL passthrough to the async image conversion path with a regression test covering downloads disabled.
You can send follow-ups to the cloud agent here.
|
|
|
Good catch by Bugbot on the sync/async asymmetry; Generated by Claude Code |
|
bugbot run Generated by Claude Code |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 178f8da. Configure here.
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
…deployed model Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
mateo-berri
left a comment
There was a problem hiding this comment.
The unresolved item is the router ordering change in proxy_server.py: moving batches_router and openai_files_router before llm_passthrough_router means calls that previously fell through to the raw provider passthrough now hit LiteLLM's own handlers — callers relying on the old passthrough behavior for Anthropic or Bedrock batch paths can break silently
Is this a valid greptile concern?
|
No it's not. |
|
Generated by Claude Code |
|
On the 3/5 concern about The files router has registered Where the native files implementation still has gaps for a given provider, that is a gap to close in the native layer, not a reason to keep the dedicated routes permanently shadowed; this is the same resolution already reached on this PR for the batches reorder. The blast radius is scoped to exactly the two route families with dedicated, tested handlers, every other passthrough path is untouched, and the new e2e suite exercises file upload plus batch create/retrieve/cancel/list through these routes against live OpenAI, Azure, and Vertex AI APIs and passes Generated by Claude Code |
|
The developer's argument is correct and exactly mirrors the reasoning that resolved the The logic holds: Confidence score revised to 5/5. The optional comment in |
|
bugbot run Generated by Claude Code |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
Autofix Details
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Upsert skips file metadata update
- Updated managed file upserts to refresh metadata fields on conflicts and added a regression test for placeholder-to-metadata writes.
You can send follow-ups to the cloud agent here.
|
Generated by Claude Code |
|
Both items called out in the 4/5 summary were already resolved on this PR, and the only change since the last 5/5 review is the Bugbot autofix commit c06d611 that the new summary itself describes as correct On the router registration reorder: this exact concern has been raised and resolved twice on this PR, on 2026-06-25 for batches_router and again earlier today for openai_files_router, both times with the score revised to 5/5. Nothing about c06d611 touches proxy_server.py or routing; the commit only changes the managed-files upsert payload and adds a regression test. The conclusion stands: the dedicated routers own /{provider}/v1/batches and /{provider}/v1/files, passthrough winning them was an accident of registration order, and the e2e suite validates the affected paths live across OpenAI, Azure, and Vertex AI On the Azure raw_model vs deployed model name: that was fixed in commit 5a86253, which set raw_model to gpt-4.1-mini-batch to match the deployment in tests/e2e/gateway/litellm-config.yml, and the corresponding review thread is marked outdated. capabilities.py on the current head reads raw_model="gpt-4.1-mini-batch", so the JSONL body embeds the real deployment name for the encoded, model_param, and provider_fallback scenarios Generated by Claude Code |
|
You're correct on both counts. I've verified:
The 4/5 in the latest summary was stale — both flagged items were resolved before |
|
bugbot run Generated by Claude Code |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit c06d611. Configure here.
a16d9c6
into
litellm_internal_staging
…ios (BerriAI#30958) * tests: add e2e tests for spend, budgets and llms * style: make chained comparison of status_code clearer Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * remove e2e_tests folder * test: add spend tracking tests * fix: p0 issues, added types and shared functions for each test suite * style: carry clearer status_code comparison into renamed e2e dir * refactor: migrate to gateway client * fix: add new tests, split gateway * test(e2e): add live batches suite across providers and routing scenarios * test(batches): cover real cost tracking on completed batch retrieve * test(e2e): assert managed vs raw file and batch id shapes per routing scenario * test(e2e): assert full response shape of each batches and files endpoint * test(e2e): only accept transitional statuses for a freshly created batch * test(prompt-factory): make test_convert_url deterministic with a data URL picsum.photos is down (HTTP 522), so test_convert_url failed on every run. Swap the live external image for an inline data: URL and assert the round-trip through convert_url_to_base64 genuinely. A data URL is already inline base64 image data, so convert_url_to_base64 now short-circuits it instead of attempting an impossible HTTP fetch; add a regression for that branch in the mapped image_handling test * fix: pass through async image data urls * fix(image-handling): short-circuit data URLs in async path too Bugbot flagged that convert_url_to_base64 returns data: base64 URLs unchanged but async_convert_url_to_base64 still tried to fetch them, so async OCR flows (Bedrock, Azure) would reject inline images the sync path accepts. Add the same guard to the async function and a regression test that asserts the async path returns the data URL without touching the HTTP client * Fix: openai batches lifecycle * Fix: add e2e azure openai tests * Fix e2e for vertex ai * Add all models for testing * test(managed-files): assert idempotent upsert in store_unified_file_id store_unified_file_id switched from create to upsert to avoid UniqueViolationError when re-storing the same unified_file_id (e.g. batch output files stored before metadata is available). Update the unit test to assert the upsert call and its create payload instead of the removed create call. * test(batches): reconcile vertex_ai native batch-id comment with fallback guard * fix(test-config): keep rust-ocr models in model_list by moving files_settings after it * fix(test-config): move batch models after OCR block to keep merge with internal_staging clean * fix(batches): use '24hrs' completion window and allow managed-files listing with provider filter Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * style: ruff format transformation.py and endpoints.py Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(e2e/batches): set Azure raw_model to gpt-4.1-mini-batch to match deployed model Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(vertex-ai/batches): correct completion_window to 24h per Literal type definition * test(vertex-ai/batches): align completion_window assertion to 24h * fix: update managed file metadata on upsert --------- Co-authored-by: mubashir1osmani <mubashir.osmani777@gmail.com> Co-authored-by: Mateo Wang <277851410+mateo-berri@users.noreply.github.com> Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Current state of the repo:
OPENAI: WORKS✅
AZURE OPENAI: WORKS✅
VERTEX AI: WORKS✅
BEDROCK: DOESNT WORK❌
This test setup tests the following things:
Summary
Adds a live e2e suite at
tests/e2e/batches/covering the Batches API across every provider LiteLLM supports (OpenAI, Azure, Vertex AI, Bedrock, plus Anthropic retrieve), exercising all four proxy create-routing scenarios: file encoded with model, unified managed file, model from header/query/body, and provider fallback. It runs the synchronous tier only; a batch's completion window is 24h, so the tests assert upload then create then retrieve then cancel then list (where a provider supports the op) and never wait for a batch to reach completed. Everything created is deleted on teardown.Based on

litellm_e2e_testingsince it builds on that branch's e2e harness; retarget tolitellm_internal_stagingonce the harness lands.Note
Medium Risk
Upsert and router registration order change production batch/file paths; e2e additions are lower risk but depend on live provider credentials.
Overview
Adds a live e2e Batches API suite under
tests/e2e/batches/(OpenAI, Azure, Vertex; four proxy routing paths) with shared multipart upload helpers, gateway batch/files_settingsconfig, and lifecycle keys that support model restrictions anduser_idfor managed-batch ACL. Extends spend e2e with/spend/tagsaccuracy and optional failure-row checks.Fixes batch/managed-file behavior:
store_unified_file_iduses Prisma upsert so later writes can refreshfile_objectand storage fields instead of failing on duplicate ids. Sync and async image URL conversion now pass throughdata:...;base64,...URLs without HTTP fetch. Vertex batch responses usecompletion_window24h(not24hrs).batches_router/openai_files_routerare registered earlier on the proxy app. Unit coverage adds managed-file upsert, data-URL image handling, and completed-batch cost-from-output-file integration.Reviewed by Cursor Bugbot for commit c06d611. Bugbot is set up for automated code reviews on this repo. Configure here.