Merge pull request #40632 from BerriAI/litellm_fix_ui_disable_cache_control_injection_points

fix(ui): persist disabling cache control injection points on model update
This commit is contained in:
ryan-crabbe-berri 2026-09-17 17:35:07 -07:00 • committed by GitHub
commit 03ba5634a2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 56 additions and 3 deletions

View file

@ -144,6 +144,8 @@ if TYPE_CHECKING:
from prisma import types as prisma_types
router: Final = APIRouter()
CLEARABLE_LITELLM_PARAMS: Final = frozenset({"cache_control_injection_points"})
NULL_CLEARABLE_LITELLM_PARAMS: Final = frozenset((*SPECIAL_MODEL_INFO_PARAMS, *CLEARABLE_LITELLM_PARAMS))
async def update_team(*args, **kwargs):
@ -898,7 +900,7 @@ def update_db_model(db_model: Deployment, updated_patch: updateDeployment) -> Pr
# clear propagates to both blobs.
if updated_patch.litellm_params:
for field in updated_patch.litellm_params.model_fields_set:
if field in SPECIAL_MODEL_INFO_PARAMS and getattr(updated_patch.litellm_params, field) is None:
if getattr(updated_patch.litellm_params, field) is None and field in NULL_CLEARABLE_LITELLM_PARAMS:
merged_litellm_params.pop(field, None)
merged_model_info.pop(field, None)
elif (

View file

@ -3864,6 +3864,54 @@ class TestModelInfoServerDerivedPricingFilter:
assert written["access_groups"] == ["prod"]
class TestUpdateDBModelClearCacheControlInjectionPoints:
def test_explicit_null_removes_stored_injection_points(self):
from litellm.proxy.management_endpoints.model_management_endpoints import (
update_db_model,
)
from litellm.types.router import LiteLLM_Params, ModelInfo, updateLiteLLMParams
db_model = Deployment(
model_name="haiku-cached",
litellm_params=LiteLLM_Params(
model="anthropic/claude-haiku-4-5",
cache_control_injection_points=[{"location": "message", "role": "system"}],
),
model_info=ModelInfo(id="dep-cache-0"),
)
patch = updateDeployment(
litellm_params=updateLiteLLMParams(cache_control_injection_points=None)
)
result = update_db_model(db_model=db_model, updated_patch=patch)
params = json.loads(result["litellm_params"])
assert "cache_control_injection_points" not in params
assert params["model"] == "anthropic/claude-haiku-4-5"
def test_omitted_key_keeps_stored_injection_points(self):
from litellm.proxy.management_endpoints.model_management_endpoints import (
update_db_model,
)
from litellm.types.router import LiteLLM_Params, ModelInfo, updateLiteLLMParams
db_model = Deployment(
model_name="haiku-cached",
litellm_params=LiteLLM_Params(
model="anthropic/claude-haiku-4-5",
cache_control_injection_points=[{"location": "message", "role": "system"}],
),
model_info=ModelInfo(id="dep-cache-0"),
)
patch = updateDeployment(litellm_params=updateLiteLLMParams(tpm=10))
result = update_db_model(db_model=db_model, updated_patch=patch)
params = json.loads(result["litellm_params"])
assert params["cache_control_injection_points"] == [{"location": "message", "role": "system"}]
assert params["tpm"] == 10
class TestGetModelInfoWithIdBlocked:
"""`ProxyConfig.get_model_info_with_id` must propagate the DB-level `blocked`
column into the in-memory `model_info` dict so the router filter can read it."""

View file

@ -1785,7 +1785,7 @@ describe("ModelInfoView", () => {
expect(payload.litellm_params.cache_control_injection_points).toEqual([{ location: "message", role: "user" }]);
});
it("drops the stored injection points when the operator turns the toggle off", async () => {
it("sends an explicit null when the operator turns the toggle off so the backend clears the stored points", async () => {
withCachePoints([{ location: "message", role: "user" }]);
const user = userEvent.setup();
await enterEditMode(user);
@ -1793,7 +1793,7 @@ describe("ModelInfoView", () => {
await user.click(screen.getByRole("switch"));
const payload = await save(user);
expect(payload.litellm_params).not.toHaveProperty("cache_control_injection_points");
expect(payload.litellm_params.cache_control_injection_points).toBeNull();
});
it("adds a typed index as a string, matching what the deployment already stores", async () => {

View file

@ -352,8 +352,11 @@ export default function ModelInfoView({
}
// Handle cache control settings
const hadInjectionPoints = Boolean(localModelData?.litellm_params?.cache_control_injection_points);
if (values.cache_control && (values.cache_control_injection_points?.length ?? 0) > 0) {
updatedLitellmParams.cache_control_injection_points = values.cache_control_injection_points;
} else if (hadInjectionPoints) {
updatedLitellmParams.cache_control_injection_points = null;
} else {
delete updatedLitellmParams.cache_control_injection_points;
}