Backfill free-tier team model allowlists when FREE_LLM_MODELS changes - #268
Draft
juanmichelini wants to merge 1 commit into
Draft
Backfill free-tier team model allowlists when FREE_LLM_MODELS changes#268juanmichelini wants to merge 1 commit into
juanmichelini wants to merge 1 commit into
Conversation
FREE_LLM_MODELS is only applied when a team is (re)provisioned, so adding a model such as deepseek-v4-flash to the list leaves existing zero-credit teams on the stale allowlist and they keep getting 403 team_model_access_denied for the new model. Add LiteLlmManager.reconcile_free_tier_models(), an idempotent sweep that lists teams and, for each free-tier team whose allowlist has drifted from the current FREE_LLM_MODELS, re-runs the existing update_team_and_users_budget(team_id, 0.0) backfill. It is invoked best-effort from the run_budget_maintenance entrypoint, which the budget-maintenance CronJob already runs on every deploy and every 15 minutes, so the backfill happens whenever the env var changes without any new CronJob, chart change, or schema migration. Teams already in sync are skipped, so the proxy is written only on drift. Co-authored-by: openhands <openhands@all-hands.dev>
Coverage reportClick to see where and how coverage changed
This report was generated by python-coverage-comment-action |
||||||||||||||||||||||||||||||||||||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
FREE_LLM_MODELSis only applied to a team's LiteLLMmodelsallowlist when the team is (re)provisioned (create_entries/ budget updates). Changing the env var — e.g. addingdeepseek-v4-flash— therefore does not update existing zero-credit teams. They stay on the stale allowlist and keep hitting403 team_model_access_deniedfor the newly-added model until some unrelated provisioning pass happens to touch them.There was no automatic backfill anywhere: PR #143 is explicitly scoped to provisioning and documents that existing teams are not reconciled; migration 153 only rewrote the stored default model, not the LiteLLM allowlist; and neither the daily maintenance tasks nor the 15-minute budget CronJob backfilled allowlists.
Fix
Add
LiteLlmManager.reconcile_free_tier_models()— an idempotent sweep that:GET /team/list.FREE_LLM_MODELS, re-runs the existingupdate_team_and_users_budget(team_id, 0.0)backfill (which already re-derives the allowlist fromFREE_LLM_MODELSand clears any stale member-level budget).A team is considered free-tier when either:
max_budget is Noneandmodelsis a non-empty subset ofFREE_LLM_MODELS(the exact shape written formax_budget == 0.0), ormax_budget == 0.0with an emptymodelslist (legacy no-credit teams that predate the free-tier restriction).Paid teams (
max_budget > 0), unlimited teams (Nonebudget + no restriction), and teams with custom non-subset allowlists are left untouched. Teams already in sync are skipped, so the proxy is written only on drift.Wiring — no new infrastructure
The reconcile is invoked best-effort from the existing
run_budget_maintenanceentrypoint, which thebudget-maintenanceCronJob already runs on every deploy and every 15 minutes withFREE_LLM_MODELSinjected. So:Testing
TestReconcileFreeTierModels(9 cases): legacy zero-budget team, restricted free-tier missing the new model, already-in-sync skip, paid/unlimited/non-subset skip, only-drifted-teams reconciled, error counting without raising, and no-op without proxy config.test_lite_llm_manager.pysuite passes (138 tests). No newrufferrors introduced.This PR was created by an AI agent (OpenHands) on behalf of the user.
@juanmichelini can click here to continue refining the PR
Enterprise server image for this PR: