Commit graph

13345 commits

Author SHA1 Message Date
Sameer Kankute
a6fb16aea0
Merge pull request #23103 from netbrah/fix/anthropic-tool-schema-type-enforcement
fix(anthropic): enforce type:"object" on tool input schemas in _map_tool_helper
2026-03-11 13:06:59 +05:30
Sameer Kankute
b9a311743f
Merge pull request #23104 from netbrah/fix/anthropic-deduplicate-tool-results
fix(anthropic): deduplicate tool_result messages by tool_call_id
2026-03-11 13:04:59 +05:30
yuneng-jiang
ff2f96d09e Fix mcp_tool_permissions JSON string deserialization in _resolve_team_allowed_mcp_servers
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 00:23:40 -07:00
yuneng-jiang
860cb17571 Fix cross-team MCP server info disclosure and restricted key bypass
The GET /v1/mcp/server endpoint allowed any authenticated user to pass
an arbitrary team_id and enumerate another team's MCP server config.
Restricted virtual keys could also use the team_id param to bypass
their access limitations. Add team membership check for non-admins
and block restricted keys from using the team_id filter.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 23:48:30 -07:00
yuneng-jiang
c362ae5095 Add team-scoped MCP server filtering for key creation and fix UnboundLocalError
When creating a key, the MCP server list now filters by the selected team's
allowed servers. Also fixes UnboundLocalError on `is_restricted_virtual_key`
when `team_id` query param was provided to GET /v1/mcp/server.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 23:15:14 -07:00
Sameer Kankute
2a9bcf2530 Fix greptile reviews 2026-03-11 11:41:29 +05:30
Sameer Kankute
d25b8e6d00 Add support for gcs url for vertex ai embeddings 2026-03-11 10:58:04 +05:30
Sameer Kankute
b108c02fd7 Add support for gemini multimodal embedings 2026-03-11 10:08:17 +05:30
Cesar Garcia
260c37d670
Merge pull request #21398 from Chesars/feat/openai-like-responses-api
feat(openai_like): add Responses API support to JSON providers
2026-03-11 00:15:06 -03:00
Chesars
da76e1738a fix(perplexity): restore type='message' safety net for list inputs
Perplexity requires type='message' on input items. Add _ensure_message_type
to automatically set it when missing, matching the old _format_input behavior.
2026-03-11 00:14:13 -03:00
Chesars
636b474a8a fix(perplexity): remove redundant dict-cost check in Usage and add streaming cost test
Remove the isinstance(cost, dict) guard from Usage.__init__ — ResponseAPIUsage.parse_cost
validator already converts Perplexity's cost dict to float before it reaches Usage.

Add test_streaming_cost_dict_to_float_via_validator to verify the dict→float conversion
works end-to-end through transform_streaming_response (pydantic recursive construction).
2026-03-10 23:52:17 -03:00
Chesars
8b385120b9 fix: add isinstance guard for aliases field and remove unused helper 2026-03-10 22:58:31 -03:00
Cesar Garcia
2ed4119542
Update tests/test_litellm/test_model_cost_aliases.py
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-03-10 22:56:08 -03:00
Ishaan Jaff
82a9b0ea03
feat(chat-ui): responses API + MCP tool execution in /chat (#23297)
* feat(ui): add Chat UI v0 — standalone LiteLLM-branded chat window

Adds a full chat UI accessible from the sidebar Chat link (opens in new tab).
- Standalone route at /chat (outside dashboard layout — no Navbar/Sidebar chrome)
- Claude.ai-style layout: model selector top-left, LiteLLM logo center, settings top-right
- Greeting with time-of-day, centered input card, suggestion chips (Write/Learn/Code/Brainstorm)
- Sliding conversation history sidebar with Cmd+K search, rename, delete, date grouping
- localStorage-backed conversation persistence (litellm_chat_history_v1)
- Streaming completions via makeOpenAIChatCompletionRequest with AbortController stop support
- MCP server picker (toggle servers on/off per conversation)
- LiteLLM aesthetic: white/light-gray background, Ant Design blue (#1677ff) primary, system font
- Sidebar2: Chat menu item opens in new tab via window.open

* feat(chat-ui): responses API + MCP tool execution display

- Switch /chat from chat completions to responses API (previous_response_id session chaining)
- Add MCP server picker with search filter in chat input bar
- Show MCP tool call events (list_tools + call_tool) inline in chat via MCPEventsDisplay
- Add tool chip strip showing available tools when MCP servers are selected
- Non-blocking MCP toggle: server added immediately, verification in background (works for no-auth MCPs like deepwiki)
- Add truncateAfterMessage to useChatHistory for edit/retry
- Sync activeConversationId on URL change (fixes stale conversation on new chat)
- Add "Open Chat" shortcut button to sidebar

* fix(chat-ui): switch to responses API, remove dead code, add tests

- Switch handleSend from makeOpenAIChatCompletionRequest to makeOpenAIResponsesRequest with previous_response_id session chaining
- Add responsesSessionId state; reset to null when starting a new conversation
- Remove unused ChatInputBar.tsx and ModelSelector.tsx (dead code)
- Add tests/test_litellm/test_chat_ui_responses_session.py covering previous_response_id forwarding and signature validation

* fix(chat-ui): address greptile review issues

- Reset responsesSessionId when activeConversationId changes (not just on new conversation)
- Wire onMCPEvent callback into makeOpenAIResponsesRequest; render MCPEventsDisplay below messages
- Clear mcpEvents on each new send
- Explicitly filter history to user/assistant roles only (no tool-role casting)
- Remove duplicate "Chat" menu item from sidebar (pinned button serves same purpose)
- Make Sider a flex column so "Open Chat" button actually pins to bottom
- Fix tests to intercept real HTTP requests and assert previous_response_id in body

* fix(chat-ui): address greptile review feedback (greploop iteration 1)

- Fix duplicate context: when responsesSessionId is set, only send the
  new user message as input (prior context is already server-side via
  session chaining). Full history is still sent on the first turn.
- Fix ephemeral MCP events: store events per-message in ChatMessage.mcpEvents
  instead of ephemeral component state. Events now survive across turns
  and render inline below each assistant response via MCPEventsDisplay.
- Remove stale mcpEvents useState and ephemeral panel at bottom of chat.

* fix(chat-ui): address greptile review feedback (greploop iteration 2)

- Fix stale session on edit/retry: derive previousResponseId as null when
  historyOverride is set so edit/retry always starts a fresh Responses API
  session rather than chaining off a now-invalid prior session
- Fix unsafe MCPEvent cast: import MCPEvent directly from MCPEventsDisplay
  into types.ts and type ChatMessage.mcpEvents as MCPEvent[], eliminating
  the bare 'as MCPEvent[]' cast in ChatMessages.tsx

* fix(chat-ui): fix MCPEvent layering, batch localStorage writes, module-level test imports

- Move MCPEvent interface definition into chat/types.ts (single source of truth)
- MCPEventsDisplay.tsx now imports MCPEvent from types.ts instead of defining it locally
- Batch MCP event localStorage writes: accumulate during stream, persist once in finally
- Move test imports to module level per PEP 8 convention

* fix(chat-ui): fix MCPEvent import path and rename truncateFromMessage

- responses_api.tsx now imports MCPEvent directly from chat/types (not via MCPEventsDisplay re-export)
- Remove the now-unnecessary MCPEvent re-export from MCPEventsDisplay.tsx
- Rename truncateAfterMessage → truncateFromMessage: the function removes the target message and all subsequent ones (not just what comes after), so the new name accurately describes the behavior

* fix(responses-api): fix whitespace token filter and MCP server URL construction

- Drop the delta.trim() whitespace filter that was silently swallowing spaces
  and newlines during streaming, causing words to concatenate and paragraphs
  to collapse. Only skip truly empty strings (delta.length > 0).
- Use proxyBaseUrl for MCP server_url construction instead of the hardcoded
  relative path "litellm_proxy/mcp", so non-root deployments route correctly.

* fix(responses-api): use unique server_label per MCP server to prevent tool routing collisions

* fix(chat-ui): move MCPEvent to shared mcp_tools/types, skip partial events on abort

- Move MCPEvent interface to mcp_tools/types.tsx (shared with MCPServer/MCPTool),
  eliminating the playground→chat cross-module dependency. chat/types.ts and
  both playground components now import from mcp_tools/types.
- Only persist accumulated MCP events when the stream completes cleanly; aborted
  or errored turns drop partial events to avoid showing incomplete tool calls.

* fix(responses-api): use server_name for MCP URL routing, fix test path

- Use server_name (not alias) as the URL path segment for MCP server_url;
  alias is a display name that may differ from the registered proxy route.
  URL-encode the path to handle names with spaces/special characters.
- Fix sys.path.insert in tests to use __file__-relative path so tests pass
  regardless of which directory pytest is invoked from.

* fix(chat-ui): fix stale session after failed edit, clean MCP event persistence, unique server_label

- Eagerly call setResponsesSessionId(null) when historyOverride is set so a
  failed/aborted edit does not leave a stale session contaminating the next turn
- Replace abort-signal check with streamCompletedCleanly flag to correctly skip
  MCP event persistence on both abort and non-abort errors (network/API failures)
- Use server_name (unique) as server_label instead of alias to prevent silent
  tool-routing failures when two MCP servers share the same display name
2026-03-10 18:53:54 -07:00
Cesar Garcia
f51a5b9c3e
Update tests/test_litellm/test_model_cost_aliases.py
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-03-10 22:53:02 -03:00
Chesars
18a48d0a0b fix(tests): add missing assertions for alias conflict warning and aliases key removal 2026-03-10 22:46:21 -03:00
Chesars
b00e507574 fix: address Greptile review feedback
- Clean up aliases key from entries with empty aliases list
- Strengthen test assertion for alias conflict warning
2026-03-10 22:42:18 -03:00
Chesars
c0dbff21a6 feat: add model cost aliases expansion support 2026-03-10 22:42:18 -03:00
Cesar Garcia
3d2df7e8b5
Revert "feat: add model_cost aliases expansion support" 2026-03-10 22:39:19 -03:00
Chesars
a2781f0db3 fix(perplexity): remove models from shared TypedDict and restore error handling
- Remove Perplexity-specific `models` field from ResponsesAPIOptionalRequestParams
  TypedDict to avoid polluting the shared OpenAI type. The param is still passed
  through via get_supported_openai_params + map_openai_params at runtime.
- Add transform_response_api_response override to catch Perplexity's HTTP 200
  with status:"failed" and raise BaseLLMException instead of silently succeeding.
2026-03-10 19:51:23 -03:00
Chesars
e0927d1bac fix(tests): update Perplexity tests for simplified config
- Update test_all_supported_params_declared to match the simplified
  8-param list (was 24 params from old 410-line implementation)
- Replace test_cost_transformation tests: use ResponseAPIUsage
  validator directly instead of removed _transform_usage method
  (cost parsing moved to generic parse_cost validator)
2026-03-10 19:29:49 -03:00
Cesar Garcia
5f5e47fc24
Merge pull request #22138 from Chesars/fix/unify-finish-reason-mapping
fix(completion): unify finish_reason mapping to OpenAI-compatible values
2026-03-10 19:29:04 -03:00
Chesars
e223b29d31 fix(responses): add models to TypedDict and fix test state corruption
- Add 'models' field to ResponsesAPIOptionalRequestParams TypedDict so
  the Perplexity fallback chain param is not silently filtered out by
  get_requested_response_api_optional_param(). Verified with curl that
  Perplexity's models param works (tries models in order until one
  succeeds).
- Fix test_python_class_takes_priority_over_json: save and restore the
  original JSONProviderRegistry entry instead of deleting it, preventing
  state corruption for subsequent tests.
2026-03-10 19:19:07 -03:00
Chesars
d501c33a9d feat(types): expose native_finish_reason in provider_specific_fields
When a provider's finish_reason is mapped to a different OpenAI-compatible
value (e.g. "MALFORMED_FUNCTION_CALL" → "stop"), the original value is now
preserved in choices[].provider_specific_fields["native_finish_reason"].

This allows agent loops to distinguish between different stop conditions
without breaking the unified OpenAI-compatible finish_reason mapping.

Also returns a defensive copy from get_finish_reason_mapping() to prevent
accidental mutation of the global _FINISH_REASON_MAP.
2026-03-10 18:43:51 -03:00
Cesar Garcia
6bca746d23
Merge pull request #21601 from Chesars/feat/model-cost-aliases
feat: add model_cost aliases expansion support
2026-03-10 18:07:23 -03:00
Cesar Garcia
e4fddb9f24
Merge pull request #23093 from MaxwellCalkin/fix/thinking-blocks-interleave-23047
fix: preserve thinking block order with multiple web searches
2026-03-10 18:06:45 -03:00
Cesar Garcia
b905e1493b
Merge pull request #23201 from Chesars/claude/brave-ritchie
feat(images): support input_fidelity parameter for image edit API
2026-03-10 18:05:02 -03:00
Cesar Garcia
d34999900c
Merge pull request #23265 from Chesars/fix/vertex-gemini2-tool-schema-minimal-transform
fix(vertex): skip schema transforms for Gemini 2.0+ tool parameters
2026-03-10 18:04:46 -03:00
Ishaan Jaff
373e5e316b
feat(mcp): BYOM — non-admin MCP server submission + admin review workflow (#23205)
* feat(mcp): add BYOM (Bring Your Own MCPs) submission + admin review workflow

Non-admins can now submit MCP servers for review via POST /v1/mcp/server/register.
Admins get a Submissions tab in the UI to approve or reject pending servers.
Approved servers enter the active runtime; rejected ones stay out with notes.

- DB: add approval_status, submitted_by, submitted_at, reviewed_at, review_notes
  to LiteLLM_MCPServerTable with migration
- Backend: new endpoints register, submissions, approve, reject
- reload_servers_from_database now only loads approval_status=active servers
- UI: Submissions tab with stat cards, card list, confirm dialogs; non-admin
  "Submit MCP Server" button wired to /register endpoint
- Fix get_mcp_submissions to filter by submitted_at IS NOT NULL (not submitted_by,
  which can be null for team-scoped keys without an associated user)

* feat(mcp): rename nav item to Team MCPs + add New badge

* fix(mcp): revert nav label, rename Submissions tab to Team MCPs + New badge

* feat(mcp): add MCP Standards — required fields config + CI-style checks on submissions

Adds a "Standards" tab (admin-only) to MCP Servers where admins define which
server fields are required for a submission to pass. Each submission card in
Team MCPs then shows a green ✓ or red ✗ for each required field, with a
summary "N/M checks" badge in the header — like GitHub CI status rows.

Also adds a `source_url` field (GitHub / Source URL) to the MCP server schema
so non-admins can link to the source repo when submitting a server.

- schema.prisma: add `source_url String?` to LiteLLM_MCPServerTable
- migration: 20260309000001_add_mcp_source_url
- _types.py: source_url on NewMCPServerRequest, UpdateMCPServerRequest, LiteLLM_MCPServerTable
- types.tsx: source_url on MCPServer interface
- create_mcp_server.tsx: GitHub/Source URL form field
- MCPStandardsSettings.tsx: new — toggle which fields are required (stored in general settings as mcp_required_fields)
- mcp_servers.tsx: Standards tab (admin-only)
- MCPSubmissionsTab.tsx: load required fields + CI-style check pills on each card

* refactor(mcp): move submission rules into Team MCPs tab, grouped free-form UI

Folds the Standards tab into Team MCPs. Submission Rules panel now lives at the
top of the Team MCPs tab — collapsible, shows active rules as chips when closed,
expands to a grouped checkbox editor (Documentation / Source / Connection /
Security). Removes the separate Standards tab from the nav.

MCPStandardsSettings.tsx is now constants-only (FIELD_GROUPS, MCP_REQUIRED_FIELD_DEFS,
SETTINGS_KEY) — the UI lives in MCPSubmissionsTab.

* feat(mcp): add mcp_required_fields to ConfigGeneralSettings + config/list endpoint

Registers mcp_required_fields as a proper general_settings field so the UI
can read/write it via /config/list and /config/field/update without the
"Invalid field" error. Also fixes a pre-existing pyright None-check issue
in _sync_ui_settings_to_general_settings.

* ui(mcp): GitHub-style PR checks panel on submission cards

* ui: rename Team MCPs -> Submitted Tools, Team Guardrails -> Submitted Guardrails

* address greptile review feedback (greploop iteration 1)

* fix: inline import, add approval workflow tests, rename Submitted MCPs

* fix(mcp): allow re-approval of rejected MCP server submissions

* fix(mcp): evict rejected servers from runtime; enforce mcp_required_fields on /register

* fix(mcp): sort submissions newest-first; force active status on admin-created servers

* fix(mcp): add missing mock in test, show Approve for rejected, clear submission metadata, drop spurious Content-Type

* fix(mcp/ui): show Reject for active servers; show submit form to non-admins with team-key note

* fix(mcp): conditional reload on reject; view-only admin for submissions; block admin from /register

* fix(mcp): match auth_type required-field validation to UI compliance check (reject 'none')

* fix(mcp): block view-only admin from /register; log settings failure; warn on active server reject

* fix(mcp): allow view-only admin to use /register; add _validate_mcp_required_fields tests

* fix(mcp): validate field names in mcp_required_fields; surface backend error in submit UI

* fix(mcp): fix falsy field check; add field-name validation; add take limit; document server-managed fields; close dialog on error
2026-03-10 13:58:59 -07:00
Chesars
926a0df9b0 Merge main into feat/openai-like-responses-api
Resolve conflict in perplexity/responses/transformation.py by keeping
the simplified ~50 line version (PR's goal) instead of main's ~410 line
version. Added supports_native_websocket() -> False from main.
2026-03-10 17:36:32 -03:00
Chesars
2315d4b73c fix: resolve merge conflicts with staging branch
Keep unified _FINISH_REASON_MAP dict approach, discard upstream's
inconsistent _VALID_OPENAI_FINISH_REASONS frozenset that mapped to
values not in the OpenAIChatCompletionFinishReason Literal.
2026-03-10 17:27:57 -03:00
stevejaker
2341a38c08
fix(snowflake): transform tool_choice string to object format (#23268)
* fix(snowflake): transform tool_choice string to object format

Snowflake's Cortex API requires tool_choice to be an object, not a string.
For example, {"type": "auto"} instead of "auto".

Ref: https://docs.snowflake.com/en/developer-guide/snowflake-rest-api/reference/cortex-inference#post--api-v2-cortex-inference-complete-req-body-schema

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 01:41:24 +05:30
Jason Roberts
70fca22f68
feat(panw-prisma-airs): PANW Prisma AIRS guardrail with apply_guardrail support (#22999)
* feat(panw-prisma-airs): PANW Prisma AIRS guardrail with apply_guardrail support

* fix(panw): honor masking and fallback behavior

* fix(panw): clean up apply_guardrail MCP metadata handling

* fix(panw): clean up apply_guardrail MCP metadata handling

* fix(panw): harden apply_guardrail edge cases

* fix(panw): apply MCP masked data on allow responses

* fix(panw): scan latest developer message in anthropic mode

* fix(panw): restore legacy user-only pre-call scanning

* fix(panw): record apply_guardrail in applied guardrails header

* fix(panw): scan developer role in legacy pre-call path

* fix(panw): harden SSE parsing and narrow MCP name fallback

* fix(panw): harden streaming attr lookup and document dual scans

* fix(panw): fail closed on permanent 4xx and cover streaming observability
2026-03-10 12:31:31 -07:00
Chesars
6469de9516 fix: address Greptile review feedback
- Clean up aliases key from entries with empty aliases list
- Strengthen test assertion for alias conflict warning
2026-03-10 16:09:49 -03:00
Chesars
7ccb14cab4 feat: add model cost aliases expansion support 2026-03-10 15:57:23 -03:00
michelligabriele
ffc89e4ef6
fix(mcp): add AWS SigV4 auth for Bedrock AgentCore MCP servers (#22782)
* fix(mcp): add AWS SigV4 auth for Bedrock AgentCore MCP servers

Add aws_sigv4 auth type to MCP client via httpx.Auth subclass that
signs each request with SigV4 using botocore. Enables mcp_servers
config to connect to AgentCore-hosted MCP servers.

* docs(mcp): add AWS SigV4 auth documentation for Bedrock AgentCore

Add dedicated docs page for configuring MCP servers with AWS SigV4
authentication, update MCP overview with aws_sigv4 auth type and
config example, and link from Bedrock AgentCore provider docs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mcp): address Greptile review — requires_request_body, full header signing, health check

- Add requires_request_body = True to MCPSigV4Auth so httpx buffers the
  request body before calling auth_flow (prevents empty body hash for
  streaming requests)
- Pass all request headers to AWSRequest for canonical SigV4 signing
  instead of only Content-Type
- Exclude aws_sigv4 from health check skip logic since it has its own
  credential fields (not authentication_token)
- Fix docs: mark aws_access_key_id/aws_secret_access_key as optional
  (falls back to boto3 credential chain)
- Add test for requires_request_body flag

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Krish Dholakia <krrishdholakia@gmail.com>
2026-03-10 11:11:20 -07:00
Ishaan Jaff
9543d785b5
fix(mcp): don't auto-detect M2M OAuth from field presence (#23187)
* fix(mcp): require explicit opt-in for OAuth2 M2M client_credentials flow

Auto-detecting M2M from client_id+secret+token_url presence broke existing
interactive OAuth setups (e.g. GitHub Enterprise). Add oauth2_flow field and
default has_client_credentials to False — M2M must be explicitly opted into
with oauth2_flow: client_credentials.

* test(mcp): add regression tests for oauth2_flow M2M opt-in behavior
2026-03-10 10:59:49 -07:00
mubashir1osmani
26febf11a7
Merge pull request #23202 from mubashir1osmani/fix/tag-usage-cost-panel-zero
fix: tag usage cost panel zero
2026-03-10 13:57:22 -04:00
mubashir1osmani
88d0f9d834 added comments 2026-03-10 13:56:15 -04:00
mubashir1osmani
6a59ec5ddf
fix: anthropic prompt caching returns a string instead of an int
fix: anthropic prompt caching returns a string instead of an int
2026-03-10 13:51:17 -04:00
yuneng-jiang
b02ecc7807
Merge pull request #23260 from milan-berri/feat/mcp-token-auth-support
feat(mcp): add token authentication support for MCP servers
2026-03-10 09:57:21 -07:00
Milan
4c9220bdec feat(mcp): add token authentication support for MCP servers
- Add 'token' to MCPAuth enum for custom token auth format
- Implement token auth in MCP client (_get_auth_headers)
- Add token auth support for OpenAPI-based MCP tools
- Add comprehensive unit tests to existing test_mcp_client.py
- Fixes issue where MCP servers expecting 'Authorization: token <value>' header could not connect
2026-03-10 18:33:08 +02:00
milan-berri
336fb0cfeb
fix(security): strip secret_fields from guardrail logging response (#23162)
When guardrails return the full data dict (e.g. guardrails_ai), the
guardrail response logged to spend logs and OTEL traces could contain
data["secret_fields"].raw_headers with plaintext Authorization headers.

This adds a pop("secret_fields") in the guardrail logging path,
matching the existing pattern used by Langfuse and Arize integrations.

Tested: Verified fix removes secret_fields/raw_headers/authorization
from both /spend/logs/ui responses and OTEL trace span attributes.
2026-03-10 08:58:18 -07:00
xykong
810de556bd
fix(streaming): map unknown finish_reason values to finish_reason_unspecified to prevent ValidationError in stream_chunk_builder (#22673)
* fix(streaming): map unknown finish_reason values to finish_reason_unspecified

Some LLM providers return non-standard finish_reason values that are not
in the OpenAIChatCompletionFinishReason Literal (e.g. ZhipuAI/GLM returns
'network_error' when a streaming error occurs mid-response).

Previously map_finish_reason() fell through with return finish_reason,
passing the unknown value directly to Choices.__init__() which calls
Pydantic validation. This caused a ValidationError that was caught by
stream_chunk_builder() and re-raised as the misleading:
  litellm.APIError: Error building chunks for logging/streaming usage calculation

Fix: after all known provider-specific mappings, check if the value is in
the valid set (stop, length, tool_calls, content_filter, function_call,
guardrail_intervened, eos, finish_reason_unspecified, malformed_function_call).
Any value not in this set is mapped to 'finish_reason_unspecified' instead
of being returned as-is.

This is consistent with how other unknown stop reasons (e.g. Vertex AI's
FINISH_REASON_UNSPECIFIED) are already handled.

* refactor: use get_args(OpenAIChatCompletionFinishReason) for valid set

Per code review feedback: replace the hardcoded _valid_finish_reasons set
with a module-level frozenset derived dynamically from the source-of-truth
Literal type via typing.get_args(). This ensures the valid-reason check
stays in sync automatically when new finish reasons are added to the Literal,
and avoids recreating the set on every streaming chunk call.

* test(map_finish_reason): add unit tests and warning log for unknown finish reasons

- Add TestMapFinishReason class in test_core_helpers.py covering:
  - All known OpenAI-native values pass through unchanged (parametrized)
  - Provider-specific mappings: Anthropic, Cohere, Vertex AI
  - Unknown/provider-specific values map to 'finish_reason_unspecified'
  - Regression test for ZhipuAI/GLM-5 'network_error' case
- Add verbose_logger.warning() in map_finish_reason() when an unknown
  finish_reason is encountered, so operators can track which providers
  return non-standard values
2026-03-10 21:25:24 +05:30
Chesars
0680a97409 fix: handle list-content messages in thinking block interleaving
When assistant content is already a list containing thinking blocks
inline (not str/None), SEQUENTIAL MODE was still prepending all
thinking_blocks from provider_specific_fields, causing duplication
and breaking Anthropic's position-dependent signature verification.

Now detects if the content list already has thinking blocks and skips
the extend(thinking_blocks) to preserve the original interleaved order.

Addresses the correctness gap identified by Greptile review where
list-content messages bypass INTERLEAVED MODE.

Fixes: https://github.com/BerriAI/litellm/issues/23047
2026-03-10 12:48:30 -03:00
Harshit Jain
424a96580b
Merge pull request #22627 from BerriAI/litellm_presidio_antropic_edge_case
fix: presidio edge case with antropic handle on pii token leak
2026-03-10 21:16:56 +05:30
Harshit Jain
e1c2c36f67
Merge pull request #23259 from BerriAI/litellm_claude_missing_reqs
fix: claude code req traces on langfuse
2026-03-10 21:15:36 +05:30
Harshit Jain
fdb0a46242
Merge pull request #23209 from BerriAI/litellm_silent_metrics
feat: record silent metrics
2026-03-10 21:14:09 +05:30
Chesars
a9c3095cc5 fix(vertex): skip harmful schema transforms for Gemini 2.0+ tool parameters
Gemini 2.0+ natively accepts JSON Schema in tool parameters, including
bare {} (TYPE_UNSPECIFIED), anyOf with null, and lowercase types. The
existing _build_vertex_schema pipeline was coercing {} to {"type": "object"},
breaking JsonValue/Any field semantics (issue #22391).

Add _build_vertex_schema_for_gemini_2() that only resolves $ref (which
Gemini doesn't support in tools) and filters unsupported fields. Use it
for Gemini 2.0+ models, keeping the full transform for Gemini 1.5.
2026-03-10 11:15:27 -03:00
Chesars
a6cb510703 merge: resolve conflicts between main and litellm_oss_staging_03_04_2026
Resolved 14 file conflicts:
- image_edits.md: combined OpenRouter + Black Forest Labs providers
- utils.py: kept staging's message-level cache_control check
- networking.tsx: kept export on 4 tool interfaces
- tool_management_endpoints.py: kept ToolOutputPolicy import
- Accepted main's version for: schema.prisma, a2a_protocol, mcp_server,
  _types.py, auth_checks.py, db_spend_update_writer, endpoints.py,
  spend_tracking_utils, a2a_endpoints, model_prices backup
2026-03-10 10:45:04 -03:00