fix(config): add retry logic for provider loading

This commit is contained in:
Bohdan Triapitsyn
2025-12-25 23:57:03 +02:00
parent 3106abec9b
commit 2080ce6d65
+49 -30
View File
@@ -259,42 +259,61 @@ export const useConfigStore = create<ConfigStore>()(
modelsMetadata: new Map<string, ModelMetadata>(), modelsMetadata: new Map<string, ModelMetadata>(),
loadProviders: async () => { loadProviders: async () => {
try { const previousProviders = get().providers;
const metadataPromise = fetchModelsDevMetadata(); const previousDefaults = get().defaultProviders;
const apiResult = await opencodeClient.getProviders(); const previousProviderId = get().currentProviderId;
const providers = Array.isArray(apiResult?.providers) ? apiResult.providers : []; const previousModelId = get().currentModelId;
const defaults = apiResult?.default || {}; let lastError: unknown = null;
const processedProviders: ProviderWithModelList[] = providers.map((provider) => { for (let attempt = 0; attempt < 3; attempt++) {
const modelRecord = provider.models ?? {}; try {
const models: ProviderModel[] = Object.keys(modelRecord).map((modelId) => modelRecord[modelId]); const metadataPromise = fetchModelsDevMetadata();
return { const apiResult = await opencodeClient.getProviders();
...provider, const providers = Array.isArray(apiResult?.providers) ? apiResult.providers : [];
models, const defaults = apiResult?.default || {};
};
});
const defaultProviderId = defaults.provider || processedProviders[0]?.id || ""; const processedProviders: ProviderWithModelList[] = providers.map((provider) => {
const provider = processedProviders.find((p) => p.id === defaultProviderId); const modelRecord = provider.models ?? {};
const defaultModelId = defaults.model || provider?.models?.[0]?.id || ""; const models: ProviderModel[] = Object.keys(modelRecord).map((modelId) => modelRecord[modelId]);
return {
...provider,
models,
};
});
set({ const defaultProviderId = defaults.provider || processedProviders[0]?.id || "";
providers: processedProviders, const provider = processedProviders.find((p) => p.id === defaultProviderId);
defaultProviders: defaults, const defaultModelId = defaults.model || provider?.models?.[0]?.id || "";
currentProviderId: defaultProviderId, set({
currentModelId: defaultModelId, providers: processedProviders,
}); defaultProviders: defaults,
const metadata = await metadataPromise; currentProviderId: defaultProviderId,
if (metadata.size > 0) { currentModelId: defaultModelId,
set({ modelsMetadata: metadata }); });
const metadata = await metadataPromise;
if (metadata.size > 0) {
set({ modelsMetadata: metadata });
}
return;
} catch (error) {
lastError = error;
const waitMs = 200 * (attempt + 1);
await new Promise((resolve) => setTimeout(resolve, waitMs));
} }
} catch (error) { }
console.error("Failed to load providers:", error);
set({ providers: [], defaultProviders: {}, currentProviderId: "", currentModelId: "" }); console.error("Failed to load providers:", lastError);
} // Preserve previous state on failure instead of clearing it
}, set({
providers: previousProviders,
defaultProviders: previousDefaults,
currentProviderId: previousProviderId,
currentModelId: previousModelId,
});
},
setProvider: (providerId: string) => { setProvider: (providerId: string) => {
const { providers } = get(); const { providers } = get();