Skip to content

chore(release): cherry-pick #28284 and #28683 into patch/1.86.0 - #28731

Merged
yuneng-berri merged 2 commits into
patch/1.86.0from
litellm_/nice-gates-04f540
May 24, 2026
Merged

chore(release): cherry-pick #28284 and #28683 into patch/1.86.0#28731
yuneng-berri merged 2 commits into
patch/1.86.0from
litellm_/nice-gates-04f540

Conversation

@yuneng-berri

Copy link
Copy Markdown
Collaborator

Summary

Cherry-picks onto patch/1.86.0 for the 1.86.0 stable release.

Test plan

  • CI green on patch/1.86.0

yuneng-berri and others added 2 commits May 23, 2026 18:12
* fix(proxy): hydrate wildcard discovery credentials

* fix(proxy): constrain wildcard credential hydration

Co-authored-by: Dibyo Mukherjee <dibyo@adobe.com>
(cherry picked from commit 37ef8d9)
…8683)

* fix(team): refresh team cache on team_model_add/delete (LIT-3244)

team_model_add and team_model_delete wrote to the DB but did not
invalidate the in-memory LiteLLM_TeamTableCachedObj used by
common_checks. After the v1.83.14 common_checks centralization made
team.models authoritative on /v1/files and /v1/vector_stores/*,
adding a Team-BYOK model silently failed to grant the new public
model name to team members until the cache TTL expired (and a
removed model kept working until then on the symmetric path).

Extract the cache-refresh snippet from update_team into a small
helper and apply it consistently at all three team-write sites.

* test: also assert updated models in team-cache-refresh pin

Strengthens the LIT-3244 regression test to also assert
`call_kwargs["team_table"].models` matches the updated row,
not just `team_id`. Both `existing_team` and `updated_team`
share `team_id` in the test setup, so the previous assertion
would have passed even if the implementation accidentally cached
the pre-mutation row.

Greptile review feedback.

* fix(team): hydrate object_permission on cache-refreshing team updates

The Prisma update calls in update_team, team_model_add, and
team_model_delete returned a team row with object_permission_id set
but object_permission=None (the relation was not requested via
include=). _refresh_cached_team then wrote that to the in-memory
LiteLLM_TeamTableCachedObj, and the cache-hit path in get_team_object
returns the cached object without re-hydrating. Downstream consumers
(validate_key_search_tools_against_team, the MCP/agent authz paths)
treat a missing object_permission as no team-level restriction, so
a team-write op silently dropped object-permission enforcement until
the cache TTL expired or a DB-fetch path re-hydrated it.

Add include={"object_permission": True} to all three updates so the
refresh writes a complete cached team. Extend the LIT-3244 regression
test to pin both the cached object_permission and the include shape
on the Prisma call.

Surfaced in PR review of LIT-3244.

(cherry picked from commit 5f73ad4)
@codecov

codecov Bot commented May 24, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 36.00000% with 16 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
litellm/proxy/auth/model_checks.py 47.05% 9 Missing ⚠️
...tellm/proxy/management_endpoints/team_endpoints.py 14.28% 6 Missing ⚠️
litellm/proxy/utils.py 0.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@greptile-apps

greptile-apps Bot commented May 24, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This cherry-pick combines two bug fixes for the 1.86.0 patch release: wildcard credential hydration for BYOK discovery routes, and team cache staleness after team_model_add/team_model_delete mutations.

  • Credential hydration (model_checks.py, utils.py): _hydrate_litellm_credential_name resolves a litellm_credential_name reference into concrete API credentials before calling get_provider_models, so team-scoped BYOK wildcard deployments return the correct model list. team_id is threaded from get_available_models_for_user down to llm_router.get_model_list so the router picks the right team-scoped deployment.
  • Team cache refresh (team_endpoints.py): _refresh_cached_team wraps _cache_team_object and is now called after every litellm_teamtable mutation. The Prisma update for team_model_add/delete now includes object_permission so the refreshed cached object retains the team's search-tool allowlist.

Confidence Score: 4/5

The core production changes are correct: credentials are hydrated before wildcard discovery and the team cache is refreshed consistently after DB writes.

Both fixes are well-motivated and the new code paths are covered by focused mock tests. The _hydrate_litellm_credential_name function correctly copies params before mutating and guards against missing credentials. The _refresh_cached_team helper correctly uses the Prisma row returned by the update. The parametrized regression test for team_model_delete asserts a model list that only makes sense for the add case — the pin still catches the regression but the assertion is slightly weaker than intended.

The parametrized test in tests/test_litellm/proxy/management_endpoints/test_team_endpoints.py shares a single updated_team mock between the add and delete scenarios, making the models assertion for the delete case misleading. No production files require special attention.

Important Files Changed

Filename Overview
litellm/proxy/auth/model_checks.py Adds _hydrate_litellm_credential_name to resolve credential-name references before wildcard model discovery, and threads team_id through the wildcard expansion path so team-scoped BYOK deployments are found correctly.
litellm/proxy/management_endpoints/team_endpoints.py Introduces _refresh_cached_team helper and wires it into team_model_add, team_model_delete, and update_team so the in-memory team cache stays in sync after every DB write.
litellm/proxy/utils.py Computes effective_team_id (query param or key's own team_id) and passes it to get_complete_model_list so the wildcard expansion uses the correct team-scoped deployment.
tests/test_litellm/proxy/auth/test_model_checks.py Adds four focused mock-only tests covering credential hydration for wildcard discovery and end-to-end get_available_models_for_user flow.
tests/test_litellm/proxy/management_endpoints/test_team_endpoints.py Adds a parametrized regression pin for LIT-3244 cache refresh and updates two existing tests to patch the re-exported _cache_team_object binding correctly.

Reviews (1): Last reviewed commit: "fix(team): refresh team cache on team_mo..." | Re-trigger Greptile

Comment on lines +1592 to +1605
updated_team = MagicMock()
updated_team.team_id = "team-1234"
updated_team.model_dump.return_value = {
"team_id": "team-1234",
"models": ["bedrock-claude-sonnet-4", "openai/*", "team-byok-1"],
# The Prisma update must come back with `object_permission` populated
# (via `include={"object_permission": True}`), otherwise the cache
# write below would null it out — see LIT-3244 follow-up.
"object_permission_id": "op-1234",
"object_permission": {
"object_permission_id": "op-1234",
"search_tools": ["allowed-tool-A"],
},
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 The updated_team mock is shared between both the team_model_add and team_model_delete parametrized cases, and its models list (["bedrock-claude-sonnet-4", "openai/*", "team-byok-1"]) only makes sense for the add case. The delete case asserts that the cached models still include "openai/*" and "team-byok-1", which is logically backwards. The regression pin still holds because the key check is that the mock's return value (not existing_team) was cached, but the model-list assertion passes for reasons unrelated to the delete path's correctness.

Suggested change
updated_team = MagicMock()
updated_team.team_id = "team-1234"
updated_team.model_dump.return_value = {
"team_id": "team-1234",
"models": ["bedrock-claude-sonnet-4", "openai/*", "team-byok-1"],
# The Prisma update must come back with `object_permission` populated
# (via `include={"object_permission": True}`), otherwise the cache
# write below would null it out — see LIT-3244 follow-up.
"object_permission_id": "op-1234",
"object_permission": {
"object_permission_id": "op-1234",
"search_tools": ["allowed-tool-A"],
},
}
add_updated_models = ["bedrock-claude-sonnet-4", "openai/*", "team-byok-1"]
delete_updated_models = ["bedrock-claude-sonnet-4"]
updated_team = MagicMock()
updated_team.team_id = "team-1234"
updated_team.model_dump.return_value = {
"team_id": "team-1234",
"models": add_updated_models if endpoint_name == "team_model_add" else delete_updated_models,
# The Prisma update must come back with `object_permission` populated
# (via `include={"object_permission": True}`), otherwise the cache
# write below would null it out — see LIT-3244 follow-up.
"object_permission_id": "op-1234",
"object_permission": {
"object_permission_id": "op-1234",
"search_tools": ["allowed-tool-A"],
},
}

@yuneng-berri
yuneng-berri merged commit a81ba48 into patch/1.86.0 May 24, 2026
61 of 75 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant