Commit graph

112 commits

Author SHA1 Message Date
mateo-berri
897fba08c8 feat(models): add gpt-6-astra pricing and metadata
Adds the OpenAI gpt-6-astra entry to both price files with standard, flex, priority (fast mode), batch, and above-272K long-context rates, and regression tests covering each tier and the batch rates.
2026-09-03 12:47:25 -07:00
mateo-berri
c11a1f0bc1 fix(cost_calculator): scope region_name to response-derived model names
The unconditional region read let a base_model or custom pricing
deployment resolve to the regional cost-map key: a bedrock kimi
base_model shifted to regional rates and vertex claude-opus-5 with a
us-east5 key priced 0.0. Region now applies only when the model name
comes from the provider response (provider_response_model or the
response's own model), matching the base branch. Restores the #38069
regression test and adds region-on-provider-model and base-model-free
cases
2026-08-28 12:19:14 -07:00
Andrew Mattie
134a4cd9fd fix(streaming): preserve provider model for cost calculation 2026-08-27 23:26:00 -05:00
mateo-berri
dbadee7210 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_together_cache_pricing
# Conflicts:
#	litellm/model_prices_and_context_window_backup.json
#	model_prices_and_context_window.json
#	tests/test_litellm/test_cost_calculator.py
2026-08-27 14:29:46 -07:00
mateo-berri
ef4c84dc36 feat(gemini): day-0 support for gemini-3.5-transcribe and transcribe-live
Adds a Gemini audio transcription config that maps /v1/audio/transcriptions
onto the Interactions API (speaker attribution and word timestamps land on
the OpenAI verbose_json shape), registers both models with published pricing,
routes text-only Live sessions to TEXT responseModalities so
gemini-3.5-transcribe-live sessions survive, and makes the token-priced
transcription cost path provider-aware instead of hardcoding OpenAI.
2026-08-27 10:08:23 -07:00
Mateo Wang
b54f7505a3
Merge pull request #38419 from BerriAI/litellm_gemini_live_realtime_cost
fix(cost): price gemini-live-2.5-flash-native-audio realtime sessions
2026-08-26 17:15:41 -07:00
mateo-berri
885d95d71b Merge remote-tracking branch 'origin/litellm_internal_staging' into pr37724
# Conflicts:
#	tests/test_litellm/test_cost_calculator.py
2026-08-26 16:33:28 -07:00
mateo-berri
e7b843d69b test: trim realtime cost test docstrings to one line 2026-08-26 16:33:02 -07:00
mateo-berri
ac3f987883 fix: thread service_tier through vertex cost_per_character fallbacks
Vertex Gemini 3.x models route through cost_per_character (the cost_router
token-path gate only matches gemini-2), and its token fallbacks dropped
service_tier, so ON_DEMAND_FLEX responses were still billed at the standard
rate. Pass the tier through the call site and all four fallbacks.
2026-08-26 16:29:45 -07:00
mateo-berri
b48bff7b54 fix(cost_calculator): require real values when detecting declared realtime pricing 2026-08-26 16:27:28 -07:00
mateo-berri
ab1b7bf3b6 fix(cost): price gemini-live-2.5-flash-native-audio realtime sessions
The GA vertex model had no cost map entry, and the realtime cost handler
accepted the router's price-less auto-registered deployment entry for the
session.created model at zero-defaulted rates, so sessions billed 0.0 even
when base_model pointed at the priced preview key. Adds the GA entry at its
published rates and makes the handler fall through zero-defaulted candidates
unless their cost map entry explicitly declares pricing.
2026-08-26 15:53:37 -07:00
mateo-berri
951cef1e98 fix(cost_calculator): strip duplicated region segment from alias cost keys 2026-08-26 14:10:05 -07:00
mateo-berri
6d1a7ff8a8 Merge remote-tracking branch 'origin/litellm_internal_staging' into fix-cost-alias-double-prefix 2026-08-26 13:22:45 -07:00
mateo-berri
c33454fdec fix(cost_calculator): keep custom-priced router ids when resolving slash aliases 2026-08-26 13:22:45 -07:00
Mateo Wang
74b6149d18
Merge pull request #38370 from BerriAI/litellm_azure_gpt_5_6_cache_write_pricing
fix(pricing): add azure gpt-5.6 cache write rates and correct data zone priority
2026-08-26 12:21:39 -07:00
mateo-berri
ece187ea24 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_anthropic_fast_mode_cache_and_response_speed
# Conflicts:
#	tests/test_litellm/test_cost_calculator.py
2026-08-26 12:10:33 -07:00
Mateo Wang
c13b278d79
Merge pull request #38369 from BerriAI/litellm_anthropic_geo_uplift_missing_models
fix(cost-map): add US data residency uplift to claude-sonnet-4-6 and mythos entries
2026-08-26 12:05:25 -07:00
mateo-berri
dbe52a80c1 test(cost): wrap overlong us data residency test declaration 2026-08-26 11:42:28 -07:00
mateo-berri
e97a84afcf fix(model_prices): add above-272k priority rates to azure us/eu gpt-5.6 entries 2026-08-26 11:40:19 -07:00
mateo-berri
a0d1fef89d fix(anthropic): scale cache costs by fast mode and trust served speed 2026-08-26 11:24:12 -07:00
mateo-berri
b349b9bf50 fix(pricing): add azure gpt-5.6 cache write rates and correct data zone priority 2026-08-26 10:50:44 -07:00
mateo-berri
6416a97a4d fix(model_prices): price 1-hour cache writes on claude-3-haiku and claude-3-opus at 2x input 2026-08-26 10:48:49 -07:00
mateo-berri
a2cd2d8a4b fix(cost-map): add US data residency uplift to claude-sonnet-4-6 and mythos entries 2026-08-26 10:43:43 -07:00
ksk2023
a76e224a5f fix(cost_calculator): resolve real cost key when model_name alias contains '/'
When a router-facing model_name alias contains a '/' whose leading segment
is not a registered provider (e.g. 'vertex/claude-opus-5' for deployment
'vertex_ai/claude-opus-5'), _select_model_name_for_cost_calc re-prefixed
it into a non-existent key ('vertex_ai/vertex/claude-opus-5'), so cost
lookup silently priced every streamed request at $0 - token counts were
recorded, no error raised, budgets never tripped.

After prefixing, walk the alias tail and return the first assembly that
exists in litellm.model_cost ('vertex_ai/claude-opus-5'). Provider/region
segments in the head are preserved, and an alias that resolves to no
known key keeps the previous behavior (no crash, legacy double-prefix).

Fixes #38069
2026-08-26 22:06:06 +08:00
mateo-berri
abe9af622b fix(cost): keep size buckets for Together registry rows without pricing 2026-08-25 17:09:12 -07:00
mateo-berri
6fafb46731 fix(cost): apply Together AI cache read pricing and per-model registry rates 2026-08-25 16:45:50 -07:00
mateo-berri
9906770e41 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_google_interactions_cost
# Conflicts:
#	litellm/constants.py
#	litellm/interactions/main.py
#	litellm/litellm_core_utils/litellm_logging.py
#	litellm/litellm_core_utils/llm_cost_calc/usage_object_transformation.py
#	litellm/proxy/hooks/proxy_track_cost_callback.py
#	litellm/proxy/management_endpoints/credential_migration.py
#	tests/test_litellm/litellm_core_utils/test_litellm_logging.py
#	tests/test_litellm/test_cost_calculator.py
#	ui/litellm-dashboard/src/lib/http/schema.d.ts
2026-08-22 10:39:45 -07:00
yuneng-jiang
0c97eea660
test(cost-calc): stop 182 global writes leaking out of the cost-calc suites (#37815)
* test(cost-calc): stop 182 global writes leaking out of the cost-calc suites

Across test_cost_calculator.py and llm_cost_calc/test_llm_cost_calc_utils.py,
58 tests opened by setting LITELLM_LOCAL_MODEL_COST_MAP in os.environ and
replacing litellm.model_cost, and none of them put the env var back. The
second file already had a _local_model_cost_map fixture doing it by hand with
a try/finally, so both idioms sat in the same file.

Keep that fixture, give it monkeypatch, and have every one of those tests ask
for it. The margin and discount tests drop their hand-rolled
copy-then-restore in favour of monkeypatch.setattr, which also puts the
global back when an assertion fails part way through.

Both files also drop a sys.path.insert whose argument resolves outside the
repo, so it was never what made the imports work.

TQ003 1077 -> 1075, TQ004 768 -> 693, TQ005 2836 -> 2731, and the budget
ceilings come down with them.

* fix(test): make the streamed-cost tests load the map they assert against

The local_cost_map fixture set LITELLM_LOCAL_MODEL_COST_MAP but never reloaded
litellm.model_cost, and reading the variable is not what loads the map. So the
three streaming-cost tests billed against whatever map the process happened to
be holding, and their hardcoded prices only held when something else had
already swapped in the checked-in one. This branch stops the cost-calc tests
leaking that map, which left test_main billing at the ambient prices instead.

The fixture now loads the map it names, so the prices these tests assert hold
on their own.
2026-08-21 21:00:04 -07:00
Mubashir Osmani
e6a6016e3e fix(model-costs): apply GPT-5.6 Sol promotional pricing cut
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-21 19:48:27 +00:00
mateo-berri
c549cddada fix(vertex_ai): price passthrough calls on the URL's serving location 2026-08-19 16:44:52 -07:00
mateo-berri
b39a339b7d fix(vertex_ai): apply regional endpoint uplift to cost tracking 2026-08-19 15:21:06 -07:00
mateo-berri
e736b59802 test(cost): type the batch_cost_calculator model_info literals instead of suppressing 2026-08-17 15:40:29 -07:00
Marty Sullivan
800e1d4f35 fix(cost): treat a batch rate configured as zero as free, not unset
batch_cost_calculator gated the batch rate fields on truthiness, so a deployment
that configures input_cost_per_token_batches or its output twin as 0.0 was read
as having configured nothing and that token direction fell through to half the
standard rate. Layering declared rates over published ones made this reachable:
a deployment declaring only a zero batch rate previously kept a fabricated zero
on the standard field, which happened to bill nothing.

The two batch fields are now gated on presence. Verified no cost-map entry
changes behavior: the only three carrying a zero batch rate are embeddings, whose
standard output rate is also 0.0, so both paths yield the same zero.

Adds a parametrized regression over an explicit zero, an explicit non-zero, and
unset, plus coverage for the deployment id get_model_info cannot resolve, which
were the lines Codecov flagged.
2026-08-17 14:28:38 -07:00
mateo-berri
2c6409c7e6 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_tiered_pricing_cache_creation 2026-08-14 17:44:39 -07:00
mateo-berri
2f6f5c4961 fix(cost): reach tiered pricing for models without top-level per-token rates 2026-08-14 17:04:48 -07:00
shivam
2351aaba74 test(anthropic cost): scope local cost-map env flag with monkeypatch
Some checks failed
LiteLLM Rust / rustfmt, clippy, test (push) Has been cancelled
Terraform Provider / gofmt, vet, build, test (push) Has been cancelled
Terraform Provider / Provider endpoints vs proxy OpenAPI schema (push) Has been cancelled
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-11 00:58:24 +00:00
shivam
dc58c35bba fix(anthropic cost): apply regional geo uplift to cached tokens
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-11 00:58:24 +00:00
tin-berri
32deaff015
feat(spend): rebuild the auto-router benchmarks backend as a per-session rollup (#35910)
Folds every successful auto-routed request into LiteLLM_AutoRouterSession with one
conditional upsert at spend-write time, classifying each turn (same model, first
visit, return to tier, out of order) against the row's own columns so nothing is
read before the write. The upsert's placeholders and argument tuple both derive
from the transaction dataclass's own field order, so the SQL and the call site
cannot drift apart. GET /auto_router/benchmarks aggregates the rollup, grouped
by the full (router, type) identity, and never scans LiteLLM_SpendLogs. A turn's
cache interaction is derived once from its usage record (savings.py owns the
extraction; compute_savings_spend derives cache reads from usage_object itself),
hits are counted order-independently so the overall hit rate matches its covered
denominator, caller-chosen session ids are bounded before entering the primary
key, and a poisoned statement drops only its own session's remaining turns.
Return misses inside the recorded TTL are named for what the telemetry shows
(within_ttl) rather than a presumed cause, since a provider can evict early.
Savings ride each router's derived baseline by default, so the response carries
no deployment-wide baseline label. Rollup retention has its own
maximum_autorouter_session_retention_period setting, pattern-identical to the
spend-logs knob and running in the same cleanup job on its own cutoff. Every
drain trigger sizes the queues through one owner and the enqueue honors
disable_spend_logs beside the tool-usage queue it mirrors.
2026-08-05 20:06:32 +00:00
mateo-berri
bd04520d98 Merge branch 'litellm_internal_staging' into litellm_gpt56_cache_token_pricing 2026-08-05 01:51:07 -07:00
devin-ai-integration[bot]
551e5d097c
feat(dashscope): add qwen3.7-plus and qwen3.7-max to the model cost map (#35123)
* feat(dashscope): add qwen3.7-plus and qwen3.7-max to the model cost map

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* chore: limit backup cost map diff to the new dashscope entries

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(cost_calculator): adjust tier-only alias assertion for mapped qwen3.7-plus

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(dashscope): drop redundant cost map pinning tests

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(cost_calculator): point tier-only alias check at an unmapped model

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: shivam <shivam@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-07-29 14:22:22 -07:00
Devin AI
37744ca944 fix(cost): price anthropic messages cache read/write tokens instead of full input rate
Anthropic-shaped usage was mapped through the Responses API usage converter, which ignores top-level cache_read_input_tokens/cache_creation_input_tokens, so cache hits on /v1/messages were billed entirely at the uncached input rate
2026-07-28 16:37:49 +00:00
mateo-berri
d3f5c6dbf6 fix(cost_calculator): sum mirrored cache token fields once in combine_usage_objects
combine_usage_objects iterates prompt_tokens_details model_fields and sums each;
with cache_write_tokens and cache_creation_tokens now mirroring each other via
__setattr__, the pair was summed twice, doubling cache creation counts for
Anthropic batch cost calc, mid-stream fallback usage merges, and realtime usage.
Collapse the mirrored pair to one representative before summing.
2026-07-23 19:07:09 -07:00
mateo-berri
e458aa1230 fix(interactions): bill google_search grounding queries per query 2026-07-15 08:12:49 -07:00
mateo-berri
59d4e52a3d fix(interactions): bill background interactions once completed via cost polling 2026-07-14 20:05:33 -07:00
mateo-berri
f08742c6f4 fix(interactions): track cost and spend for Google Interactions API requests 2026-07-14 17:29:48 -07:00
Shivam Rawat
65e2432a37 fix(proxy): bill tier-only deployments instead of $0
Route cost calculation to the deployment's router_model_id entry when it carries tiered_pricing but no flat per-token rate, so models like dashscope/qwen3.7-plus are billed via their tier table rather than the pricing-stripped shared alias.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-11 13:47:56 -07:00
Mateo Wang
9076c33347
fix(batches): price anthropic passthrough message batches correctly in batch cost job (#32307)
* fix(batches): price anthropic passthrough message batches correctly in batch cost job

Anthropic message batches created via the /anthropic passthrough were never
cost tracked. The CheckBatchCost job fetched batch results from the Files API
(POST /v1/files/msgbatch_.../content), which Anthropic rejects with "File id
must have file_ prefix"; the error response was silently wrapped as file
content, parsed as zero successful rows, logged as a $0 aretrieve_batch spend
row, and the job was marked batch_processed=true so the $0 was permanent.

Route msgbatch_ file ids to GET /v1/messages/batches/{id}/results in the
anthropic files transformation, raise on HTTP error status in
retrieve_file_content instead of returning the error body as content, parse
Anthropic's results JSONL shape (result.type == "succeeded",
result.message.usage with cache creation/read tokens) in batch_utils, price
cache creation tokens at cache_creation_input_token_cost in the batch cost
fallback (50% batch discount preserved for base input, cache reads, cache
writes, and output), and leave the managed object row unprocessed when cost
tracking fails so a later poll retries instead of permanently recording $0.

* fix(batches): carry cache token details into aggregated anthropic batch usage
2026-07-06 20:33:57 -07:00
Mateo Wang
43b0a25f07
feat(vertex_ai): add Google Cloud Speech-to-Text Chirp 3 transcription support (#32274)
* fix(llm_http_handler): send dict transcription request data as a JSON body

httpx form-encodes dicts passed via data= and silently ignores json=, so the
generic audio transcription path never actually sent a JSON body. No provider
hit this before; JSON-body speech APIs need it.

* feat(vertex_ai): add Google Cloud Speech-to-Text Chirp 3 transcription support

Adds a VertexAIAudioTranscriptionConfig wired through ProviderConfigManager so
vertex_ai/chirp_3 works on /v1/audio/transcriptions (sync and async) via the
Speech-to-Text v2 recognize API. Auth reuses the standard Vertex credential
resolution (vertex_project/vertex_location/vertex_credentials or ADC); the
location defaults to the us multi-region since chirp_3 is only served from the
us and eu multi-regions, and non-global locations use the regional
<location>-speech.googleapis.com host. Maps language to languageCodes (auto
language detection by default), joins all result alternatives into the
transcript, and tracks cost from totalBilledDuration with a
vertex_ai/chirp_3 price entry at Google's published $0.016/min.

* fix(vertex_ai): map bare ISO-639-1 language codes to BCP-47 for Speech-to-Text

OpenAI clients send language codes like "en", which Google rejects with 400
("not supported by the model chirp_3 in the location us"); Speech-to-Text
wants region-qualified BCP-47 like "en-US". Adds a shared
normalize_transcription_language_to_bcp47 helper in audio_utils (NVIDIA Riva's
transcription config already hand-rolled the same table privately) that maps
common bare codes and passes region-qualified ones through, and applies it in
the Vertex transcription request. Also narrows the response JSON parse guard
to ValueError.

* fix(vertex_ai): drop zero output_cost_per_second so chirp_3 cost tracking works

cost_per_second prefers output_cost_per_second whenever it is not None, so the
0.0 in the chirp_3 entry priced every transcription at $0.00 instead of using
input_cost_per_second. Remove it from both cost maps and pin the behavior with
a regression test computing 18s of chirp_3 audio to ~$0.0048.

* fix(vertex_ai): validate client-controllable location to prevent SSRF in Speech-to-Text

get_complete_url interpolated vertex_location straight into the request host,
and vertex_location is client-controllable on the proxy (it flows from the
request body and is not on the request-body blocklist). An authenticated caller
could send vertex_location="attacker.example/" to point the host at their own
server, so the proxy would POST the audio plus its admin-minted Google bearer
token and x-goog-user-project header to the attacker, exfiltrating a
cloud-platform-scoped OAuth token minted from the admin's credentials.

Factor the location validation the rest of vertex_ai already applied in
get_vertex_base_url (^[a-z][a-z0-9-]*$ plus the global allowance) into a shared
validate_vertex_location helper in common_utils and call it from both the chat
host builder and the new speech host builder. Invalid locations now raise a 400
VertexAIError instead of building a host. Also reject vertex_project values that
carry URL-structural characters, since it lands in the URL path.

Regression tests assert on the parsed netloc so the security property is pinned:
valid locations always resolve to a *speech.googleapis.com host and injection
inputs are rejected.

* fix(vertex_ai): reject unsupported transcription response_format values instead of silently ignoring
2026-07-06 18:25:22 -07:00
Mateo Wang
5f864c83ce
chore(lint): zero out crash-class pyright rules and ban new type: ignore comments (#32152)
* fix: zero out crash-class basedpyright rules across litellm/

* feat(lint): add LIT009 banning inert type: ignore comments

* docs: require bracketed rule and reason on every suppression

* chore(lint): ratchet budgets down and zero crash-class pyright limits

* fix: narrow auto router routelayer through a local before calling

* test: add regression tests for crash-class fixes

* fix: drop dead AZURE_AD_TOKEN lookups and word-bound the type-ignore regex
2026-07-04 16:56:12 -07:00
Shivam Rawat
f0d41e4d16 fix: attribute realtime transcription cost in cost breakdown
Pass transcription_cost through additional_costs so cost_breakdown's
input_cost + output_cost + additional_costs sums to total_cost instead
of silently folding it into total_cost only.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-04 12:22:53 -07:00