From 0b641208744292983a3dff0121200227fa868fb3 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Tue, 22 Sep 2026 21:07:49 +0200 Subject: [PATCH] Stop retrying requests the provider refuses for good --- .../Assistants/I18N/allTexts.lua | 3 +++ .../Provider/BaseProvider.cs | 25 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/app/MindWork AI Studio/Assistants/I18N/allTexts.lua b/app/MindWork AI Studio/Assistants/I18N/allTexts.lua index f09f9d56..a59b4133 100644 --- a/app/MindWork AI Studio/Assistants/I18N/allTexts.lua +++ b/app/MindWork AI Studio/Assistants/I18N/allTexts.lua @@ -10141,6 +10141,9 @@ UI_TEXT_CONTENT["AISTUDIO::PROVIDER::BASEPROVIDER::T265391888"] = "The selected -- The provider '{0}' could not be reached. Please check whether it is running and reachable, then try again. UI_TEXT_CONTENT["AISTUDIO::PROVIDER::BASEPROVIDER::T2819996431"] = "The provider '{0}' could not be reached. Please check whether it is running and reachable, then try again." +-- We tried to communicate with the LLM provider '{0}' (type={1}). The provider turned the request down with the status code {2} and would turn it down again, so we stopped trying. The provider message is: '{3}' +UI_TEXT_CONTENT["AISTUDIO::PROVIDER::BASEPROVIDER::T2993640453"] = "We tried to communicate with the LLM provider '{0}' (type={1}). The provider turned the request down with the status code {2} and would turn it down again, so we stopped trying. The provider message is: '{3}'" + -- We tried to communicate with the LLM provider '{0}' (type={1}). Something was not found. The provider message is: '{2}' UI_TEXT_CONTENT["AISTUDIO::PROVIDER::BASEPROVIDER::T3014737766"] = "We tried to communicate with the LLM provider '{0}' (type={1}). Something was not found. The provider message is: '{2}'" diff --git a/app/MindWork AI Studio/Provider/BaseProvider.cs b/app/MindWork AI Studio/Provider/BaseProvider.cs index 4c0a133a..a53a4201 100644 --- a/app/MindWork AI Studio/Provider/BaseProvider.cs +++ b/app/MindWork AI Studio/Provider/BaseProvider.cs @@ -831,6 +831,31 @@ public abstract class BaseProvider : IProvider, ISecretId break; } + // + // Everything else the provider answers in the 400 range is about this request itself, + // and sending the very same request again cannot change that answer. Only 408 and 429 + // say "later" rather than "no", and waiting them out is what the delay below exists + // for. This branch comes last on purpose: every status code we have a better sentence + // for is handled above, and only what is left over ends up with this general wording. + // + if(nextResponse.StatusCode is not (HttpStatusCode.RequestTimeout or HttpStatusCode.TooManyRequests) && (int)nextResponse.StatusCode is >= 400 and < 500) + { + // + // What the provider said about it, falling back to the reason phrase. The status + // code is named as well: this is the branch for refusals we have no wording of our + // own for, and then the number is what the user can ask the provider about. + // + var refusalMessage = ReadProviderErrorMessage(errorBody); + if (string.IsNullOrWhiteSpace(refusalMessage)) + refusalMessage = nextResponse.ReasonPhrase; + + await MessageBus.INSTANCE.SendError(new(Icons.Material.Filled.CloudOff, string.Format(TB("We tried to communicate with the LLM provider '{0}' (type={1}). The provider turned the request down with the status code {2} and would turn it down again, so we stopped trying. The provider message is: '{3}'"), this.InstanceName, this.Provider, (int)nextResponse.StatusCode, refusalMessage))); + this.logger.LogError("Failed request with status code {ResponseStatusCode} (message = '{ResponseReasonPhrase}', error body = '{ErrorBody}').", nextResponse.StatusCode, nextResponse.ReasonPhrase, errorBody); + errorMessage = nextResponse.ReasonPhrase; + failureAlreadyExplained = true; + break; + } + errorMessage = nextResponse.ReasonPhrase; var timeSeconds = Math.Pow(RETRY_DELAY_SECONDS, retry + 1); if(timeSeconds > 90)