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:
parent
f705a4948d
commit
f1516d9228
2 changed files with 77 additions and 4 deletions
|
|
@ -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(
|
const handleBaseUrlChange = useCallback(
|
||||||
|
|
|
||||||
|
|
@ -374,7 +374,12 @@ export const useSettingsStore = create<SettingsStore>()(
|
||||||
},
|
},
|
||||||
|
|
||||||
setPostProcessProvider: async (providerId) => {
|
setPostProcessProvider: async (providerId) => {
|
||||||
const { settings, setUpdating, refreshSettings } = get();
|
const {
|
||||||
|
settings,
|
||||||
|
setUpdating,
|
||||||
|
refreshSettings,
|
||||||
|
setPostProcessModelOptions,
|
||||||
|
} = get();
|
||||||
const updateKey = "post_process_provider_id";
|
const updateKey = "post_process_provider_id";
|
||||||
const previousId = settings?.post_process_provider_id ?? null;
|
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 {
|
try {
|
||||||
await commands.setPostProcessProvider(providerId);
|
await commands.setPostProcessProvider(providerId);
|
||||||
await refreshSettings();
|
await refreshSettings();
|
||||||
|
|
@ -436,7 +445,49 @@ export const useSettingsStore = create<SettingsStore>()(
|
||||||
},
|
},
|
||||||
|
|
||||||
updatePostProcessBaseUrl: async (providerId, baseUrl) => {
|
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) => {
|
updatePostProcessApiKey: async (providerId, apiKey) => {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue