Commit graph

25 commits

Author SHA1 Message Date
mateo-berri
5eeccf69b6 fix(batches): skip undecodable batch output lines when costing 2026-08-19 14:35:01 -07:00
mateo-berri
51cafe4365 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_batch_empty_line_cost
# Conflicts:
#	type-discipline-budget.json
2026-08-19 13:54:57 -07:00
mateo-berri
5c6391d7d2 refactor(batches): parameterize the batch output Mapping annotations 2026-08-19 02:15:22 -07:00
mateo-berri
df0d8ff15e test: assert the vertex batch output rate is a real discount 2026-08-18 22:38:13 -07:00
mateo-berri
3a2728a42f test: derive vertex batch cost expectation from the cost map
The gemini 3.6 flash batch rates landed at half the standard rates in
94a29e0708, so the hardcoded standard-rate expectation started failing
on staging and red-lit misc / Run tests on every PR.
2026-08-18 21:18:16 -07:00
mateo-berri
608d749983 fix(batches): stop one bad output line from zeroing an entire batch's spend 2026-08-18 20:46:59 -07:00
mateo-berri
678a636846 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_internal_copy_37077
# Conflicts:
#	tests/test_litellm/batches/test_batch_utils.py
2026-08-17 14:57:29 -07:00
Mateo Wang
3f4810b8f2
Merge pull request #37078 from cu-aaii/litellm_fix_bedrock_converse_batch_usage
fix(bedrock): read batch usage by payload shape, not by provider name
2026-08-17 14:51:02 -07:00
Marty Sullivan
b593cef758 fix(batches): keep published rates for a side the deployment leaves unset
Substituting a deployment's pricing wholesale billed the token direction it did
not configure at zero: get_model_info fills an absent cost with 0, and any
non-None pricing field suppressed the global fallback. A deployment declaring
only input_cost_per_token therefore billed output at nothing.

Each of the four batch cost fields now falls back to the model's published rate
when the deployment leaves it unset, so a one-sided override applies to the side
it configures and only that side.

Adds a parametrized regression over input-only, output-only, and both-zero, plus
coverage for a deployment whose model has no published entry. Annotates the new
test helpers per the repo's type-coverage rule and drops the narrative banner
comment from the batch tests.
2026-08-17 14:28:38 -07:00
Marty Sullivan
f74c72eedb fix(batches): price a retrieved batch from its deployment's model and rates
Retrieving a completed batch computed its cost with no model identity: neither the
deployment's model nor its configured pricing reached the batch cost calculation.

For bedrock that left the cost model falling back to the provider's own response
model (e.g. "claude-sonnet-4-6"), which does not resolve under a bedrock provider,
so the lookup missed and cost silently became $0 while usage stayed correct.
Dropping the deployment's model info separately discarded any rates configured on
that deployment, billing a zero-cost deployment at the public rate instead.

Both are the same omission at the call site, so both are fixed by passing the
logging object's own model and the pricing the router registered for the
deployment.
2026-08-17 14:28:37 -07:00
Mateo Wang
2bc87ec3cc
Merge pull request #34067 from MUSE-CODE-SPACE/fix/batch-logging-null-output-file
fix(batches): don't crash logging when a completed batch has no output file
2026-08-17 10:01:02 -07:00
Marty Sullivan
5fe7793a14 refactor(bedrock): own the Converse batch usage shape in the provider layer
Shape detection and block normalization sat in the generic batch layer, which
let batch and live parsing of the same wire format drift apart. Both now live on
AmazonConverseConfig as is_converse_usage_shape and usage_from_batch_output, so
batch_utils asks the provider adapter rather than knowing Bedrock's field names.

Adds direct coverage for the shape predicate, the completion of an incomplete
block, cache-count inflation, and the streaming usage event that shares the
public transform. Drops the narrative banner from the batch tests.
2026-08-16 22:32:56 -04:00
Marty Sullivan
7dbf2d57c5 fix(bedrock): read batch usage by payload shape, not by provider name
Every bedrock batch output line went through the Anthropic usage parser, which
reads snake_case input_tokens/output_tokens. Converse-family models (Nova and
friends) report camelCase inputTokens/outputTokens, so their usage came back
0/0/0 and the batch billed $0 despite real token consumption.

Usage is now selected by the shape of the payload: a Converse-shaped block goes
through the same transform the live Converse path uses, so a batch and an
equivalent non-batch call agree on tokens, including cache reads and writes.
Anthropic-shaped bedrock output is unchanged.

A shape neither parser understands (an InvokeModel-native payload from Titan,
Cohere, or Llama, which name their counts differently again) still reads zero,
but now warns with the keys it saw instead of silently billing $0.

Exposes the Converse usage transform as public, since batch parsing is a second
legitimate caller; that also removes the private-member access invoke_handler
was already making.
2026-08-16 04:18:22 -04:00
mateo-berri
1524880dce fix(batches): sign the retrieve-path output read with the deployment's AWS credentials 2026-08-15 12:09:59 -07:00
Marty Sullivan
60fe4e464c fix(bedrock): resolve the managed-batch output bucket on the inline accounting path too
A third path reads a completed batch's output file, and it could not resolve the
bucket either. When cost is accounted from the retrieve itself rather than from
the poller, the batch success handler calls _handle_completed_batch, which fetches
the output file through _extract_file_access_credentials. That helper forwarded a
whitelist covering Azure and Vertex, gcs_bucket_name included, but nothing for
Bedrock, and retrieve_batch built its litellm_params through get_litellm_params,
whose fixed signature drops the trusted credential snapshot. So the snapshot never
reached the file read and it failed with "S3 bucket_name is required" for a bucket
the deployment had configured, leaving the batch's cost unrecorded.

Adding s3_bucket_name to that whitelist would not have worked. The Bedrock file
config deliberately resolves the bucket only from the immutable server-side
snapshot or the environment, never from a request param, because the bucket is
what managed file ids are validated against. The snapshot is therefore what has to
flow, exactly as it already does for the model-routed and cost-poller paths.

retrieve_batch now re-adds the snapshot after get_litellm_params, the same way the
file operations already do, the whitelist forwards it, and the proxy attaches it
for router-routed managed batches from the deployment behind the unified id.
Verified against a live proxy reading a real completed Bedrock batch: the cost row
appears within seconds of the retrieve carrying the batch's real spend and usage,
where before the read raised and no row was written.

Resolving those credentials is best effort. A batch whose deployment no longer
resolves, which happens when a model group is removed while batches are in
flight, still serves its status instead of failing the request on the lookup.
This matters for the OSS and polling-disabled configurations, where the retrieve
path is the only thing that accounts for a batch at all.
2026-08-14 01:17:56 -04:00
MUSE
f91e698adb fix(batch): avoid reading a nonexistent output artifact for completed batches
Completed batches that contain only failed requests do not generate an
output file, leaving output_file_id unset while the failures are recorded
through error_file_id instead.

The completion handler attempted to read the output payload regardless of
whether an output file actually existed. During retrieve polling this caused
the logging pipeline to fail with "Output file id is None cannot retrieve
file content", preventing normal completion bookkeeping from running.

Skip output retrieval when no output file is available and return an empty
batch summary (zero usage, zero cost, no model entries). The lower-level
file retrieval helper still reports an error if it is called directly with
an invalid or missing file identifier.

Closes #33987
2026-08-14 05:20:16 +09:00
Rithvik Mysore Suresh
390cddb69f test(batches): run Responses coverage in CI
Coverage jobs collect tests/test_litellm/batches. Move the mixed Responses and chat regression into that suite so CI exercises the normalization branch.
2026-07-31 10:24:10 -04:00
mateo-berri
a97233067d Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_batch_output_single_pass
# Conflicts:
#	basedpyright-code-budget.json
#	ruff-strict-budget.json
#	type-discipline-budget.json
2026-07-30 10:55:28 -07:00
mateo-berri
8a30092961 test(batches): exercise real GCS validation for vertex batch output reads 2026-07-29 23:53:15 -07:00
mateo-berri
0b09588685 refactor(batches): aggregate batch output cost, usage, and models in a single pass
Completed-batch cost tracking parsed the whole output file into a list of
dicts, pretty-printed it into debug strings even with debug logging off, and
walked the list three times (cost, usage, models), so a large batch output
could pin a worker's memory. The output is now folded line by line into small
per-line stats records via _aggregate_batch_cost_usage_models, the eager
json.dumps debug calls are gone, and the raw-vertex path computes cost and
usage in one call instead of two. _get_batch_output_file_content_as_dictionary
becomes _fetch_batch_output_file_content (returns bytes); the superseded
three-pass helpers are deleted and their tests migrated
2026-07-29 22:00:01 -07:00
mateo-berri
27ccc44471 fix(batches): forward gcs_bucket_name so vertex batch cost logging can read the output file 2026-07-29 20:44:31 -07:00
mateo-berri
692a812f13 fix(batches): calculate cost and usage for completed Vertex AI batches 2026-07-29 20:17:39 -07:00
Sameer Kankute
c2141b1113
feat(batches): track cost for unmanaged Bedrock batches, generalize the flag (#32315)
* feat(batches): track cost for unmanaged Bedrock batches, generalize the flag

CheckBatchCost skipped Bedrock batches whose unified_object_id is a raw
model-invocation-job ARN, the same root cause previously fixed for
unmanaged Vertex batches. Bedrock batches embed the model name in their
s3:// input file name instead (litellm-bedrock-files-{model}-{uuid}.jsonl),
so the same routing mechanism now derives the model from that layout and
matches it to a configured bedrock deployment.

track_unmanaged_vertex_batch_cost is renamed to track_unmanaged_batch_cost
since two providers now share this mechanism.

* fix(batches): parse Bedrock batch output and price with deployment model name

Bedrock model-invocation-job results use modelOutput/error rows and short
internal model ids that are not in the cost map, so unmanaged batch cost
tracking logged tokens but $0 spend. Use deployment model name for pricing
and add regression tests.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-13 10:33:13 +05:30
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
Sameer Kankute
2cf565ae28
test(batches): add 1:1 test file scaffold for batches component paths (#30529)
* test(batches): add 1:1 test file scaffold for batches component paths

Co-authored-by: Cursor <cursoragent@cursor.com>

* Add harness test for create batch endpoint

* Add retrieve endpoint harness tests

* Add list  endpoint harness tests

* Add cancel endpoint harness tests

* Add cancel endpoint harness tests

* Add test for litellm/batches/main.py

* Add test for litellm/tests/test_litellm/batches/test_batch_utils.py

* Add handler and transformation tests for all providers

* Fix: run batches tests in cicd

* fix(tests): remove azure/__init__.py that shadowed azure namespace package

Adding __init__.py to tests/test_litellm/llms/azure/ caused pytest to
insert tests/test_litellm/llms/ into sys.path[0], making our empty
azure/ dir shadow the real azure-identity namespace package. Any test
that patched azure.identity.* would then fail with AttributeError.

* style(tests): apply ruff format to test_batch_utils.py

Base migrated the formatter from black to ruff format (#31317); reformat the
batches scaffold test file to match.

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
2026-06-29 09:22:58 +05:30