fix: auto-refresh model list when switching post-processing providers (#854)

* fix: auto-refresh model list when switching post-processing providers

Clear cached model options and auto-fetch available models when the user
switches providers or changes the Custom provider's base URL. Prevents
stale model values from silently causing 404s at runtime.

* fix: address PR review feedback

- Fix race condition in updatePostProcessBaseUrl: persist base_url
  before clearing models so a failed write doesn't wipe the model
- Fix indentation in handleProviderSelect callback body
- Add guard before auto-fetching models: skip when provider has no
  API key or Custom has no base_url to avoid unnecessary errors

* fix: check result status before clearing models, run Prettier

- Check changePostProcessBaseUrlSetting and changePostProcessModelSetting
  result status before proceeding; bail on error to avoid partial state
- Clear cached model options only after both backend writes succeed
- Run Prettier to fix line-length violations (dependency array, destructuring)
This commit is contained in:
that-lucas 2026-02-25 09:21:26 +01:00 committed by GitHub
parent f705a4948d
commit f1516d9228
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 77 additions and 4 deletions

View file

@ -89,9 +89,31 @@ export const usePostProcessProviderState = (): PostProcessProviderState => {
}
}
void setPostProcessProvider(providerId);
await setPostProcessProvider(providerId);
// Auto-fetch available models for the new provider so the model dropdown
// reflects what's actually valid. Without this, a stale model value from
// a previous provider/base_url can persist and silently 404 at runtime.
// Skip when the provider isn't configured yet (no API key / empty base URL)
// to avoid unnecessary backend errors.
if (providerId !== APPLE_PROVIDER_ID) {
const provider = providers.find((p) => p.id === providerId);
const apiKey = settings?.post_process_api_keys?.[providerId] ?? "";
const hasBaseUrl = (provider?.base_url ?? "").trim() !== "";
const hasApiKey = apiKey.trim() !== "";
if (provider?.id === "custom" ? hasBaseUrl : hasApiKey) {
void fetchPostProcessModels(providerId);
}
}
},
[selectedProviderId, setPostProcessProvider],
[
selectedProviderId,
setPostProcessProvider,
fetchPostProcessModels,
providers,
settings,
],
);
const handleBaseUrlChange = useCallback(

View file

@ -374,7 +374,12 @@ export const useSettingsStore = create<SettingsStore>()(
},
setPostProcessProvider: async (providerId) => {
const { settings, setUpdating, refreshSettings } = get();
const {
settings,
setUpdating,
refreshSettings,
setPostProcessModelOptions,
} = get();
const updateKey = "post_process_provider_id";
const previousId = settings?.post_process_provider_id ?? null;
@ -388,6 +393,10 @@ export const useSettingsStore = create<SettingsStore>()(
}));
}
// Clear cached model options for the new provider so the dropdown
// doesn't show stale models from a previous fetch or base_url.
setPostProcessModelOptions(providerId, []);
try {
await commands.setPostProcessProvider(providerId);
await refreshSettings();
@ -436,7 +445,49 @@ export const useSettingsStore = create<SettingsStore>()(
},
updatePostProcessBaseUrl: async (providerId, baseUrl) => {
return get().updatePostProcessSetting("base_url", providerId, baseUrl);
const { setUpdating, refreshSettings } = get();
const updateKey = `post_process_base_url:${providerId}`;
setUpdating(updateKey, true);
try {
// Persist the new base URL first.
const urlResult = await commands.changePostProcessBaseUrlSetting(
providerId,
baseUrl,
);
if (urlResult.status === "error") {
console.error("Failed to persist base URL:", urlResult.error);
return;
}
// Reset the stored model since the previous value is almost certainly
// invalid for the new endpoint (e.g. switching Custom from Groq to
// Cerebras). Only proceed if the reset succeeds.
const modelResult = await commands.changePostProcessModelSetting(
providerId,
"",
);
if (modelResult.status === "error") {
console.error("Failed to reset model setting:", modelResult.error);
return;
}
// Clear cached model options only after both backend writes succeed.
set((state) => ({
postProcessModelOptions: {
...state.postProcessModelOptions,
[providerId]: [],
},
}));
// Single refresh after both backend writes.
await refreshSettings();
} catch (error) {
console.error("Failed to update post-process base URL:", error);
} finally {
setUpdating(updateKey, false);
}
},
updatePostProcessApiKey: async (providerId, apiKey) => {