fix(models): keep a restricted model visible and name it in the runtime error (#14697)
* fix(models): keep a restricted model visible and name it in the runtime error A model that an administrator restricted after it was selected (hidden by the model allowlist, or its whole provider revoked) disappeared from the builder's seat: the Language Model field read "Select a model" — or showed the first model of some other provider — and, with other models enabled, the auto-select silently swapped the saved value for one of them. Running the flow then surfaced `ModelProviderPolicyError Code: policy_blocked`, the Python class name and a reason code, with nothing about what was blocked or who to ask (LE-1960; Enterprise QA BUG-02 / BUG-03). Frontend (ModelInput): - New `isSavedModelUnavailable` helper tells "restricted / no longer offered" apart from "not enabled locally" and "deactivated": the saved provider is absent from /models entirely, or it is configured but neither its catalog nor the user's enabled-models map knows the model. Nothing is judged until both server views have settled. - `deriveSelectedModel` keeps naming the saved model and flags it `unavailable` instead of falling back to flatOptions[0]; the trigger renders a "Not available" marker with an explanation aligned with the runtime error. The backend-injected `not_enabled_locally` tag is dropped on that branch so the configure wrench (which has nothing to configure) does not render. - `useAutoSelectModel` no longer replaces a restricted model; lifting the restriction restores the saved selection. Disconnected providers and locally deactivated models keep their existing swap behaviour. Backend (lfx): - `ModelProviderPolicyError` names the blocked model and provider and tells the builder to ask an administrator. The provider-level message is unchanged. - `ErrorMessage` renders the human message of a reason-coded exception (message + code) instead of the class name and `Code: …` alone; coded exceptions without a message keep the previous rendering. * fix(models): treat a settled empty provider list as "not offered" and keep an unavailable model over the setup CTA CodeRabbit on #14697: a settled, empty /models response is a verdict (no provider is offered to this user — an Enterprise install that starts closed), not a still-loading gap, so a saved model is unavailable there like any other missing provider; and the trigger's "Setup Provider" branch must not replace a selected-but-unavailable model, which would hide both the saved selection and the reason it cannot be used (the popover footer still offers provider management).
E
Eric Hare committed
12efda24446d8dc7e820aaa9e1b2cd038ff008e2
Parent: 4f3b9f3
Committed by GitHub <noreply@github.com>
on 8/21/2026, 4:28:01 PM