diff --git a/app/MindWork AI Studio/Provider/Google/ProviderGoogle.cs b/app/MindWork AI Studio/Provider/Google/ProviderGoogle.cs index af4486f3..0d143ecd 100644 --- a/app/MindWork AI Studio/Provider/Google/ProviderGoogle.cs +++ b/app/MindWork AI Studio/Provider/Google/ProviderGoogle.cs @@ -172,11 +172,15 @@ public class ProviderGoogle() : BaseProvider(LLMProviders.GOOGLE, new Uri("https // Asking what a model is made for, rather than only ruling out the embedding ones. // Google names everything after the chat model it grew out of, so the catalog is // full of names which look like something to talk to and are not: the image models, - // and the computer use model whose API refuses a request without its tool. + // the computer use model whose API refuses a request without its tool, and the live + // line which wants a connection held open in both directions. // - ..result.Models.Where(model => - model.Id.StartsWith("gemini-", StringComparison.OrdinalIgnoreCase) && - model.IsChatModel(this.Provider)) + // The question used to be asked of names beginning with "gemini" alone, and that + // cost the two Gemma models Google serves on this very route. What the prefix kept + // out besides them -- Lyria, Imagen, Veo, the research and coding agents, AQA -- + // is kept out by a rule now, where the reason is written down. + // + ..result.Models.Where(model => model.IsChatModel(this.Provider)) .Select(this.WithDisplayNameFallback) ] }; diff --git a/app/MindWork AI Studio/Provider/Mistral/ProviderMistral.cs b/app/MindWork AI Studio/Provider/Mistral/ProviderMistral.cs index 15299569..5464a4e0 100644 --- a/app/MindWork AI Studio/Provider/Mistral/ProviderMistral.cs +++ b/app/MindWork AI Studio/Provider/Mistral/ProviderMistral.cs @@ -93,12 +93,13 @@ public sealed class ProviderMistral() : BaseProvider(LLMProviders.MISTRAL, new U { Models = [ - // Codestral is a fill-in-the-middle model, which we cannot use for chats. That is - // specific to Mistral's catalog, which is why it is not part of the shared model - // kind detection: - ..modelResponse.Models.Where(n => - !n.Id.StartsWith("code", StringComparison.OrdinalIgnoreCase) && - n.IsChatModel(this.Provider)) + // + // Codestral is a fill-in-the-middle model, which we cannot use for chats. Its own + // family says so now, bound to this provider, so the word "code" no longer has to + // be tested for here -- and testing for it never reached mistral-code-fim-latest, + // which does the same job under a name that begins differently. + // + ..modelResponse.Models.Where(n => n.IsChatModel(this.Provider)) ] }; } diff --git a/app/MindWork AI Studio/Provider/X/ProviderX.cs b/app/MindWork AI Studio/Provider/X/ProviderX.cs index 46d96be8..b10f1ef2 100644 --- a/app/MindWork AI Studio/Provider/X/ProviderX.cs +++ b/app/MindWork AI Studio/Provider/X/ProviderX.cs @@ -76,7 +76,7 @@ public sealed class ProviderX() : BaseProvider(LLMProviders.X, new Uri("https:// /// public override async Task GetTextModels(string? apiKeyProvisional = null, CancellationToken token = default) { - var result = await this.LoadModels(SecretStoreType.LLM_PROVIDER, ["grok-"], apiKeyProvisional, token); + var result = await this.LoadModels(SecretStoreType.LLM_PROVIDER, apiKeyProvisional, token); return result with { // @@ -108,19 +108,24 @@ public sealed class ProviderX() : BaseProvider(LLMProviders.X, new Uri("https:// #endregion - private Task LoadModels(SecretStoreType storeType, string[] prefixes, string? apiKeyProvisional, CancellationToken token) + /// + /// Reads the xAI catalog, whole. + /// + /// + /// Every name in it begins with "grok", which is why the prefix this used to filter by never + /// took anything away -- and why it said nothing either. What it did carry was Grok 2, appended + /// to every answer whether xAI still served it or not. It does not: the catalog has moved on to + /// Grok 4, and an entry nobody can talk to is worse than one missing from the list. + /// + /// What the catalog does hold besides the chat models is five names which draw or film. The + /// caller asks the registry about those. + /// + private Task LoadModels(SecretStoreType storeType, string? apiKeyProvisional, CancellationToken token) { return this.LoadModelsResponse( storeType, "models", - modelResponse => modelResponse.Data.Where(model => prefixes.Any(prefix => model.Id.StartsWith(prefix, StringComparison.InvariantCulture))) - .Concat([ - new Model - { - Id = "grok-2-latest", - DisplayName = "Grok 2.0 (latest)", - } - ]), + modelResponse => modelResponse.Data, apiKeyProvisional, token: token); } } \ No newline at end of file