Commit graph

332 commits

Author SHA1 Message Date
Mateo Wang
8922aaab95
fix(anthropic): log partial stream spend when a /v1/messages client disconnects mid-stream (#37558) 2026-08-19 18:43:46 -07:00
Mateo Wang
634e699555
Merge pull request #36331 from BerriAI/devin_ai_agentcore_search
feat(search): add Amazon Bedrock AgentCore web search provider
2026-08-19 15:59:17 -07:00
mateo-berri
70a4f9a73a fix(search): refuse AgentCore credentials over plaintext HTTP
A trusted hostname over plain http would expose the bearer token or a
replayable SigV4 signature to network observers. Credentials now only ride
https, with localhost exempt so local MCP stubs keep working.
2026-08-19 14:50:58 -07:00
yassin
8ef522a2a0 fix(search): read AgentCore structuredContent results
Web-search connector 1.1.0 and later return the machine-readable results in result.structuredContent and may leave the text block as prose, which the parser dropped.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-19 21:41:57 +00:00
mateo-berri
b3c3e6ebb8 fix(search): default the AgentCore MCP protocol version to the gateway default 2026-08-19 14:25:34 -07:00
mateo-berri
46a4eda19e Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_fix_bedrock_adaptive_thinking_token_accounting
# Conflicts:
#	litellm/llms/bedrock/chat/invoke_handler.py
#	litellm/responses/litellm_completion_transformation/transformation.py
#	tests/test_litellm/llms/bedrock/chat/test_converse_transformation.py
#	tests/test_litellm/responses/litellm_completion_transformation/test_reasoning_content_transformation.py
2026-08-19 14:10:53 -07:00
yassin
ae18f055ee fix(search): harden AgentCore gateway trust, error and SSE handling
Refuse to SigV4-sign requests to hosts that are neither an AgentCore gateway
hostname nor AGENTCORE_GATEWAY_URL's host, match gateway hostnames on the URL
host instead of anywhere in the URL, accept the env token when api_base is a
real gateway, raise on tools/call responses with result.isError, and split
CRLF-framed SSE events.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-19 19:07:17 +00:00
mateo-berri
54cc988a9e test: drop restating comment and wrap long call in thinking tests 2026-08-18 19:55:22 -07:00
mateo-berri
138c77023a fix: accept bool thinking param instead of crashing with AttributeError
litellm.completion(thinking=True) crashed pre-network in is_thinking_enabled
with a retryable APIConnectionError ('bool' object has no attribute 'get'),
so the router burned retries on a deterministic failure and proxy clients got
a traceback instead of a usable response.

validate_and_fix_thinking_param now coerces thinking=True to the enabled dict
with the default medium budget and drops thinking=False, and the remaining
dict-assuming thinking accessors (base config, bedrock converse, deepseek)
guard with isinstance so raw bools can never crash a transform.
2026-08-18 19:44:31 -07:00
yassin
17b72d5089 fix(search): send MCP-Protocol-Version on AgentCore gateway calls
Some checks failed
Terraform Modules / fmt, validate, test (aws) (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-18 23:26:41 +00:00
yassin
cf2e50077c Merge branch 'litellm_internal_staging' into devin_ai_agentcore_search
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-18 21:53:22 +00:00
Mateo Wang
96d2ceef3b
Merge pull request #31435 from kingdoooo/litellm_bedrock_output_bucket
fix(bedrock): validate file-content retrieval against the configured output bucket (#26335)
2026-08-17 15:48:56 -07:00
Kent
9ff9f77137 test(router): cover s3_output_bucket_name surviving the trusted credential snapshot
The field itself landed on staging via 0c5c9c79d7; these are the regression tests from PR #31435 for the retrieval-facing half.

(cherry picked from commit a9a322d63f6d4658b1f28d1622335775e94736a4)
2026-08-17 14:51:10 -07:00
Kent
7bea4def27 fix(bedrock): validate file-content retrieval against the configured output bucket
Bedrock batch jobs write their results to s3_output_bucket_name when it differs
from the input bucket, but the file-content retrieval path validated the file id
only against the input bucket (s3_bucket_name). A deployment that configures a
separate output bucket therefore could not retrieve its own batch outputs: the
id validated against the input bucket and was rejected as a foreign bucket.

Resolve the trusted output bucket alongside the input bucket from the immutable
credential snapshot (or AWS_S3_OUTPUT_BUCKET_NAME), and try the file id against
each configured bucket, returning the first that validates. The SSRF guard is
preserved: only server-configured buckets are tried, never a request param, and
an id outside both is still rejected.

(cherry picked from commit 1d407c2f26)
2026-08-17 14:51:09 -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
Brian Cox
3b6ae75f73
fix(bedrock): preserve cache token usage when invocationMetrics replace the usage block (#36878)
Bedrock invoke /v1/messages streaming reports cache_read_input_tokens and
cache_creation_input_tokens on message_stop.usage while attaching
amazon-bedrock-invocationMetrics to the same chunk. The stream decoder
rebuilt that chunk's usage block from inputTokenCount/outputTokenCount
alone, which exclude cache reads and writes, so the cache breakdown was
destroyed before _promote_message_stop_usage could surface it and cache
tokens were billed at $0. Merge instead of replace, and also map
cacheReadInputTokenCount/cacheWriteInputTokenCount when Bedrock reports
the cache itemization inside the invocation metrics.

Co-authored-by: Brian Cox <3924351+brian5021@users.noreply.github.com>
2026-08-17 11:28:35 -07:00
Yassin Kortam
ee08b63657
feat(bedrock): forward LiteLLM identity and metadata into Bedrock requestMetadata (#36861)
Adds an opt-in operator allow-list, litellm_settings::bedrock_request_metadata_fields, that forwards LiteLLM key, team and end-user identity plus client spend_logs_metadata into Bedrock request metadata so Bedrock spend can be grouped in AWS Cost Explorer.

Covers all three Bedrock surfaces: the Converse body requestMetadata field, and a signed X-Amzn-Bedrock-Request-Metadata header on Invoke chat completions and on Invoke /v1/messages, where the header is the only viable leg.

The resolver reads both metadata variable names, reserves the whole user_api_key_ prefix against caller-supplied keys, caps the client slot budget explicitly at 16 minus the reserved count, and drops rather than rejects auto-injected values that violate Bedrock constraints. Caller-supplied requestMetadata keeps its existing 400 semantics.

The request-metadata field and header are proxy-owned whenever forwarding is enabled. A caller-supplied value, reachable through the generic extra_headers passthrough, is dropped unconditionally and compared case-insensitively, and is replaced only by the proxy's own value, so identity in the AWS billing record cannot be forged. Absence of a resolved value still means absence on the wire rather than a fallback to the caller's. The guardrail headers keep their existing no-displace behaviour.
2026-08-17 11:27:46 -07:00
Mateo Wang
41c3133d0e
Merge pull request #34087 from ArjunPakhan/fix/bedrock-cancel-batch
fix(batches): support AWS Bedrock batch cancellation via `StopModelInvocationJob`
2026-08-17 10:00:57 -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
mateo-berri
1b13957776 fix(bedrock): treat ConflictException on stop as idempotent cancel 2026-08-16 13:44:27 -07: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
904ff9efa7 Merge branch 'litellm_internal_staging' into devin_ai_fix_bedrock_batch_file_bytes_36388
Some checks failed
Terraform Modules / fmt, validate, test (aws) (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
Resolves the transform_create_file_response conflict by keeping the
_uploaded_object_size handoff over the response Content-Length read,
and adds the rebind-ok justification LIT011 now requires for the
upload-size litellm_params handoff after the base budget ratcheted.
2026-08-15 17:31:52 -07:00
mateo-berri
4114f907ea fix(bedrock): reraise cancel validation errors for non-terminal jobs, allow bedrock in acancel_batch typing 2026-08-15 17:25:16 -07:00
mateo-berri
57e946f279 Merge origin/litellm_internal_staging into fix/bedrock-cancel-batch 2026-08-15 17:18:08 -07:00
mateo-berri
e8c1fe8b11 fix(bedrock): fall back to the batch deployment model for unmapped record models 2026-08-14 17:11:24 -07:00
daleselaji-dev
80c37bfe3a fix(bedrock): resolve aliases in batch file records 2026-08-14 17:04:24 -07:00
Yassin Kortam
86f2f16fd4
fix(bedrock): hoist custom.defer_loading before dropping custom on invoke tools (#36855) 2026-08-13 19:28:18 -07:00
Yuneng Jiang
075781568d
test: remove tests that never execute
Three groups, all verified by running the suite rather than by inspection.

18 files whose every test function carries an unconditional @pytest.mark.skip,
39 test functions in total. They are collected on every CI run and always skip,
so they advertise coverage the suite does not have. Reasons on the marks include
"AWS Suspended Account", "lakera deprecated their v1 endpoint" and "moved to
using 'otel' for logging"; 26 of the marks predate 2025.

30 test functions with a byte-identical body and identical decorators to a
sibling in the same file and class, differing only in name. Deleting one of each
pair removes no coverage. Four further candidates were excluded because they
override an inherited test, where deleting the override un-shadows the base
class implementation instead of removing a duplicate.

9 test functions that a later definition of the same name shadows, so Python
never binds them and pytest cannot collect them.

One file that is a demo script rather than a test; its own docstring says to run
it with python.

Verification: collecting the 26 edited files gives 2,492 node IDs before and
2,462 after. The 30 duplicate deletions account for exactly 30 removals, the 9
shadowed deletions account for 0 (confirming at runtime that they were never
collectable), nothing unexplained disappeared, and nothing new appeared. No
other test or module imports any deleted symbol.
2026-08-12 10:45:38 -07:00
Mateo Wang
7b34a6c632
Merge pull request #36507 from BerriAI/litellm_bedrock_converse_thinking_stream_fix
fix(bedrock): preserve adaptive thinking effort through the /v1/messages bridge
2026-08-11 12:23:29 -07:00
Mateo Wang
5c704055c6
Merge pull request #36502 from BerriAI/litellm_bedrock_invoke_tool_search_fix
fix(bedrock): send tool-search beta header for Haiku 4.5 on Invoke /v1/messages
2026-08-11 12:21:46 -07:00
mateo-berri
7d4488d2e8 refactor(bedrock): read tool search support from the model map
Record supports_tool_search on the Bedrock Claude entries in both cost
map files and have _supports_tool_search_on_bedrock read it first via
the provider-resolved capability lookup, keeping the name patterns as a
fallback for ARNs and ids the map cannot resolve. Threads the flag
through ModelInfoBase and drops a dated remark from the pattern list
2026-08-11 10:06:04 +00:00
mateo-berri
0f41365c34 fix(bedrock): forward output_config effort for application inference profile ARNs 2026-08-11 09:11:22 +00:00
mateo-berri
929ee52b87 fix(bedrock): preserve adaptive thinking effort through the /v1/messages bridge
Claude Code drives Opus 4.7 with thinking {"type": "adaptive"} plus
output_config {"effort": "max"}. The anthropic-to-openai adapter
forwarded thinking verbatim for Claude models but dropped output_config,
and Bedrock Converse streams zero reasoningContent blocks for adaptive
thinking without an effort tier. Forward the effort subset of
output_config for Bedrock targets, accept it in the converse supported
params, and map it with the model's effort ceiling applied. Re-enable
the skipped e2e compat cell that catches this
2026-08-11 03:23:16 +00:00
mateo-berri
b5eed5e526 test(bedrock): cover the aws request param merge guard in the unit suite 2026-08-10 20:08:20 -07:00
mateo-berri
bc98c67028 fix(bedrock): send tool-search beta header for Haiku 4.5 on Invoke /v1/messages
Bedrock InvokeModel rejects tool_search_tool_* tool types unless the
request body carries the tool-search-tool-2025-10-19 beta. The model
allowlist gating that beta omitted Haiku 4.5 (and Opus 4.7, supported
since launch per live verification), so every tool-search request on
those models got a Bedrock 400. Add both to the allowlist and re-enable
the e2e compat cell that caught it.
2026-08-11 02:46:27 +00:00
ryan-crabbe-berri
20354bfcdc
fix(bedrock): reject Anthropic server-side web_search tool with actionable error (#36473)
* fix(bedrock): reject Anthropic server-side web_search tool with actionable error

Bedrock's Anthropic Messages endpoints cannot execute Anthropic's
server-side web_search tool, so forwarding it returns an opaque
"The provided request is not valid" 400 from Bedrock. Fail fast in the
invoke transform with an error that names the unsupported tool, the
model, and links the web search interception docs as the fix.

* refactor(bedrock): address review nits on web_search guard typing
2026-08-10 15:59:18 -07:00
Alex Shtof
280c95ccb0
fix(bedrock): enable native structured output for GLM 5 and DeepSeek V3.2 (#35669)
* fix(bedrock): enable native structured output for GLM 5 and DeepSeek V3.2

* ci: empty commit

---------

Co-authored-by: Alexander Shtoff <alexander.shtoff@tii.ae>
2026-08-10 10:18:13 -07:00
devin-ai-integration
1b2430b8b6 fix(bedrock): report uploaded size in the FileObject returned by managed batch uploads 2026-08-10 10:25:37 +00:00
Devin AI
07f14617f6 feat(search): add Amazon Bedrock AgentCore web search provider
Adds 'agentcore' as a search provider backed by an AgentCore Gateway MCP web-search target, usable from litellm.search()/`/search` and as a websearch_interception backend. Supports SigV4 (AWS_IAM gateways) and bearer tokens (CUSTOM_JWT gateways) via a new BaseSearchConfig.sign_request hook.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-09 01:32:21 +00:00
tin-berri
e50a42051c
fix(websearch): restore snippet text in native web_search_tool_result blocks (LIT-5315) (#36228)
* fix(websearch): restore snippet text in native web_search_tool_result blocks (LIT-5315)

The build_web_search_tool_result_block method copied url/title/page_age but
hardcoded encrypted_content to empty string, never reading SearchResult.snippet.
This left every native block content-free, forcing clients to web_fetch each
result to recover evidence—the reported symptom.

The Anthropic spec carries page text only in encrypted_content (an opaque
server-issued blob we cannot mint), so snippet is emitted as an additive key
alongside the spec fields. encrypted_content stays empty rather than holding
plaintext, which would assert encryption semantics that don't hold.

The anthropic SDK's BaseModel sets extra='allow', so the additive snippet key
survives SDK parsing. litellm has no typed model for web_search_result at all,
so nothing drops it internally. Turn-2 replay behavior is unaffected: the
empty encrypted_content already exists today.

Tests:
- Updated test_shape_with_results to assert snippet present
- Added test_snippet_carried_for_every_result to cover multi-result ordering
- Added test_missing_snippet_degrades_to_empty_string for edge case
- Mutation check: reverting source-only yields 3 test failures, restored to 117 passed

Fixes: LIT-5315
Co-Authored-By: Claude <noreply@anthropic.com>

* fix(websearch): make synthesized web_search blocks replayable by native clients

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

* fix(websearch): flatten a resultless replayed search block so Bedrock accepts the next turn

The flatten added for LIT-5315 bails when the replayed web_search_tool_result
carries an empty content list, but that is exactly what the interceptor emits
when a search legitimately returns nothing and when a search raises. The block
survived into the outbound body, Bedrock rejected the tag, and the conversation
died on the following turn just as it did before the flatten existed.

An empty content list has no encrypted_content to respect and no evidence to
preserve, so it flattens safely, and its paired server_tool_use goes with it.
The rendered text now says so explicitly rather than emitting a bare header.

Adds the multi-turn replay coverage that existed nowhere: the outbound Bedrock
invoke body is asserted free of both block types, parametrized over the
results-present and resultless cases, and built from the interceptor's own
builder so the fixture cannot drift from what it emits.

Resolves LIT-5320

* test(websearch): pin flatten idempotency for the agentic-loop re-entry

The agentic loop re-enters the same /v1/messages entry point for its follow-up
call and hands it the original client history, so the flatten runs again over
already-flattened messages once per iteration. Bedrock always takes that path,
since its config reports web search as natively handled and the short-circuit
is skipped.

A pass that appended the rendered text instead of replacing the block would
duplicate the evidence on every iteration and re-ship the unsupported tag, and
no existing single-pass test sees it. Mutation checked: keeping the original
block alongside the rendered text fails this test on its own.

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Yassin Kortam <yassin@berri.ai>
2026-08-07 17:28:55 -07:00
mateo-berri
8ad75e5ae9 test(bedrock): cover the batch record classifier fallbacks and pin metadata handling 2026-08-06 22:35:56 -07:00
mateo-berri
9f8f9cd64d Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_wt_35675 2026-08-06 22:34:09 -07:00
mateo-berri
2cc65a94c3 merge: litellm_internal_staging into litellm_bedrock_batch_sse_kms
Some checks failed
Terraform Provider / gofmt, vet, build, test (push) Has been cancelled
Terraform Provider / Provider endpoints vs proxy OpenAPI schema (push) Has been cancelled
2026-08-06 00:09:23 -07:00
mateo-berri
7c2b709727 Merge branch 'litellm_internal_staging' into litellm_bedrock_batch_non_chat_records
Some checks failed
Terraform Provider / gofmt, vet, build, test (push) Has been cancelled
Terraform Provider / Provider endpoints vs proxy OpenAPI schema (push) Has been cancelled
2026-08-05 23:56:23 -07:00
mateo-berri
7760152487 Merge origin/litellm_internal_staging into fix/bedrock-cancel-batch 2026-08-05 23:54:13 -07:00
devin-ai-integration[bot]
f54cd287a2
fix(bedrock): grant bedrock:CountTokens in OIDC session policy (#33145)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-05 14:55:46 -07:00
Devin AI
aadfa89ff6 Merge branch 'litellm_internal_staging' into litellm_fix_bedrock_adaptive_thinking_token_accounting
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-05 21:13:36 +00:00
Devin AI
af2246c5b8 fix(anthropic,bedrock): report provider thinking tokens instead of classifying them as text
Resolves LIT-5244

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-05 20:47:05 +00:00
Yassin Kortam
267adf709a
fix(bedrock): sign Bedrock managed-file S3 requests with S3SigV4Auth (#35983)
S3 rebuilds the canonical request from the wire path with single
percent-encoding, which botocore models as S3SigV4Auth. Generic SigV4Auth
quotes the already encoded path a second time, so an object key holding any
character that percent-encodes was signed over %2520 while the request
carried %20, and S3 answered 403 SignatureDoesNotMatch.

The S3 logger was corrected in #35726; the Bedrock managed-files upload and
retrieval paths copied that same pre-fix pattern and were left behind, so a
configured bucket prefix with a space 403s every file upload and every file
content read.
2026-08-05 13:43:30 -07:00
tin
d39c557743 fix(bedrock): drop conflicting tool_choice.type when toolConfig.toolChoice is set
Converse rejects a request that carries both toolConfig.toolChoice and an
additionalModelRequestFields.tool_choice.type, so any request that pairs
parallel_tool_calls with an explicit tool_choice 400s with "The additional field
tool_choice/type conflicts with the existing field toolConfig.toolChoice.auto".
That pairing is what agentic clients send by default; Codex CLI sends
tool_choice "auto" and parallel_tool_calls false on every turn, so tool calling
was broken outright on Bedrock models that advertise
supports_parallel_tool_use_config.

Drop the type from the Anthropic passthrough once toolChoice carries it, and keep
disable_parallel_tool_use, which has no toolConfig equivalent and is accepted
alongside toolChoice. Measured against Bedrock directly: toolChoice plus
{disable_parallel_tool_use} succeeds for auto, any and tool, while an empty
tool_choice with no toolChoice is rejected for a missing type, so the type still
has to be emitted when the caller sends no tool_choice.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-04 03:50:33 +00:00