Forking a shared budget row rebuilt budget_reset_at from the duration, so editing
an unrelated limit restarted the member's window while their spend carried over:
a tpm bump quietly handed them a fresh period. The fork now inherits the source
row's deadline, and only recomputes when the patch actually sets budget_duration.
The bulk member budget route now writes one audit entry per call, a team-scoped
'updated' row carrying every written member's limits before and after, matching
what /team/member_add already records for membership changes. It honors the
litellm-changed-by header like the other audited team routes.
The chat route handed the registry's stored headers dict straight to validate_environment, which wrote the caller's bearer into it, so the next caller of the same agent with no key of their own sent the previous caller's token. The registry lookup now copies the stored headers and validate_environment returns a new dict instead of mutating its input. A regression test drives two completions through one registered agent and asserts the second carries no Authorization and the stored agent is unchanged.
Virtual-hosted URLs for bucket names containing dots fail TLS verification, so the
media duration fetch failed and completed jobs were charged the eight hour maximum
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Keeps this branch scoped to running the prompt injection heuristics off the event loop
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Log the underlying ImportError server side and send the client only the installed
version, the supported range and the install hint
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Amazon Transcribe bills every second of the media file, silence included, while the
transcript's last end_time stops at the last word, so pricing from the transcript
undercharged. After a job completes, download Media.MediaFileUri from S3 with the
proxy's credentials and read its length with libsndfile. Formats libsndfile cannot
read (mp4, m4a, webm, amr) and custom language models under LanguageIdSettings are
refused before signing. The S3 signature is only sent to hosts in the AWS partition
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
The roster the authorization check reads came from the routed reader, so a
replica lagging behind a team-admin demotion could still grant that caller
member-budget writes. Pin that read to the writer, as the model reconcile does.
A budget_duration the reset job can never schedule from, a non-positive one
that leaves the row permanently due or an unparseable one that blew up mid
batch as a 500, is now a 422 naming the row it came from, with nothing written.
The check is the same one /team/member_update and /budget/new already run,
lifted out of validate_budget_duration so both surfaces share it.
Custom auth callables that already capped an end user keep their cap; the key
default fills only unset limits. The proxy-wide default still reaches an
uncapped custom-auth token, and the missing-budget log strips line breaks
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>