* ci: run the unit_selection.sh shard files on every event instead of only fork pull requests
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* ci: rename fork-flag to unit-flag now that it applies on every event
* test: move tests/test_litellm root and small trees into tests/unit
Pure renames, no content changes. Follow-up commits in this PR fix
references, merge the three files that already existed in tests/unit,
keep live-provider tests in tests/test_litellm and wire CI.
* test: carry tests/test_litellm conftest isolation into tests/unit
Callback lists, routing fallbacks, cached HTTP clients, logger state, AWS,
proxy-URL and keychain env, and session-end client cleanup now reset for
unit tests too. The environment isolation owns its MonkeyPatch so a test's
own monkeypatch is undone before the model-cost teardown runs.
* test: merge, split and prune the moved root and small-tree tests
Merge batches/test_batch_utils.py and the chat_completions and messages
dispatch tests into the files that already existed in tests/unit. Keep
the live Gemini interactions tests, the async image-fetch format test and
the OpenAI embedding scorer test in tests/test_litellm since they need
real network or keys. Put test_router.py under tests/unit/test_router so
the existing package no longer shadows it. Delete eight tests the audit
found superseded by stronger ones kept in this move.
* ci: run the moved root and small-tree tests under their legacy flags
Add the misc and responses-caching-types flags to unit_selection.sh and
CircleCI, extend enterprise-routing and mcp-integration, and point the
legacy GHA shards, Makefile, redis-compat workflow, merge smoke manifest
and change classifier at the new paths.
* test: make the new tests/unit directories packages
tests/unit/test_package_layout.py requires every directory to carry an
__init__.py, and without one the moved and retained
test_litellm_responses_bridge.py modules collide on import.
* test: scope the unit socket block to tests/unit in shared sessions
The GHA shards collect the legacy test-path and the unit selection in one
pytest session. The unit conftest's loopback-only block leaked into legacy
modules that reach the network at import. The legacy conftest now lifts the
restriction at collect and setup time, and the unit conftest re-applies it
when collecting its own modules.
* test: move tests/test_litellm/llms into tests/unit/llms
Rename-only. Moves the provider tests and the fine-tuning fixtures they
load, mirroring the old paths. Follow-up commits merge, split and wire them.
* test: merge, split and prune the moved llms tests
Merges the Databricks chat transformation tests into the existing unit
file, keeps the tests that need real keys or the network in
tests/test_litellm, deletes the audited tests a stronger unit test
already covers, and points imports at tests.unit.llms.
* ci: run the moved llms tests under their legacy flags
The Vertex AI and All Other Providers shards keep their legacy test-path
for the retained files and add the llm-vertex-ai and llm-other-providers
unit selections. CircleCI gets matching unit jobs.
* test: make the tests/unit/llms directories packages
Adds __init__.py to the moved dirs and drops the legacy ones whose
directories no longer hold tests.
* test: drop script runners and path hacks the llms split left dangling
The __main__ runners in the split openai_like files and the Databricks e2e
runner called tests that now live in the other half of the split or were
deleted. The retained legacy halves also no longer need sys.path edits.
* test: give the shard-script tests their own GITHUB_OUTPUT
They only passed where the runner set it. The CircleCI unit job's env
allowlist drops it, so the script's redirect failed there.
* test: point the router and module-deletion checks at tests/unit
router_code_coverage and code_qa_check_tests only searched tests/test_litellm,
so the moved router tests no longer counted. The two silent-experiment tests
the audit deleted were the only direct callers of those methods; they are
replaced with tests that assert the forwarded shadow request and the
recursion guard.
* test: move tests/test_litellm integrations and secret_managers into tests/unit
Rename-only. Mirrors the old paths, including the directory conftests
and the prompt and JSON fixtures. Follow-up commits prune and wire them.
* test: prune and repoint the moved integrations tests
Deletes the 7 audited tests a stronger test in the same tree already
covers, imports the TLS sink helpers from their new conftest path, and
restores os.environ after each integrations test. Some presets write
OTEL_EXPORTER_OTLP_HEADERS straight into os.environ, and without the
legacy tree's test ordering that header leaked into the AgentOps tests.
* ci: run the moved integrations tests under their legacy flag
The integrations GHA shard and a new CircleCI job run the integrations
unit selection. secret_managers joins the misc selection.
* docs: point integrations and secret_managers references at tests/unit
* test: make the moved integrations directories packages
* test: keep the Databricks manual e2e runner and fix the SageMaker Nova run path
The Databricks e2e file is a manual script whose main() calls the tests
that were pruned, so pruning them broke the documented run. It is back to
its main version. The SageMaker Nova docstring now points at the file's
real location in tests/local_testing.
* test: keep the job's UNIT_FLAG out of the shard-script tests
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* feat(spend): capture-rate check of LiteLLM spend against the OpenAI bill
* fix(spend): claim the alert lock after the check, NaN gauge on no rate, 180-day range cap, live settings, OpenAI adapter under llms
* fix(spend): chart the capture-rate gauge in the all-metrics dashboard and clear it when the check is removed
* fix(prometheus): record the capture-rate gauge when api_provider is an excluded label
---------
Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
* feat(cost): warn and count $0 cost on billable requests
A request that carries usage but prices to $0 on a model whose pricing
entry has a non-zero rate now logs one warning naming the model, the
pricing entry, and the missing rate, and increments
litellm_zero_cost_requests_total{requested_model, model, model_id,
api_provider, reason}. Free models (every used rate is 0), requests
without usage, and unmapped models stay silent. The diagnostic rides on
the standard logging payload as zero_cost_diagnostic
* fix(cost): keep the zero-cost diagnostic importable on 3.10 and recursion-free
* fix(cost): warn once per request when a $0 result is priced again
* fix(cost): judge a free deployment by its own pricing and keep it silent on calculator errors
* fix(cost): warn once per request when a usage-less evaluation sits between two zero-cost findings
* fix(cost): judge zero-cost findings by the priced entry, skip cache hits, count failure rows
* test(cost): type the zero-cost diagnostic test helpers
* test(logging): flag a $0 terminal Responses stream event by its inner response
* chore: restore the lazy OpenAPI snapshot as CI's Python 3.12 generates it
---------
Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
Fixes the litellm_remaining_requests and litellm_remaining_tokens queries in
dashboard_v2 (renamed to *_metric in v1.80.15) and adds dashboard_all_metrics
with a panel for every litellm_* family the proxy can emit, including the
prometheus_system service metrics, admission control, Redis circuit breaker and
spend log cleanup metrics. dashboard_1 charted a metric that is never emitted
and is superseded, so it is removed. A test fails when a dashboard references a
metric the proxy does not emit or when an emitted family has no panel
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
lite login used to write the minted cli-session key in cleartext to
~/.litellm/token.json. The secret material (key plus any JWT) now goes
to the OS keychain through the optional keyring package, with the 0600
file kept for non-secret metadata and as the fallback on headless boxes.
Legacy plaintext files keep authenticating and are migrated into the
keychain, then scrubbed, on first read. A secret still on disk always
outranks the keychain entry, so a failed keychain write can never
resurrect a stale key. LITELLM_PROXY_API_KEY and --api-key precedence
is unchanged, lite logout clears both stores and warns when the
keychain will not release the entry, and ~/.litellm is created 0700
(tightened from 0755 where an older CLI left it broader).
LITELLM_CLI_DISABLE_KEYRING=1 forces the file fallback.
The existing dashboards in this folder chart the litellm_* Prometheus metrics.
Nothing charted the gen_ai.* metrics the OpenTelemetry v2 integration emits, and
Grafana's own prebuilt GenAI dashboards cannot: twenty of their twenty-two panels
filter on telemetry_sdk_name="openlit", a label LiteLLM does not carry and has no
setting to add.
Ten panels over the six gen_ai instruments: spend, tokens, request count and p95
duration as stats, then request rate, spend per hour, tokens per minute split by
input and output, and p95 duration, time to first token, and provider generation
time by model. Template variables for data source, service, and model.
Verified against a live Grafana Cloud stack with real traffic across three
models. The readme documents the attribute filter the panels depend on, since the
default attribute set gives nearly every request its own series and makes every
rate-based panel read zero.
Updates the gollem_go_agent_framework example to the current Go release.
Clears stale Go stdlib advisories reported by osv-scanner against the
older 1.25.1 directive. No source changes; the single pinned dependency
(gollem v0.1.0) is backward compatible.
- Add 8 content PRs that merged directly to the release branch outside the listed staging PRs: #23769 (Ramp callback), #25252 (JWT OAuth2 override), #25254 (AWS GovCloud mode), #25258 (batch-limit cleanup), #25334 (router custom_llm_provider), #25345 (Triton embeddings), #25347 (tag-based routing), #25358 (Baseten pricing attribution)
- Add @kedarthakkar to new contributors (first-ever PR via #23769)
- Update RELEASE_NOTES_GENERATION_INSTRUCTIONS: require walking git log range between release tags in addition to staging PRs, and verify new-contributor status per author rather than trusting the GH release body floor
The cookbook example pinned litellm==1.61.15 which has 3 known
vulnerabilities (CVE-2026-35029, CVE-2026-35030, and a password
hash exposure issue), all patched in 1.83.0.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* update bedrock models in tests
* updated more tests and model_prices_and_context_window
* fix model id and pricing
* replace more sonnet models
* update tests
* git push
* update pricing
* flaky total cost
* monkey patch
* relax the cost change
* fix and revert some changes
* revert the pricing
* chore: move cost/pricing changes to bedrock-cost-fixes branch
* chore: split Bedrock file-api beta stripping to separate branch
Removes strip_unsupported_file_api_betas_for_bedrock_invoke from this branch;
see litellm_bedrock_invoke_strip_file_api_betas for that fix.
Made-with: Cursor
The file was at the repo root and excluded from pip distributions. Moving it to litellm/proxy/public_endpoints/ alongside the other provider JSON files ensures it is packaged correctly. Updates all references in the endpoint handler, coverage tests, and release notes instructions.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
* feat: initial commit adding prompt management api
* feat: initial commit adding prompt management api
* fix: refactoring to make sure get prompt is async
* fix: additional fixes
* fix(generic_guardrail_api.py): add 'structured_messages' support
allows guardrail provider to know if text is from system or user
* fix(generic_guardrail_api.md): document 'structured_messages' parameter
give api provider a way to distinguish between user and system messages
* feat(anthropic/): return openai chat completion format structured messages when calls made via `/v1/messages` on Anthropic
* feat(responses/guardrail_translation): support 'structured_messages' param for guardrails
structured openai chat completion spec messages, for guardrail checks when using /v1/responses api
allows guardrail checks to work consistently across APIs
* fix(unified_guardrail.py): support during_call event type for unified guardrails
allows guardrails overriding apply_guardrails to work 'during_call'
* feat(generic_guardrail_api.py): support new 'tool_calls' field for generic guardrail api
returns the tool calls emitted by the LLM API to the user
* fix(generic_guardrail_api.py): working anthropic /v1/messages tool call response
send llm tool calls to guardrail api when called via `/v1/messages` API
* fix(responses/): run generic_guardrail_api on responses api tool call responses
* fix: fix tests
* test: fix tests
* fix: fix tests
* fix(unified_guardrail.py): correctly map a v1/messages call to the anthropic unified guardrail
* fix: add more rigorous call type checks
* fix(anthropic_endpoints/endpoints.py): initialize logging object at the beginning of endpoint
ensures call id + trace id are emitted to guardrail api
* feat(anthropic/chat/guardrail_translation): support streaming guardrails
sample on every 5 chunks
* fix(openai/chat/guardrail_translation): support openai streaming guardrails
* fix: initial commit fixing output guardrails for responses api
* feat(openai/responses/guardrail_translation): handler.py - fix output checks on responses api
* fix(openai/responses/guardrail_translation/handler.py): ensure responses api guardrails work on streaming
* test: update tests
* test: update tests
* fix: support multiple kinds of input to the guardrail api
* feat(guardrail_translation/handler.py): support extracting tool calls from openai chat completions for guardrail api's
* feat(generic_guardrail_api.py): support extracting + returning modified tool calls on generic_guardrails_api
allows guardrail api to analyze tool call being sent to provider - to run any analysis on it
* fix(guardrails.py): support anthropic /v1/messages tool calls
* feat(responses_api/): extract tool calls for guardrail processing
* docs(generic_guardrail_api.md): document tools param support
* docs: generic_guardrail_api.md
improve documentation
* fix(unified_guardrail.py): correctly map a v1/messages call to the anthropic unified guardrail
* fix: add more rigorous call type checks
* fix(anthropic_endpoints/endpoints.py): initialize logging object at the beginning of endpoint
ensures call id + trace id are emitted to guardrail api
* feat(anthropic/chat/guardrail_translation): support streaming guardrails
sample on every 5 chunks
* fix(openai/chat/guardrail_translation): support openai streaming guardrails
* fix: initial commit fixing output guardrails for responses api
* feat(openai/responses/guardrail_translation): handler.py - fix output checks on responses api
* fix(openai/responses/guardrail_translation/handler.py): ensure responses api guardrails work on streaming
* test: update tests
* test: update tests
* test: update tests
* fix(bedrock_guardrails.py): fix post call streaming iterator logic
* fix: fix return
* fix(bedrock_guardrails.py): fix
* refactor(generic_guardrail_api.py): refactor to update to new guardrail api logic
* refactor: refactor llm api integrations to support passing in text as a list[str] instead of one at a time
* refactor: fix linting errors
* refactor: pass request type to guardrail api
allows request vs. response processing to occur
* feat: pass user api key dict information to the guardrail api
* fix: pass user api key dict information to the guardrail api
* feat: pass litellm call id + trace id, if present
* docs: update docs
* feat(generic_guardrail_api.py): new generic api for guardrails
Allows guardrail providers to work with litellm for guardrails without needing to make a PR to LiteLLM
* docs(generic_guardrail_api.md): document new generic guardrail api
* Fix: Improve PII detection and guardrail API integration
Co-authored-by: krrishdholakia <krrishdholakia@gmail.com>
* feat: correctly extract raw request from guardrail api
* docs(generic_guardrail_api.md): document this is a beta feature
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>