Commit graph

2911 commits

Author SHA1 Message Date
ryan-crabbe-berri
634852a183 fix(anthropic): key the /v1/messages prompt cache on Claude Code's session_id only
The bridges derived prompt_cache_key as the first 64 chars of metadata.user_id.
Claude Code packs a JSON object into that field whose prefix is the per-install
device_id, so every session and subagent on one machine shared a single key,
and a plain end-user id pinned all of that user's conversations to one slot.

Parse the JSON and use session_id; send no key otherwise so the provider falls
back to its own prompt-prefix hashing. An explicit prompt_cache_key still wins.

Fixes #39145
2026-09-08 18:06:39 -07:00
Mateo Wang
402351d980
Merge pull request #40268 from BerriAI/litellm_fireworks_responses_reasoning_instructions
fix(fireworks_ai): fold instructions and developer items into one leading system message on the Responses path
2026-09-08 17:16:52 -07:00
Mateo Wang
568c5713ef
Merge pull request #40180 from BerriAI/litellm_lit_4352_marengo_embed_3
feat(bedrock): add TwelveLabs Marengo Embed 3.0 embeddings
2026-09-08 16:38:07 -07:00
devin-ai-integration[bot]
0f886d9006
perf: move Anthropic, Vertex Anthropic, Ollama and HF template fetches off the event loop (#40311)
Direct Anthropic http image inlining, Vertex AI Anthropic forced base64 conversion, Ollama completion image download and the watsonx GPT-OSS Hugging Face chat template lookup all ran synchronous HTTP inside the async request path. Each provider config now transforms through async_inline_remote_media on the async path, the Anthropic handler awaits the config's async_transform_request before dispatch and in the Rust fallback, and watsonx text exposes async_transform_request and always awaits ahf_chat_template

Resolves LIT-7028

Co-authored-by: yassin <yassin@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-08 15:53:43 -07:00
yuneng-jiang
b8d573c5f9
Merge pull request #40203 from BerriAI/litellm_mongodb_sidecar
feat: move MongoDB vector search to an optional sidecar (BETA)
2026-09-08 15:49:24 -07:00
Yuneng Jiang
5c55ad7db0
merge: resolve MongoDB sidecar staging conflicts 2026-09-08 13:59:56 -07:00
mateo-berri
384eee26a5 fix(bedrock): reject s3 Marengo media without bucketOwner and skip items without an embedding 2026-09-08 12:53:01 -07:00
mateo-berri
cecd481ae3 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_fix_post_call_policy_pipeline 2026-09-08 12:36:13 -07:00
mateo-berri
da2e1ff619 fix(fireworks): fold system and developer items into instructions on the responses path
Fireworks renders a Responses request through a chat template that only
accepts a system message at the very beginning, so a request carrying
`instructions`, a developer item, and a replayed reasoning item (the shape
Codex CLI sends from its second prompt on) came back 400 with "System
message must be at the beginning".

The leading system or developer items, and any developer item later in
the conversation, now fold their text into top-level `instructions`,
joined with blank lines, and leave `input`. A developer item that closes
the conversation right after an assistant turn stays where it is as a
system item, as does any system or developer item with an image or file
part, so those parts still reach Fireworks. Mid-conversation system items
stay untouched. Non-string `instructions` pass through unchanged.

Folding into `instructions` rather than a leading system item keeps
`previous_response_id` chaining working, since Fireworks prepends the
stored history to `input` and a leading system item would land after it.
This supersedes the leading system item approach from deaadc21d3 and
4807630c2a on this branch. The leading and closing block rules match the
chat path change in #39852.
2026-09-08 12:12:34 -07:00
yujonglee
35d1d40a67
fix(ocr): run post-call logging hooks (#40154) 2026-09-08 12:07:25 -07:00
mateo-berri
4807630c2a fix(fireworks_ai): keep non-text system and developer parts on the folded leading system message 2026-09-08 11:48:01 -07:00
mateo-berri
deaadc21d3 fix(fireworks_ai): fold instructions and developer items into one leading system message on the Responses path 2026-09-08 11:08:03 -07:00
Yuneng Jiang
0c519b162f
fix: preserve MongoDB deadlines and secure remote sidecar transport 2026-09-07 23:43:21 -07:00
Yuneng Jiang
5c037299f4
feat: move MongoDB vector search to an optional sidecar 2026-09-07 23:02:27 -07:00
Mateo Wang
9dbfb060bd
Merge pull request #39668 from BerriAI/litellm_lit6899_vertex_batch_tuned_endpoints
fix(vertex_ai): support fine-tuned Gemini endpoints in managed batches
2026-09-07 20:28:02 -07:00
mateo
adcfe8cb7f test: pin redirected xai slugs to the target's tier field set
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-08 02:44:52 +00:00
mateo
dc035cba62 test: preserve live xai pricing invariant
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-08 02:33:04 +00:00
mateo
5cfe20a68d test: collapse blank lines left by removed tests
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-08 02:21:55 +00:00
mateo
3023497590 test: drop static cost-map value assertions
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-08 02:19:32 +00:00
mateo-berri
a601c00afd fix(bedrock): pass litellm_params into the Bedrock embedding call so drop_params reaches Marengo 3.0 2026-09-07 18:47:25 -07:00
mateo-berri
80fea089b6 fix(bedrock): reject Marengo 2.7-only and misplaced media params on 3.0 unless drop_params
Marengo 3.0 requests now get a 400 naming any textTruncate, lengthSec,
useFixedLengthSec, or minClipSec parameter, and any video or audio option
sent with a text, image, text_image, or multi_input request, instead of
silently dropping them. drop_params (global, per deployment, or per
request) drops them instead. Pydantic validation errors name the field
and the reason, and the 3.0 marker is the exact "marengo-embed-3-" model
id segment.
2026-09-07 18:40:31 -07:00
mateo-berri
86790a7723 fix(bedrock): bill Marengo embeddings per request instead of per estimated token
AWS prices Marengo 2.7 and 3.0 text and image embeddings per request, never per
token, and their responses carry no token count. The old transform estimated
prompt tokens from the vector length, which billed a text request at 128 tokens
times the per-token rate (0.00896 instead of 0.00007). Marengo responses now
report zero tokens with query_count and image_count derived from the request
batch, and all six Marengo cost-map entries price per request (with the video
and audio per-second and per-image rates on the base entries). query_count is a
new prompt_tokens_details field wired to input_cost_per_query in the cost
calculator.
2026-09-07 18:20:28 -07:00
tin-berri
7da6fe54b5
fix: skip one-shot Claude Code cache injection (#40175) 2026-09-07 18:03:43 -07:00
mateo-berri
dc09d9e7cf feat(bedrock): add TwelveLabs Marengo Embed 3.0 embeddings 2026-09-07 17:24:17 -07:00
mateo-berri
0d5ea553da Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_fix_post_call_policy_pipeline 2026-09-07 17:24:10 -07:00
yucheng-berri
1009976c49
fix(bedrock): keep x-amzn-RequestId on chat error responses (#40089)
* fix(bedrock): keep x-amzn-RequestId on chat error responses

Bedrock chat error paths built BedrockError from only a status code and a
message, so the provider response headers were gone before exception mapping
ran and the proxy had nothing to forward. AWS support needs x-amzn-RequestId
to investigate a server-side error.

- converse and invoke chat handlers pass the real headers and response when
  they turn an httpx.HTTPStatusError into a BedrockError, and read the body
  through error_response_text so a streamed body nobody read does not throw
- every bedrock chat get_error_class honors the headers it is already handed:
  invoke, moonshot, bedrock-hosted openai, agentcore and the invoke agent
- BedrockError carries those headers into the response it synthesizes when a
  caller has headers but no response, skipping values httpx cannot carry
- the bedrock 500 mapping forwards the provider response like its 4xx and 503
  siblings instead of fabricating a blank one

The proxy now returns llm_provider-x-amzn-requestid on Bedrock chat errors.

* fix(bedrock): keep request-id on text-classified errors

The context-window and image branches of _map_bedrock_exception built their
litellm exception without the provider response, so a Bedrock 400 classified
by its body text lost x-amzn-RequestId while the sibling branches kept it.

Also narrows the new BedrockError types and trims its docstrings.

* chore(bedrock): drop the docstrings on the new error helpers

* fix(bedrock): keep request-id on every error path that has one

The ticket's root cause is that every BedrockError raise site under
litellm/llms/bedrock/ was built from status and message alone. The first
commits covered the chat and invoke handlers; this covers the rest.

Embeddings, rerank, image generation, image edit, count tokens, search and
the transformation layers now hand on the provider response or its headers,
and both bedrock_mantle configs return a BedrockError instead of the
OpenAI error that drops them.

Two blockers surfaced while verifying the streaming path. The trailing
`except Exception` in make_call and make_sync_call swallowed the BedrockError
raised a few lines above, relabelling a provider status as a 500, and the
non-200 branch read an unread streamed body, which throws.

The raise sites left alone have no provider response to carry: timeouts,
credential and config errors, and mid-stream event frames.

* fix(bedrock): forward provider headers from the count tokens route

The count tokens route converts BedrockError into an HTTPException, and dropped
the headers the handler had just kept, so that route still lost the request id.

get_response_headers now takes a Mapping so an httpx.Headers can be handed to it
without a copy.

* fix(bedrock): classify every bedrock surface through BedrockError

Eleven bedrock configs still inherited a provider-agnostic get_error_class
that builds a blank response, so the request id was gone before the proxy
read it. Claude platform, bedrock anthropic-messages, both image edit
configs, passthrough, realtime, vector stores and agentcore search now
return BedrockError, and a parametrized audit drives all 36 configs.

* fix(proxy): keep provider headers on the httpx status error branch

_handle_llm_api_exception forwards safe_headers on every branch except the
httpx.HTTPStatusError one, which the bedrock passthrough route reaches, so
the request id was dropped before the client saw the response.

* fix(bedrock): keep the request id on the timeout mappings

Timeout takes no response argument, so the three bedrock timeout branches
dropped the provider headers even when the upstream answered 408 or 504
with an x-amzn-RequestId. They now ride on the exception, already
llm_provider-prefixed, which is the form the proxy emits.

* fix(bedrock): keep the provider response on mapped timeouts

The previous round attached llm_provider-prefixed headers directly to the
Timeout. That shadowed the raw upstream headers for _get_response_headers,
so router cooldown and fallback cooldown stopped honouring retry-after on
bedrock 408/504 replies.

Give Timeout an optional response instead, the way every other mapped
bedrock exception already carries one. Retry logic reads the raw
retry-after off the response, and the proxy prefixes those headers on the
way out, so clients still see llm_provider-x-amzn-requestid.

* chore(bedrock): drop the explanatory comment on Timeout.response
2026-09-07 17:16:47 -07:00
mateo-berri
18aa52d5e1 chore: merge litellm_internal_staging into litellm_lit_6348_fireworks_responses_api 2026-09-07 15:43:08 -07:00
Mateo Wang
d0dd3ce2d8
Merge pull request #38869 from BerriAI/litellm_fix_guardrail_route_call_types
fix(guardrails): resolve generateContent routes and async-first passthrough call types
2026-09-07 15:15:51 -07:00
Mateo Wang
9eaf15bcf9
Merge pull request #38842 from BerriAI/litellm_fix_responses_reasoning_drop_params
fix(responses): drop unsupported reasoning param for openai non-reasoning models
2026-09-07 15:14:13 -07:00
Yassin Kortam
192e38fa7b
feat(skills): semantic search over the LiteLLM-hosted skill registry (#39401)
* feat(skills): semantic search over the LiteLLM-hosted skill registry

Adds GET /v1/skills?query= (custom_llm_provider=litellm_proxy) and a
skill_search MCP virtual tool, ranking the caller's accessible skills by
semantic similarity, mirroring the A2A agent registry search (LIT-6309).

Also fixes a pre-existing bug where create_skill() dropped description and
instructions for the litellm_proxy provider, which left every LiteLLM-hosted
skill with no searchable text.

* fix(mcp): coerce skill_search top_k instead of raising 500 on malformed input

The MCP-REST skill_search dispatch validated raw tool arguments through a
pydantic model directly, so a non-numeric top_k raised a ValidationError
that the endpoint's catch-all turned into an HTTP 500. Mirrors the
agent_search branch's tolerant coerce_top_k handling instead.

* fix(skills): enforce key limits on search embeddings and bound the semantic index

Semantic search embeddings now run the same pre_call_hook the /embeddings
route runs, so key rate limits, budgets and guardrails apply before the
embedding model is called. The shared SemanticTextIndex caps cached vectors
and evicts the least recently searched entries, and each skill's embedded
text is capped so one skill cannot inflate the embedding batch

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

* fix(skills): surface proxy 429s from search embeddings instead of a 503

ProxyRateLimitError is also an OpenAIError, so the search engine was folding
a key rate limit into skill_search_unavailable. Proxy HTTPExceptions now
propagate so the caller gets the same 429 the /embeddings route returns

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

* fix(skills): import assert_never from typing_extensions for Python 3.10

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

* fix(skills): embed the request as the pre-call hooks returned it, not the original text

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

* refactor(skills): keep the litellm_proxy provider check for GET /v1/skills?query= inside llms/

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

* test(skills): move the GET /v1/skills?query= endpoint tests under tests/test_litellm/proxy

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-07 12:28:38 -07:00
Mateo Wang
9700f666d0
Merge pull request #39839 from BerriAI/litellm_async_remote_image_fetch
fix(async): move remote image fetches off the event loop for Snowflake, Bedrock invoke Claude, Mantle and Gemini
2026-09-07 10:55:04 -07:00
Mateo Wang
a9556c7bad
Merge pull request #39965 from BerriAI/litellm_fix_oci_cohere_stream_tool_turn_dup
fix(oci): stream Cohere tool-calling answers once
2026-09-07 10:54:59 -07:00
yujonglee
217cb12623
refactor(rust): remove per-request enablement arguments (#39928)
* refactor(rust): remove per-request enablement arguments

* fix(rust): remove ignored transcription enablement

* refactor(rust): remove OCR-specific bridge controls
2026-09-07 10:43:45 -07:00
mateo-berri
5825cc7593 chore: merge litellm_internal_staging into litellm_mistral_voxtral_tts_speech
Some checks failed
LiteLLM Rust / rustfmt, clippy, test (push) Has been cancelled
LiteLLM Rust / release wheel (push) Has been cancelled
Terraform Modules / fmt, validate, test (aws) (push) Has been cancelled
Terraform Modules / fmt, validate, test (gcp) (push) Has been cancelled
2026-09-06 03:24:55 -07:00
Mateo Wang
02522a5441
Merge pull request #39983 from BerriAI/litellm_lit_7081_azure_ai_gpt_6_astra_pricing
feat(cost-map): add azure_ai/gpt-6-astra Foundry pricing
2026-09-06 01:27:22 -07:00
Mateo Wang
4104868458
Merge pull request #39723 from Atharva-Kanherkar/fix/anthropic-responses-refusal-translation
Some checks failed
Unit Tests / misc (push) Waiting to run
Unit Tests: Proxy DB Operations / budgets (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / custom-logging (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / db-and-spend (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / endpoints-and-responses (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / guardrails-hooks (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / jwt-and-keys (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / key-generation (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / logging-misc (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / proxy-runtime (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / proxy-server-core (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / proxy-utils (push) Blocked by required conditions
Unit Tests / caching-local (push) Waiting to run
Unit Tests / core-utils (push) Waiting to run
Unit Tests / enterprise-package (push) Waiting to run
Unit Tests / enterprise-routing (push) Waiting to run
Unit Tests / integrations (push) Waiting to run
Unit Tests / All Other Providers (push) Waiting to run
Unit Tests / Vertex AI (push) Waiting to run
Unit Tests / proxy-endpoints (push) Waiting to run
Unit Tests / proxy-extras (push) Waiting to run
Unit Tests / proxy-infra (push) Waiting to run
Unit Tests / proxy-auth (push) Waiting to run
Unit Tests / proxy-server (push) Waiting to run
Unit Tests / responses-caching-types (push) Waiting to run
GitHub Actions Security Analysis / zizmor (push) Waiting to run
LiteLLM Rust / release wheel (push) Has been cancelled
Terraform Modules / fmt, validate, test (aws) (push) Has been cancelled
LiteLLM Rust / rustfmt, clippy, test (push) Has been cancelled
Terraform Modules / fmt, validate, test (gcp) (push) Has been cancelled
fix(anthropic_responses): preserve Responses refusal blocks in Anthropic messages translation
2026-09-06 00:03:06 -07:00
mateo-berri
05cba21763 fix(anthropic): split refusal off a combined finish_reason chunk
A fake-streamed provider hands the adapter one chunk carrying both the
delta payload and the finish_reason, which is exactly what the combined
chunk splitter exists for, but its content check never listed the refusal.
The translation short-circuits on finish_reason, so that refusal text was
dropped and the client got `stop_reason: refusal` over an empty content
array, the symptom this PR set out to fix.

Both refusal accumulators also drop their `mutable-ok` lists for a plain
string attribute
2026-09-05 23:40:20 -07:00
mateo-berri
c09d34fc4b fix(anthropic): stream refusals parked in provider_specific_fields
The first-delta guard read `delta.refusal` directly, while the translation
three lines later goes through `openai_chat_refusal_text`, which also reads
the `provider_specific_fields` LiteLLM parks unrecognized fields in. A
provider that sends the refusal that way had its only refusal delta skipped
as blank, so the client got `stop_reason: refusal` over an empty content
array, which is the symptom this PR set out to fix
2026-09-05 23:20:19 -07:00
mateo-berri
fffe0bb0dc test(azure_ai): pin the tier the messages bridge sends when astra refuses max
The /v1/messages adapter lowers a tier the entry does not accept, so dropping max from the astra
rows moves that path from Foundry's 400 to a request at xhigh. Nothing pinned that, and the guard
test's docstring named gpt-6-astra as the only gpt-5 name with an azure_ai row, which 11 rows
contradict.
2026-09-05 23:18:25 -07:00
Mateo Wang
0318b4acdc
Merge pull request #30856 from emerzon/litellm_vertex_lyria_models
feat(vertex): add Lyria model support
2026-09-05 23:12:25 -07:00
mateo-berri
02b44820c4 test(vertex_ai): keep imagen predict passthrough off the Lyria audio path
The new Lyria passthrough branch runs before the image-generation branch
and keys on the same `predictions[0].bytesBase64Encoded` shape imagen
returns, so only the cost-map lookup separates them. Cover an imagen
predict response end to end so a future change that drops that lookup
fails here instead of misbilling images as audio.
2026-09-05 22:59:57 -07:00
mateo-berri
6be78fa850 fix(vertex_ai): bill Lyria per generation, not per audio second
Google prices Lyria per generated clip, so every Vertex Lyria entry in the
price map now carries a single output_cost_per_image and both the speech
and the passthrough cost paths read that one field. The old
output_cost_per_second and audio_seconds_per_prediction pair assumed a
30 second clip, which does not match the 32.768 second WAV Vertex returns,
and no other model in the map priced audio that way

Drops max_audio_length_hours and max_audio_per_prompt from the price map,
its schema, the generator, and ModelInfo, since nothing reads them, and
drops the audio_mime_type hidden param for the same reason: the response
already carries the resolved content type on its own header

Folds the per-model bundled catalog lookups into one cached parse of the
local cost map, validated with a TypeAdapter over a ReadOnly TypedDict
2026-09-05 22:34:31 -07:00
mateo-berri
fa2b64878b fix(azure_ai): redirect a gpt-5 capability lookup only when the map has a foundry row
gpt-6-astra is the only gpt-5-family name with an azure_ai row. Prefixing the rest
cost them every effort flag, since get_llm_provider sends an azure_ai name down the
azure provider when a global AZURE_AI_API_BASE points at an openai.azure.com host and
azure/<model> is not a key either, which turned temperature, top_p and logprobs on
azure_ai/gpt-5.1-chat-latest from accepted into an UnsupportedParamsError.
2026-09-05 22:31:33 -07:00
Emerson Gomes
fd24cce2c3
test(vertex): isolate Lyria fallback from the remote catalog 2026-09-06 00:15:08 -05:00
Emerson Gomes
82edb9e901
fix(vertex): preserve Lyria pricing fallback and audio MIME 2026-09-06 00:09:27 -05:00
mateo-berri
79d47788d9 fix(anthropic): stream the refusal text on bridged /v1/messages calls
Both bridges opened an empty text block on a refused streaming turn and
closed it without a single delta, so a client replaying that assistant
turn got HTTP 400 "text content blocks must be non-empty" from Anthropic.
The safeguard-refusal fallback that motivated withholding the text only
runs on the awaited non-streaming response, so nothing needed it withheld

Move the refusal readers into the shared messages/utils helpers so the
adapters stop reaching into each other's private statics, which is also
what put reportPrivateUsage over its budget
2026-09-05 20:56:39 -07:00
mateo-berri
a17fcecf70 refactor(azure_ai): type the Foundry param mapping override and drop test docstrings
The AzureAIStudioConfig.map_openai_params override now carries dict[str, object]
annotations instead of bare dict, and the docstrings added to the new tests go away
since the test names already say what they cover. No behavior change
2026-09-05 19:21:34 -07:00
mateo-berri
15372967c6 fix(azure_ai): read the azure_ai card for gpt-5 series reasoning effort gates
Foundry deployments of gpt-6-astra reached through azure_ai used the bare OpenAI card
for the reasoning_effort none gates, so temperature and top_p were refused while the
azure_ai card says none is supported. AzureAIStudioConfig now dispatches gpt-5 series
params through AzureAIGPT5Config, which looks capabilities up under the azure_ai/
prefix the way the azure route does

Also carries the search_context_cost_per_query block azure/gpt-6-astra has, adds a
flex service tier cost test that fails at the merge base, and keeps the wildcard test
from stripping azure_ai/gpt-6-astra out of the provider set
2026-09-05 19:06:38 -07:00
mateo-berri
d748cf40b7 fix(responses): only drop reasoning when it carries an effort and let an explicit map flag win
Some checks failed
LiteLLM Rust / rustfmt, clippy, test (push) Has been cancelled
LiteLLM Rust / release wheel (push) Has been cancelled
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
2026-09-05 18:53:37 -07:00
tin-berri
01680d7b42
fix(anthropic): keep provider_specific_fields off the native /v1/messages wire (#39967)
The chat and Responses bridges serialize tool_use blocks with model_dump(), so every
bridged /v1/messages response carried LiteLLM's internal provider_specific_fields key
(null, or a Gemini thought signature). Clients replay the block verbatim, and the next
turn that lands on a native Anthropic deployment (auto-router tier change, model swap)
is rejected with "tool_use.provider_specific_fields: Extra inputs are not permitted"

Strip the key from replayed content blocks at the single native Anthropic dispatch so
already-poisoned transcripts self-heal on every native provider, and stop emitting the
null on new responses. The bridges keep reading the signature for the Gemini round trip

Closes #19739
2026-09-05 17:50:54 -07:00