fix: chat works with any configured provider + surfaces errors

The chat defaulted to a Claude model, so a user who saved only a Gemini key got
a silent failure (backend derived Anthropic, found no key, errored — and the UI
showed nothing).

- Backend: resolveModel now falls back to whichever provider actually has a key
  (preferring the configured one), so a Gemini key just works regardless of the
  picked model. Clear 400 if no provider is configured at all.
- Frontend: the chat seeds its model/effort from the saved AI config, and now
  surfaces request failures as both a persistent alert banner and a toast —
  never silent.
- Settings: switching provider auto-selects that provider's default model.
- Refreshed the model catalog to current ids (Gemini 2.5 Pro/Flash + 2.0 Flash;
  dropped the retired gemini-1.5-pro); per-provider default model updated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Khalid Abdi
2026-06-13 19:27:37 +03:00
parent a80086ef72
commit ddf4b49d82
5 changed files with 139 additions and 32 deletions
+14 -3
View File
@@ -71,6 +71,19 @@ export function AIPanel() {
const set = <K extends keyof AiConfig>(key: K, value: AiConfig[K]) =>
setConfig((prev) => ({ ...prev, [key]: value }));
// Switching provider: if the current default model doesn't belong to the new
// provider, pick that provider's first model so they never end up mismatched.
const setProvider = (provider: ApiProvider) =>
setConfig((prev) => {
const models = AI_MODELS.filter((m) => m.provider === provider);
const stillValid = models.some((m) => m.id === prev.defaultModel);
return {
...prev,
provider,
defaultModel: stillValid ? prev.defaultModel : (models[0]?.id ?? prev.defaultModel),
};
});
// Models available for the currently selected cloud provider.
const providerModels = useMemo(
() => AI_MODELS.filter((m) => m.provider === config.provider),
@@ -169,9 +182,7 @@ export function AIPanel() {
<div className="space-y-1.5">
<FieldLabel>{t("settings.ai.provider")}</FieldLabel>
<Select
onValueChange={(value) =>
set("provider", value as ApiProvider)
}
onValueChange={(value) => setProvider(value as ApiProvider)}
value={config.provider}
>
<SelectTrigger>