Skip to content

Litellm oss staging 04 14 2026 p1#25744

Open
krrish-berri-2 wants to merge 5 commits intomainfrom
litellm_oss_staging_04_14_2026_p1
Open

Litellm oss staging 04 14 2026 p1#25744
krrish-berri-2 wants to merge 5 commits intomainfrom
litellm_oss_staging_04_14_2026_p1

Conversation

@krrish-berri-2
Copy link
Copy Markdown
Contributor

Relevant issues

Pre-Submission checklist

Please complete all items before asking a LiteLLM maintainer to review your PR

  • I have Added testing in the tests/test_litellm/ directory, Adding at least 1 test is a hard requirement - see details
  • My PR passes all unit tests on make test-unit
  • My PR's scope is as isolated as possible, it only solves 1 specific problem
  • I have requested a Greptile review by commenting @greptileai and received a Confidence Score of at least 4/5 before requesting a maintainer review

Delays in PR merge?

If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-review).

CI (LiteLLM team)

CI status guideline:

  • 50-55 passing tests: main is stable with minor issues.
  • 45-49 passing tests: acceptable but needs attention
  • <= 40 passing tests: unstable; be careful with your merges and assess the risk.
  • Branch creation CI run
    Link:

  • CI run for the last commit
    Link:

  • Merge / cherry-pick CI run
    Links:

Screenshots / Proof of Fix

Type

🆕 New Feature
🐛 Bug Fix
🧹 Refactoring
📖 Documentation
🚄 Infrastructure
✅ Test

Changes

lovek629 and others added 4 commits April 14, 2026 18:54
…#25696)

* feat(proxy): add NO_OPENAPI env var to disable /openapi.json endpoint - Fixes #25538

* test(proxy): add tests for _get_openapi_url

---------

Co-authored-by: Progressive-engg <lov.kumari55@gmail.com>
* feat(prometheus): add api_provider label to spend metric

Add `api_provider` to `litellm_spend_metric` labels so users can
build Grafana dashboards that break down spend by cloud provider
(e.g. bedrock, anthropic, openai, azure, vertex_ai).

The `api_provider` label already exists in UserAPIKeyLabelValues and
is populated from `standard_logging_payload["custom_llm_provider"]`,
but was not included in the spend metric's label list.

* add api_provider to requests metric + add test

Address review feedback:
- Add api_provider to litellm_requests_metric too (same call-site as
  spend metric, keeps label sets in sync)
- Add test_api_provider_in_spend_and_requests_metrics following the
  existing pattern in test_prometheus_labels.py
… align with `post_call` guardrail (#25641)

* fix: ensure `litellm_metadata` is attached to pre_call to align with post_call

* refactor: remove unused BaseTranslation._ensure_litellm_metadata

* refactor: module level imports for ensure_litellm_metadata and CodeQL

* fix: update based off of Codex comment

* revert: undo usage of `_guardrail_litellm_metadata`
@vercel
Copy link
Copy Markdown

vercel bot commented Apr 15, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
litellm Ready Ready Preview, Comment Apr 15, 2026 3:31am

Request Review

@codspeed-hq
Copy link
Copy Markdown
Contributor

codspeed-hq bot commented Apr 15, 2026

Merging this PR will not alter performance

✅ 16 untouched benchmarks


Comparing litellm_oss_staging_04_14_2026_p1 (20758e6) with main (9790a46)

Open in CodSpeed

…chema (#25740)

When response_format={"type": "json_object"} is sent without a JSON
schema, _create_json_tool_call_for_response_format builds a tool with an
empty schema (properties: {}). The model follows the empty schema and
returns {} instead of the actual JSON the caller asked for.

This patch:
- Skips synthetic json_tool_call injection when no schema is provided.
  The model already returns JSON when the prompt asks for it.
- Fixes finish_reason: after _filter_json_mode_tools strips all
  synthetic tool calls, finish_reason stays "tool_calls" instead of
  "stop". Callers (like the OpenAI SDK) misinterpret this as a pending
  tool invocation.

json_schema requests with an explicit schema are unchanged.

Co-authored-by: Claude <noreply@anthropic.com>
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 15, 2026

Greptile Summary

This staging PR bundles four independent fixes/features: (1) Bedrock Converse now skips synthetic tool injection for json_object requests without a schema and corrects finish_reason to "stop" after filtering all synthetic tool calls; (2) litellm_metadata is now populated on the pre_call guardrail path to match the post_call path; (3) api_provider label is added to litellm_requests_metric and litellm_spend_metric; (4) a NO_OPENAPI env var disables /openapi.json, and pricing is added for openrouter/google/gemini-3.1-flash-lite-preview. All remaining findings are P2 style cleanup.

Confidence Score: 5/5

Safe to merge — all functional changes are correct and well-tested; only P2 style issues remain.

All four bundled changes are logically sound and backed by new unit tests. The three findings are P2 style issues (duplicate import, inline import, missing blank line) that do not affect runtime behavior.

litellm/proxy/proxy_server.py (duplicate import) and litellm/proxy/guardrails/guardrail_hooks/unified_guardrail/unified_guardrail.py (inline import) have minor style cleanup needed.

Important Files Changed

Filename Overview
litellm/llms/bedrock/chat/converse_transformation.py Skips synthetic tool injection for json_object with no schema, and fixes finish_reason to "stop" when json_mode filters all tool calls; logic is correct and well-covered by new unit tests.
litellm/proxy/proxy_server.py Wires _get_openapi_url() into FastAPI app constructor; duplicate import of _get_openapi_url on lines 496 and 499 should be cleaned up.
litellm/proxy/utils.py Adds _get_openapi_url() helper following the same pattern as _get_docs_url; missing one blank line before the function definition.
litellm/proxy/guardrails/guardrail_hooks/unified_guardrail/unified_guardrail.py Adds _ensure_litellm_metadata to align pre_call guardrail with post_call; deferred import inside the function body should be moved to module level per project style guide.
litellm/types/integrations/prometheus.py Adds api_provider label to litellm_requests_metric and litellm_spend_metric; backwards-compatible addition with appropriate tests.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["response_format param"] --> B{type?}
    B -->|json_schema + model supports native| C["outputConfig path\n(no tool injection)"]
    B -->|json_schema + fallback model| D["Inject synthetic\njson_tool_call tool"]
    B -->|json_object with schema| D
    B -->|json_object NO schema| E["Skip tool injection\n(NEW: prevents empty {} response)"]
    C --> F["finish_reason from stopReason"]
    D --> G["_filter_json_mode_tools"]
    G --> H{filtered_tools empty\nand tools had calls?}
    H -->|yes| I["finish_reason = 'stop'\n(NEW: was 'tool_calls')"]
    H -->|no| F
    E --> F
Loading

Reviews (1): Last reviewed commit: "fix(bedrock): skip synthetic tool inject..." | Re-trigger Greptile

_get_openapi_url,
_get_projected_spend_over_limit,
_get_redoc_url,
_get_openapi_url,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Duplicate import

_get_openapi_url is imported twice in the same block (lines 496 and 499). Python silently accepts this, but the duplicate is dead code and should be removed.

Suggested change
_get_openapi_url,
_get_projected_spend_over_limit,

Comment on lines +58 to +61
from litellm.llms.base_llm.guardrail_translation.base_translation import (
BaseTranslation,
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Inline import inside module-level function

Per the project style guide (CLAUDE.md), imports belong at the top of the file. The commit history notes "refactor: module level imports for ensure_litellm_metadata" was an explicit intent, but the import was left inside the function body. Move it to the top of the file unless a circular-import comment explains why it must be deferred.

Suggested change
from litellm.llms.base_llm.guardrail_translation.base_translation import (
BaseTranslation,
)
user_metadata = BaseTranslation.transform_user_api_key_dict_to_metadata(

Context Used: CLAUDE.md (source)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!


return "/"

def _get_openapi_url() -> Optional[str]:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Missing blank line before top-level function

PEP 8 and the surrounding code style require two blank lines between top-level definitions. Only one blank line separates _get_docs_url and _get_openapi_url.

Suggested change
def _get_openapi_url() -> Optional[str]:
def _get_openapi_url() -> Optional[str]:

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

_get_openapi_url,
_is_projected_spend_over_limit,
_is_valid_team_configs,
get_custom_url,
Comment on lines +58 to +60
from litellm.llms.base_llm.guardrail_translation.base_translation import (
BaseTranslation,
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants