The proxy stores both fields with a whole-row read-modify-write of
general_settings, so two concurrent writes from one save can drop one
of them. Also drops docstrings and suppressions the diff did not need
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Adds POST /management/v1/teams/{team_id}/members/bulk_update, a merge patch
over per-member limits (max_budget_in_team, tpm_limit, rpm_limit,
budget_duration, allowed_models) for up to 500 members in one transaction.
Editing a team's default member budget has never reached members who already
have a budget row, because /team/member_add clones the default per member.
This gives admins one call to roll a new cap out across the roster, and each
result carries max_budget_source so a caller can see whether a member is on
their own cap or on the team default.
Reads run on the writer inside the batch transaction, and any budget row more
than one membership points at is cloned before it is written, so raising one
member's cap never moves another's.
A service-account key can now carry end_user_budget_id in its metadata. When a request through that key names a customer that does not exist yet, the key's budget is applied to the new customer from the first request and wins over the proxy-wide max_end_user_budget_id. A customer with an explicitly assigned budget keeps it. The Admin UI exposes the setting on service-account key creation and key edit, and only proxy admins may set or clear it.
Resolves LIT-7996
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Adds temp_budget_increase and temp_budget_expiry to the team member edit form with pair validation,
seeds stored values into edit mode, sends both through /team/member_update, and adds cached-key auth
and reservation regression tests for active and expired increases
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Adds the mcp_allowed_clients general setting, enforced against the
clientInfo.name each MCP client sends in its initialize request. A client
not on the list, or one that does not identify itself, is rejected with
403 before any stateful session is created. The setting is configurable
from config.yaml and from the Admin UI MCP network settings page
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
A blocked source, or source and username pair, is now refused with 429 before the database lookup and password check, in place of the soft block that held wrong guesses for 30 seconds and let a correct password through. The env admin credentials and the master key typed into the login form are refused like any other credential while blocked; recovery is the master key as an API bearer token, which never goes through the sign-in path
trusted_proxy_ranges: [] now means clients connect directly, so the peer address is the source and the per-source limit stays on. Only an unset or malformed value leaves the topology unknown, warns at startup and turns the per-source limit off
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Adds /azure_speech/{endpoint:path}, an authenticated pass-through for the Azure AI Speech REST APIs: short-audio recognition on <region>.stt.speech.microsoft.com and batch transcription on <region>.api.cognitive.microsoft.com. The proxy resolves the subscription key through PassthroughEndpointRouter (AZURE_SPEECH_API_KEY or an Admin UI credential), picks the host from AZURE_SPEECH_REGION or AZURE_SPEECH_API_BASE, injects Ocp-Apim-Subscription-Key, strips the caller's Authorization and subscription-key headers, forwards the raw audio body byte for byte, and records a zero-cost SpendLogs row tagged azure_speech since the price map has no Azure Speech STT entry
Resolves LIT-7939
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Adds both fields to the team admin editable allow-list and the dashboard's team admin form. The existing budget authority check still stops a team admin from raising or removing a standalone team's budget.
Keep /projects list paging as a pushed history entry, validate the
project key table page size against its offered options, and clear the
key table params through the table-state setters instead of a copied
key list.