Commit graph

36177 commits

Author SHA1 Message Date
Darien Kindlund
6cb956fa7f fix: catch exceptions in pass-through streaming logging handler (#21636)
_route_streaming_logging_to_handler is called via asyncio.create_task()
after streaming chunks are already delivered to the client. Any
unhandled exception in this logging task propagates as an unhandled
asyncio task exception, polluting error logs.

Wraps the method body in try/except to log errors without propagating.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-02 19:21:10 +05:30
Darien Kindlund
6bd2143a3d fix: guard against str response from Azure before calling model_dump() (#21634)
The OpenAI SDK raw_response.parse() can return a plain str instead
of a Pydantic model when Azure returns a non-JSON content type (e.g.,
HTML error page, proxy error). Calling .model_dump() on the str then
raises AttributeError.

Adds isinstance(response, str) checks before all 4 model_dump() call
sites in the Azure chat completion and embedding paths.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-02 19:21:10 +05:30
Sameer Kankute
acf324279c
Merge pull request #22550 from BerriAI/litellm_vertex-video-token-tracking
feat(vertex-ai): add VIDEO modality support in token usage tracking
2026-03-02 18:51:19 +05:30
Sameer Kankute
d3d8d72b5f
Merge pull request #22546 from BerriAI/litellm_bedrock_region_in_model_path
fix(bedrock): extract region and model ID from bedrock/{region}/{model} path format
2026-03-02 18:50:30 +05:30
Sameer Kankute
cc650f4865 fix(responses): add in-memory session tracking to ManagedResponsesWebSocketHandler for previous_response_id
Spend logs are written asynchronously in batches, so a DB lookup for a
just-completed response's spend log races and returns zero rows. Replace the
DB-only fallback with an in-memory session store (_session_history) that is
populated after each response.completed event and consulted at the start of
the next response.create. This makes same-connection multi-turn reliable
without any timing dependency on the DB write queue.

Made-with: Cursor
2026-03-02 18:30:39 +05:30
Sameer Kankute
c1136348f0 revert pyrightconfig 2026-03-02 17:27:24 +05:30
Sameer Kankute
82f5055d89 test(responses): add end-to-end test for responses API WebSocket mode
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 17:24:39 +05:30
Sameer Kankute
76ddfa184c feat(init): export _aresponses_websocket from litellm package
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 17:24:27 +05:30
Sameer Kankute
0921e26b8c feat(router): register _aresponses_websocket in Router factory functions
Also suppress pre-existing pyright type error on model_response.close() call
which is guarded by hasattr at runtime.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 17:24:12 +05:30
Sameer Kankute
512a438935 feat(proxy): add WebSocket endpoint for responses API and route_llm_request support
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 17:22:44 +05:30
Sameer Kankute
eeb2d28621 feat(proxy): add _aresponses_websocket to common_request_processing route_type Literal
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 17:22:00 +05:30
Sameer Kankute
39748fd4a3 feat(responses): add _aresponses_websocket function and HTTP handler support for WebSocket mode
Also fix pyrightconfig.json to use the conda venv for type checking, and remove
redundant inline import of ResponsesAPIRequestUtils that was confusing pyright.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 17:21:47 +05:30
Sameer Kankute
19ce26501b feat(responses): add WebSocket streaming iterator for responses API
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 16:55:27 +05:30
Sameer Kankute
538f11bdfa feat(types): add _aresponses_websocket CallType and video_tokens to PromptTokensDetailsWrapper
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 16:53:53 +05:30
David Steele
a14ef27009
test: fix copy-paste print message in multi-tool-call test 2026-03-02 09:08:03 +00:00
David Steele
a3cdf6c895
fix(streaming): don't emit finish_reason on output_item.done for function_call
The response.output_item.done handler for function_call type was emitting
finish_reason='tool_calls' and a duplicate tool_call delta. This caused
premature stream termination after the first tool call in multi-tool
scenarios — downstream wrappers (e.g. AnthropicStreamWrapper) would close
the stream before subsequent tool calls arrived.

The response.completed event already inspects the response output list and
emits finish_reason='tool_calls' when function_call items are present, so
output_item.done does not need to (and must not) do so.

This mirrors the existing fix for message-type output_item.done (#17246).

Updated test_function_call_done_emits_is_finished (renamed) to assert
finish_reason=None and no duplicate delta. Updated test_text_plus_tool_calls_sequence
to match. Added test_multi_tool_call_stream_no_premature_finish which exercises
a synthetic 2-tool-call stream and verifies no premature termination.
2026-03-02 08:59:59 +00:00
openhands
58cd6f6899 test: fix misleading precedence test per review feedback
Renamed test_build_custom_pricing_entry_kwargs_take_precedence_over_model_info
to test_build_custom_pricing_entry_setdefault_does_not_override_existing.

The original test claimed to verify kwargs precedence over model_info but
had no overlapping keys between the two sources. CustomPricingLiteLLMParams
fields and the model_info metadata keys (mode, supports_prompt_caching,
max_tokens) do not currently overlap. Updated the test to verify that
model_info fields are correctly merged, and added an explicit setdefault
assertion demonstrating that pre-existing keys would not be overwritten.

Co-authored-by: openhands <openhands@all-hands.dev>
2026-03-02 08:31:33 +00:00
openhands
5655cb87fc fix: pass all custom pricing fields to register_model in completion() and embedding()
Previously, register_model() was called with only input_cost_per_token,
output_cost_per_token, and litellm_provider. This dropped ~40+ other
pricing fields from CustomPricingLiteLLMParams (cache_read_input_token_cost,
cache_creation_input_token_cost, output_cost_per_reasoning_token, etc.)
as well as model_info metadata (mode, supports_prompt_caching, max_tokens).

For DB-sourced custom-priced models, the first request after a pod restart
would register a partial entry in litellm.model_cost, causing cost
calculations to miss cache token discounts and other extended pricing
until the entry was later enriched by deployment_callback_on_success
mutating the lru_cache.

Changes:
- Add _build_custom_pricing_entry() helper that iterates over all
  CustomPricingLiteLLMParams.model_fields and merges model_info metadata
- Replace hardcoded 3-field dicts in both completion() and embedding()
  with the new helper
- Add 7 tests covering field collection, model_info merging, precedence,
  None skipping, and end-to-end register_model behavior

Co-authored-by: openhands <openhands@all-hands.dev>
2026-03-02 08:11:07 +00:00
Sameer Kankute
8b9ffdd93f feat(vertex-ai): add VIDEO modality support in token usage tracking
- Parse VIDEO modality in promptTokensDetails → prompt_tokens_details.video_tokens
- Parse VIDEO modality in candidatesTokensDetails → completion_tokens_details.video_tokens
- Parse VIDEO modality in cacheTokensDetails and subtract from prompt video tokens
- Add video_tokens field to PromptTokensDetailsWrapper and CompletionTokensDetailsWrapper
- Fix implicit caching text-token fallback to not fire when cacheTokensDetails is present
- Add 4 unit tests covering: prompt video tokens, response video tokens,
  auto-calculated text fallback with video, and explicit video cache subtraction

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 12:47:36 +05:30
Sameer Kankute
f7b594e7f8 test(bedrock): add unit tests for region extraction from bedrock/{region}/{model} path
Covers:
- Region + modelId correctly extracted for ap-northeast-1, us-east-1, us-west-2
- No region in path leaves modelId and optional_params unchanged
- Cross-region inference prefixes (us., eu., ap.) are not treated as region segments
- Explicitly set aws_region_name is not overridden by region in model path

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 11:06:27 +05:30
Sameer Kankute
5864317d92 fix(bedrock): extract region and model ID from bedrock/{region}/{model} path format
When a user passes model="bedrock/ap-northeast-1/moonshotai.kimi-k2.5", get_llm_provider
strips the "bedrock/" prefix and passes "ap-northeast-1/moonshotai.kimi-k2.5" to the
converse handler. Two bugs occurred:

1. modelId was encoded as "ap-northeast-1%2Fmoonshotai.kimi-k2.5" (region included),
   which AWS rejects as "not a valid model identifier"
2. The region ap-northeast-1 was never extracted, so the request went to the wrong
   default region instead

Fix: after stripping routing prefixes in converse_handler.py completion(), check if the
remaining path starts with a known AWS region and strip it from modelId, injecting it
into optional_params so _get_aws_region_name picks it up.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 10:32:45 +05:30
Sameer Kankute
b518c24ff4
Merge pull request #22497 from giulio-leone/fix/featherless-ai-api-key
fix(featherless_ai): use correct FEATHERLESS_AI_API_KEY env var name
2026-03-02 08:58:32 +05:30
giulio-leone
a8adbee6c9 fix(tests): use monkeypatch for env var isolation in featherless tests
Replace patch.dict with pytest monkeypatch for idiomatic env var
isolation. Remove unused typing and unittest.mock imports (ruff F401).

Refs: #22497
2026-03-01 23:46:15 +01:00
Julio Quinteros Pro
40f1cfdb7b
Merge pull request #22526 from BerriAI/fix/router-plr0915-noqa
Fix PLR0915 lint error in _completion_streaming_iterator
2026-03-01 18:02:33 -03:00
Julio Quinteros Pro
fc68609b42
Merge pull request #22525 from BerriAI/fix/observatory-tunnel-retry
Fix observatory tunnel DNS flakiness and PLR0915 lint
2026-03-01 18:01:37 -03:00
Julio Quinteros Pro
262172d7e7 Extract _combine_fallback_usage to deduplicate streaming iterator logic
Extract the repeated usage-combining block from both
_completion_streaming_iterator and _acompletion_streaming_iterator into a
shared static helper method _combine_fallback_usage. This brings both
functions under the PLR0915 50-statement limit, removing the noqa
suppressions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 17:57:47 -03:00
Julio Quinteros Pro
3faa864713 Fix PLR0915 lint error in _completion_streaming_iterator
Add `# noqa: PLR0915` suppression to match the async twin
`_acompletion_streaming_iterator` which already carries the same
suppression. The function's complexity is inherent (nested class,
generator with fallback logic, cleanup code).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 17:54:20 -03:00
Julio Quinteros Pro
2f6298d00f Fix observatory tunnel flaky DNS and suppress PLR0915 in router
The observatory test workflow failed because the "Verify tunnel
connectivity" step used a single curl with no retries. Cloudflare quick
tunnels need time for DNS propagation, and the first lookup can return
NXDOMAIN (curl exit 6). Replace with a retry loop (10 attempts, 5s
apart) matching the pattern already used in the health check step.

Also add `# noqa: PLR0915` to `_completion_streaming_iterator` in
router.py, matching the suppression already on its async twin.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 17:45:49 -03:00
Julio Quinteros Pro
00affc01b5
Merge pull request #22523 from BerriAI/fix/lint-undefined-kwargs
Fix undefined kwargs in InFlightRequestsMiddleware
2026-03-01 17:27:38 -03:00
Julio Quinteros Pro
22140b0653 Fix undefined kwargs in InFlightRequestsMiddleware
kwargs dict was used but never initialized, causing F821
(undefined name) lint errors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 17:23:37 -03:00
Julio Quinteros Pro
7f1ca956be
Merge pull request #22518 from BerriAI/fix/observatory-checkout
Fix observatory workflow checkout failing on commit hash
2026-03-01 17:09:25 -03:00
Julio Quinteros Pro
cc0b1323d7 Fix observatory checkout failing on commit hash ref
actions/checkout treats short commit hashes as branch names, causing
fetch failures. The checkout only needs the config file from the
repo, so use the default branch instead of a specific ref.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 17:05:49 -03:00
Julio Quinteros Pro
5a35dfc258
Merge pull request #22517 from BerriAI/fix/test-linting-secrets-context
Fix invalid secrets context in test-linting workflow
2026-03-01 16:58:19 -03:00
Julio Quinteros Pro
b40b1e6a4b Fix invalid secrets context in test-linting workflow
The secrets context is not available in step-level if: conditions,
causing the workflow file to fail validation. Move the conditional
check into the shell script instead.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 16:54:53 -03:00
Julio Quinteros Pro
ac6e1d9fd1
Merge pull request #22508 from BerriAI/observatory-ci-integration
Add observatory test workflow for RC/stable releases
2026-03-01 16:43:00 -03:00
Julio Quinteros Pro
369edb2afb Move all secrets to env blocks instead of direct interpolation
Pass AZURE_API_KEY, AZURE_API_BASE, OBSERVATORY_URL,
OBSERVATORY_API_KEY, and REQUEST_ID through step-level env
blocks so they are never interpolated directly into shell scripts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 16:34:10 -03:00
Julio Quinteros Pro
a24ba226ba Validate tag input and add explicit cleanup step
- Validate inputs.tag matches vX.Y.Z format to prevent script
  injection via workflow_dispatch
- Pass tag via env var instead of direct interpolation in shell
- Add cleanup step to kill cloudflared and remove docker container

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 16:19:30 -03:00
Julio Quinteros Pro
a2946e2cc8 Add job timeout and use jq for safe JSON construction
- Add timeout-minutes: 30 to prevent runaway jobs
- Build /run-test payload with jq --arg to safely escape
  TUNNEL_URL and LITELLM_MASTER_KEY values

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:30:09 -03:00
Julio Quinteros Pro
7a46aaff2b Pin cloudflared to v2025.2.1 for reproducible builds
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:30:09 -03:00
Julio Quinteros Pro
58264aadb7 Validate request_id before polling
Fail early if request_id is missing or null from the /run-test
response instead of polling /run-status/null for 15 minutes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:30:09 -03:00
Julio Quinteros Pro
b4e0c4db07 Use temp file for JSON result passing between steps
Avoids shell quoting issues with single quotes in JSON and
multi-line output truncation when using GITHUB_OUTPUT.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:30:09 -03:00
Julio Quinteros Pro
1fdaa1588d Address PR review comments on observatory workflow
- Add permissions block (contents: read) per GitHub security scan
- Poll /run-status/{request_id} instead of global /queue-status
  to avoid race conditions with concurrent test runs
- Add result verification step that fails the workflow if tests
  did not pass or the run errored
- Fix auth header to use X-LiteLLM-Observatory-API-Key

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:30:09 -03:00
Julio Quinteros Pro
d7dd7ef33b Add observatory test workflow for RC/stable releases
- New reusable workflow that spins up a LiteLLM container from the
  release image, exposes it via cloudflared tunnel, and triggers
  test runs on the Railway-hosted observatory
- Integrates into ghcr_deploy.yml for RC and stable releases
- Can also be triggered manually via workflow_dispatch
- Add placeholder litellm_config.yaml for observatory test models

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:30:09 -03:00
giulio-leone
7934810e21 fix(tests): isolate env vars in featherless AI tests
Use clear=True with patch.dict to prevent pre-set FEATHERLESS_*
env vars from leaking into tests and causing false results.

Refs: #22497
2026-03-01 17:26:16 +01:00
giulio-leone
7d21770d99 fix(featherless_ai): use correct FEATHERLESS_AI_API_KEY env var name
The transformation.py file was using FEATHERLESS_API_KEY (missing _AI_)
while the rest of the codebase (get_llm_provider_logic.py, utils.py)
correctly uses FEATHERLESS_AI_API_KEY. This caused 401 auth errors when
the user set FEATHERLESS_AI_API_KEY as documented.

Now checks FEATHERLESS_AI_API_KEY first (canonical name) with fallback
to FEATHERLESS_API_KEY (legacy compatibility). Same fix applied to
FEATHERLESS_AI_API_BASE.

Refs: #22490
2026-03-01 17:11:58 +01:00
Harshit28j
28a48acce6 fix: add @log_db_metrics and move jwt mapping before auth_builder
- Add @log_db_metrics decorator to get_jwt_key_mapping_object for
  consistent DB latency/error tracking with other helpers
- Move virtual key mapping lookup before auth_builder() to avoid
  unnecessary team/user/org DB queries when mapping resolves
- JWT is decoded early; auth_builder only runs when no mapping found

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 16:46:49 +05:30
Harshit28j
911ba14e45 fix: address remaining greptile feedback for jwt key mapping
- Persist description field on create (was silently dropped)
- Remove phantom key_alias from JWTKeyMappingResponse (not in schema)
- Populate created_by/updated_by audit fields from authenticated user
- Pass actual jwt_valid_token in admin path instead of empty dict
- Restore hash_token on create and fix duplicate try block

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 14:28:50 +05:30
Harshit Jain
0e2dd4aac1
Update litellm/proxy/management_endpoints/jwt_key_mapping_endpoints.py
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-03-01 13:43:06 +05:30
Harshit28j
0f9d380874 fix: add pagination to jwt key mapping list endpoint
Add page/size query params with take/skip to prevent unbounded queries.
Returns paginated response with total_count, current_page, total_pages.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 13:28:06 +05:30
Harshit Jain
963390928d
Update litellm/proxy/management_endpoints/jwt_key_mapping_endpoints.py
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-03-01 13:08:40 +05:30