Registering the five managed-batch fields in all_litellm_params stops them leaking into
extra_body, but two of them never reached the transformation that reads them.
CredentialLiteLLMParams is a whitelist, so get_deployment_credentials_with_provider
round-tripped the deployment and silently dropped s3_output_bucket_name and bedrock_tags
before the files/batch/passthrough callers saw them. s3_bucket_name, s3_region_name and
aws_batch_role_arn were added to that model for #25104; these two are the remainder of
the same deployment config
bedrock_tags is typed as a plain list rather than a stricter shape so a malformed value
still reaches _validate_bedrock_tags and gets its own error message instead of a Pydantic
one
The preservation assertion previously round-tripped through GenericLiteLLMParams, which is
extra="allow" and would hold even for a field nothing declares. It now also reproduces the
CredentialLiteLLMParams normalization the proxy actually performs, and fails naming
exactly the dropped fields without this change
A Bedrock managed-batch deployment carries aws_batch_role_arn, s3_bucket_name,
s3_region_name, s3_output_bucket_name and bedrock_tags in its litellm_params,
and the batch and files transformations read all five from there. None was
registered in all_litellm_params, so the param builder swept them into
extra_body on every other route that deployment serves: Bedrock answers
"aws_batch_role_arn: Extra inputs are not permitted" on Anthropic models and
"extraneous key [aws_batch_role_arn] is not permitted" on Nova, Llama and
Titan, so configuring batch turns every chat and embedding request to that
model into a 400.
Register them alongside the agentic-loop and callback-credential fields, which
are listed for exactly this reason. The batch path is unaffected because
GenericLiteLLMParams is extra="allow" and preserves them into litellm_params
for the transformations that consume them.
Before this, batch could only be configured on a deployment dedicated to
batch; the same model group could not serve both.
The Global Control Plane (formerly documented as the HA Control Plane) is
documented as an Enterprise feature, but `worker_registry` carried no premium
check, so any OSS install could run one. Gate it at config load, matching the
`enforced_params` precedent, and fail startup rather than ignoring the registry
silently: a silently dropped registry degrades a control plane into an ordinary
proxy with no signal to the operator.
Also declare `worker_registry` and `general_settings.control_plane_url`, both
load bearing today and neither previously declared, so they appear in the
generated config schema.
Google's Gemini deprecations page lists no shutdown date for the 2.5 GA models and May 14, 2028 for gemini-embedding-001; keep only the DeepSeek V4 max output correction.
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix(proxy): requeue spend logs when the DB write fails with a transport error
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix(proxy): hardcode the spend log queue cap and drop the stale re-export
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* refactor(proxy): keep the spend log requeue within the type discipline budget
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix(proxy): apply the spend log queue cap to producer appends too
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix(proxy): lower the spend log queue cap to 1k and make it env configurable
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix(proxy): bound the spend log queue by bytes instead of row count
A row cap cannot bound memory: a row carries the whole prompt under store_prompts_in_spend_logs, so a cap that rides out an outage of counter-only rows is an OOM once prompts are stored. Every enqueue and dequeue now goes through one pair that tracks what the queue costs and drops the oldest rows past a 64 MB budget.
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix(proxy): make the spend log queue byte budget env configurable
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix(proxy): use a string default for the spend log queue byte budget env read
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix(proxy): make the spend log queue byte total a public attribute
The queue it accounts for is already public, and a private name only bought reportPrivateUsage errors at every call site.
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>
Co-authored-by: shivam <shivam@berri.ai>
Dropping it falls back to the public cost map's tier table, whose rates outrank the
zeros written beside them, so a PTU deployment on a tiered model keeps billing its
traffic per token. Stored empty, the tiers no longer apply and the zeros win
tiered_pricing is a list, so the 0.0 the flat-rate zeroing stores does not
even validate. Supplying tiers alongside PTU config gets the same 400 as a
flat rate; tiers already stored are dropped from both blobs
parse_prompt_tokens_details and parse_completion_tokens_details are imported
by four modules, so the leading underscore made every import a
reportPrivateUsage violation
The previous assertion read data-chips, which is derived from the anchor prop
being truthy, so it stayed true even when the ref never reached the DOM and the
popup was still anchored to the inner input.
Stub distinct widths on the chips container and the input, then read the width
the positioner resolved. Reverting the anchor wiring now reports the input's
width instead of the field's, which is the actual bug.
Base UI positions a combobox popup against the Combobox.Input by default. In
chips mode the visible field is the ComboboxChips wrapper and the input is a
smaller box nested inside it, so every chips-combobox in the dashboard opened
its popup 11px right of the field and 17px past its right edge.
shadcn ships the wiring for this and their combobox-multiple example uses it:
useComboboxAnchor on the chips container, passed to ComboboxContent as anchor.
The anchor prop also drives data-chips, which cancels the extra min-width an
ordinary combobox wants. Every chips site in the dashboard omitted it.
The anchor is attached through Base UI's render prop rather than a plain ref,
because React 18 drops refs on function components and ComboboxChips is one.
Adds MultiSelect's first test, covering the anchor wiring plus selection,
chip rendering and custom values.
Images nested inside an Anthropic `tool_result` block were dropped when the
request was adapted for an OpenAI-compatible provider, because the OpenAI tool
message shape only carried text. Hoist those images out of the tool result and
into a following user message so the model can still see them, and widen the
tool message content type to accept image parts.
The tab strip carried overflow-x-auto directly on the TabsList. CSS forces
overflow-y from visible to auto once overflow-x is not visible, and the line
variant's active-tab underline is an absolutely positioned ::after that hangs
5px below its trigger, so the strip picked up a pixel of vertical scroll on top
of the horizontal scroll it actually wants.
The scroll container now lives on a wrapper whose bottom padding leaves room for
the underline, offset by a matching negative margin so the row keeps its exact
geometry.
Three assertions in LogDetailContent.test.tsx matched a regex against the
rendered class string to prove a tag was green or was not red. That pins styling
rather than behavior, and jsdom does not resolve the utilities anyway, so the
checks only ever proved that a substring survived into the class attribute
The badge re-sync exposed it: base-vega's base string carries aria-invalid
variants of the destructive token, so a "not destructive" regex started matching
every badge regardless of variant
Each one now asserts the tag's text is present, which is what the surrounding
cases already do and what the user actually observes
components.json has declared "style": "base-vega" since cfe9e39e55, but badge
and skeleton were added a few days earlier under new-york and never re-synced,
so both still carried the previous style's classes. Badge's destructive variant
rendered as solid red with white text instead of the tinted wash the rest of the
dashboard uses, which is already the convention for Button
Re-runs npx shadcn add for both and keeps the two local deltas the registry
cannot supply: cva comes from @/lib/cva.config, since class-variance-authority
is not a dependency here, and both stay wrapped in React.forwardRef, which the
tripwire in tests/setupTests.ts requires until the React 19 upgrade
Adds Badge to ref-forwarding.test.tsx. Nothing covered it before, even though
two TooltipTrigger sites compose over it, so the wrapper could have been dropped
by the next re-sync without a single test going red
Retargets one assertion in LogDetailContent.test.tsx. It regex-matched the whole
class string for "destructive" to prove a tag was not alarming red, which the
restored aria-invalid classes now satisfy for every variant; it checks the
variant attribute and red utility classes instead