From ab45580473f72e66a6d729a604f0c67825caf612 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Tue, 13 Oct 2026 19:47:04 +0200 Subject: [PATCH] Added Mistral Large 4 to the model knowledge (#1059) --- .../Models/Mistral/MistralLargeFamily.cs | 13 ++++++-- .../Models/Mistral/MistralReleases.cs | 1 + .../wwwroot/changelog/v26.10.1.md | 1 + .../Models/Corpus/CapabilitySnapshot.txt | 3 ++ app/Tests/Models/Corpus/ModelCorpus.cs | 3 ++ .../Models/Mistral/MistralReleasesTests.cs | 31 ++++++++++++++++++- 6 files changed, 49 insertions(+), 3 deletions(-) diff --git a/app/MindWork AI Studio/Models/Mistral/MistralLargeFamily.cs b/app/MindWork AI Studio/Models/Mistral/MistralLargeFamily.cs index 3cbda281..00804ba3 100644 --- a/app/MindWork AI Studio/Models/Mistral/MistralLargeFamily.cs +++ b/app/MindWork AI Studio/Models/Mistral/MistralLargeFamily.cs @@ -8,7 +8,7 @@ namespace AIStudio.Models.Mistral; public sealed class MistralLargeFamily : MistralReleaseDatedFamily { /// - public override ModelSource Source => new("https://docs.mistral.ai/models/mistral-large-3-25-12", new DateOnly(2026, 9, 12), "Capabilities ported unchanged from ProviderExtensions.Mistral.cs: images and reasoning from Mistral Large 3 on. The model card states a 256k window."); + public override ModelSource Source => new("https://docs.mistral.ai/models/mistral-large-4-0", new DateOnly(2026, 10, 13), "Capabilities ported unchanged from ProviderExtensions.Mistral.cs: images and reasoning from Mistral Large 3 on. The model card of Mistral Large 3 states a 256k window, the one of Mistral Large 4 a 1M window."); /// protected override int VisionSince => 2512; @@ -20,9 +20,18 @@ public sealed class MistralLargeFamily : MistralReleaseDatedFamily protected override int LatestRelease => 2512; /// - protected override void Declare(ModelFamilyBuilder builder) => + protected override void Declare(ModelFamilyBuilder builder) + { builder.Rule("mistral-large").AsSegment() .Capabilities(WHAT_THEY_COULD_ALWAYS_DO) .Apis(CHAT_COMPLETION_API) .ContextWindow(256_000); + + // + // Mistral Large 4 reads a million tokens instead of 256k. Its names carry the generation + // instead of a release, so this rule answers for the window only; images and reasoning + // still follow from the release, which the version names map Mistral Large 4 onto: + // + builder.Rule("mistral-large-4").AsSegment().InheritsFrom("mistral-large").ContextWindow(1_000_000); + } } \ No newline at end of file diff --git a/app/MindWork AI Studio/Models/Mistral/MistralReleases.cs b/app/MindWork AI Studio/Models/Mistral/MistralReleases.cs index d18d8f84..4566cde0 100644 --- a/app/MindWork AI Studio/Models/Mistral/MistralReleases.cs +++ b/app/MindWork AI Studio/Models/Mistral/MistralReleases.cs @@ -59,6 +59,7 @@ public static class MistralReleases /// private static readonly (string VersionName, int Release)[] VERSION_NAMES = [ + ("mistral-large-4", 2610), ("mistral-large-3", 2512), ("mistral-medium-3.5", 2604), diff --git a/app/MindWork AI Studio/wwwroot/changelog/v26.10.1.md b/app/MindWork AI Studio/wwwroot/changelog/v26.10.1.md index 9ef354d2..32dc4956 100644 --- a/app/MindWork AI Studio/wwwroot/changelog/v26.10.1.md +++ b/app/MindWork AI Studio/wwwroot/changelog/v26.10.1.md @@ -9,6 +9,7 @@ - Added a way for IT departments to let requests to the self-hosted AI servers of your organization name the feature of AI Studio that sent them, either for everybody or as a default that users may change. This shows which features are used. The Enterprise IT documentation explains what is sent and what to clarify before you switch it on, for example, with your works council. - Added Requesty as a new LLM provider for chats, embeddings, and transcriptions. Requesty is an AI gateway from the United Kingdom that gives you models from many providers with a single API key. Because where your data is processed depends on the model you choose, you set its trust level yourself. Thanks, Thibault Jaigu (`Thibaultjaigu`), for this first contribution. - Added [llmman](https://github.com/llmmanorg/llmman) as a new option for the models you host yourself. llmman runs open models on your own computer or server, and AI Studio can use them for chats, embeddings, and transcriptions. Thanks, Eric Curtin (`ericcurtin`), for this first contribution. +- Added support for Mistral Large 4. - Improved the Read Web Page tool. When you have not allowed the AI to choose web addresses freely, the tool now refuses every address that does not appear in your chat or in what the tools returned, instead of only asking the AI not to read it. - Improved the installation on macOS: AI Studio is now signed and checked by Apple, so it opens like any other app. You no longer need the Terminal. - Improved the installation on Windows: AI Studio is now signed, so Windows shows who published it. For a while, Windows may still ask you to confirm the installation until it knows the app better. diff --git a/app/Tests/Models/Corpus/CapabilitySnapshot.txt b/app/Tests/Models/Corpus/CapabilitySnapshot.txt index 14529155..555a4320 100644 --- a/app/Tests/Models/Corpus/CapabilitySnapshot.txt +++ b/app/Tests/Models/Corpus/CapabilitySnapshot.txt @@ -122,6 +122,8 @@ MISTRAL | ministral-3b-latest | CHAT_COMPLETION_API, FUNCTION_CALLING, MULTIPLE_ MISTRAL | ministral-8b-2410 | CHAT_COMPLETION_API, FUNCTION_CALLING, TEXT_INPUT, TEXT_OUTPUT | CHAT | (unknown) | (unknown) | (unknown) | (unknown) MISTRAL | mistral-large-2411 | CHAT_COMPLETION_API, FUNCTION_CALLING, TEXT_INPUT, TEXT_OUTPUT | CHAT | 256000 | (unknown) | (unknown) | (unknown) MISTRAL | mistral-large-2512 | CHAT_COMPLETION_API, FUNCTION_CALLING, MULTIPLE_IMAGE_INPUT, OPTIONAL_REASONING, TEXT_INPUT, TEXT_OUTPUT | CHAT | 256000 | (unknown) | (unknown) | (unknown) +MISTRAL | mistral-large-4 | CHAT_COMPLETION_API, FUNCTION_CALLING, MULTIPLE_IMAGE_INPUT, OPTIONAL_REASONING, TEXT_INPUT, TEXT_OUTPUT | CHAT | 1000000 | (unknown) | (unknown) | (unknown) +MISTRAL | mistral-large-4-0 | CHAT_COMPLETION_API, FUNCTION_CALLING, MULTIPLE_IMAGE_INPUT, OPTIONAL_REASONING, TEXT_INPUT, TEXT_OUTPUT | CHAT | 1000000 | (unknown) | (unknown) | (unknown) MISTRAL | mistral-large-latest | CHAT_COMPLETION_API, FUNCTION_CALLING, MULTIPLE_IMAGE_INPUT, OPTIONAL_REASONING, TEXT_INPUT, TEXT_OUTPUT | CHAT | 256000 | (unknown) | (unknown) | (unknown) MISTRAL | mistral-medium-2505 | CHAT_COMPLETION_API, FUNCTION_CALLING, MULTIPLE_IMAGE_INPUT, TEXT_INPUT, TEXT_OUTPUT | CHAT | 256000 | (unknown) | (unknown) | (unknown) MISTRAL | mistral-medium-2508 | CHAT_COMPLETION_API, FUNCTION_CALLING, MULTIPLE_IMAGE_INPUT, TEXT_INPUT, TEXT_OUTPUT | CHAT | 256000 | (unknown) | (unknown) | (unknown) @@ -183,6 +185,7 @@ OPEN_ROUTER | google/gemma-4-31b-it | CHAT_COMPLETION_API, FUNCTION_CALLING, MUL OPEN_ROUTER | meta-llama/llama-4-maverick | CHAT_COMPLETION_API, FUNCTION_CALLING, MULTIPLE_IMAGE_INPUT, TEXT_INPUT, TEXT_OUTPUT | CHAT | (unknown) | (unknown) | (unknown) | (unknown) OPEN_ROUTER | minimax/minimax-m2 | ALWAYS_REASONING, CHAT_COMPLETION_API, FUNCTION_CALLING, TEXT_INPUT, TEXT_OUTPUT | CHAT | (unknown) | (unknown) | (unknown) | (unknown) OPEN_ROUTER | mistralai/mistral-large-3 | CHAT_COMPLETION_API, FUNCTION_CALLING, MULTIPLE_IMAGE_INPUT, OPTIONAL_REASONING, TEXT_INPUT, TEXT_OUTPUT | CHAT | 256000 | (unknown) | (unknown) | (unknown) +OPEN_ROUTER | mistralai/mistral-large-4-0 | CHAT_COMPLETION_API, FUNCTION_CALLING, MULTIPLE_IMAGE_INPUT, OPTIONAL_REASONING, TEXT_INPUT, TEXT_OUTPUT | CHAT | 1000000 | (unknown) | (unknown) | (unknown) OPEN_ROUTER | moonshotai/kimi-k2-thinking | ALWAYS_REASONING, CHAT_COMPLETION_API, FUNCTION_CALLING, TEXT_INPUT, TEXT_OUTPUT | CHAT | (unknown) | (unknown) | (unknown) | (unknown) OPEN_ROUTER | nvidia/nemotron-3-49b | CHAT_COMPLETION_API, FUNCTION_CALLING, REASONING_BY_DEFAULT, TEXT_INPUT, TEXT_OUTPUT | CHAT | (unknown) | (unknown) | (unknown) | (unknown) OPEN_ROUTER | openai/gpt-5.6 | CHAT_COMPLETION_API, FUNCTION_CALLING, MULTIPLE_IMAGE_INPUT, REASONING_BY_DEFAULT, TEXT_INPUT, TEXT_OUTPUT, WEB_SEARCH | CHAT | 1050000 | (unknown) | TIKTOKEN o200k_base | DEVELOPER diff --git a/app/Tests/Models/Corpus/ModelCorpus.cs b/app/Tests/Models/Corpus/ModelCorpus.cs index 34a4fe2a..be16d13e 100644 --- a/app/Tests/Models/Corpus/ModelCorpus.cs +++ b/app/Tests/Models/Corpus/ModelCorpus.cs @@ -112,6 +112,8 @@ public static class ModelCorpus private static readonly CorpusEntry[] MISTRAL_ENTRIES = [ new(MISTRAL, "mistral-large-latest", NAMED_BY_A_RULE), + new(MISTRAL, "mistral-large-4", NAMED_BY_A_RULE), + new(MISTRAL, "mistral-large-4-0", NAMED_BY_NO_RULE), new(MISTRAL, "mistral-large-2512", NAMED_BY_A_RULE), new(MISTRAL, "mistral-large-2411", NAMED_BY_A_RULE), new(MISTRAL, "mistral-medium-latest", NAMED_BY_A_RULE), @@ -227,6 +229,7 @@ public static class ModelCorpus new(OPEN_ROUTER, "google/gemini-3.7-flash", QUOTED_AS_A_NAME_SHAPE), new(OPEN_ROUTER, "google/gemma-4-31b-it", NAMED_BY_A_RULE), new(OPEN_ROUTER, "mistralai/mistral-large-3", NAMED_BY_A_RULE), + new(OPEN_ROUTER, "mistralai/mistral-large-4-0", NAMED_BY_NO_RULE), new(OPEN_ROUTER, "perplexity/sonar-reasoning", NAMED_BY_A_RULE), new(OPEN_ROUTER, "qwen/qwen3.8-flash-next", QUOTED_AS_A_NAME_SHAPE), new(OPEN_ROUTER, "deepseek/deepseek-r1-distill-llama-70b", ON_THE_MANUAL_TEST_LIST), diff --git a/app/Tests/Models/Mistral/MistralReleasesTests.cs b/app/Tests/Models/Mistral/MistralReleasesTests.cs index 289e3ce8..702713ef 100644 --- a/app/Tests/Models/Mistral/MistralReleasesTests.cs +++ b/app/Tests/Models/Mistral/MistralReleasesTests.cs @@ -24,7 +24,7 @@ public sealed class MistralReleasesTests /// /// A release far enough in the future that no name in these tests reaches it by accident. /// - private const int SOME_LATEST_RELEASE = 2604; + private const int SOME_LATEST_RELEASE = 2712; [TestCase("mistral-large-2512", ExpectedResult = 2512, TestName = "The release is read from the end of the name")] [TestCase("ministral-14b-2512", ExpectedResult = 2512, TestName = "The size of a model is not its release")] @@ -58,6 +58,8 @@ public sealed class MistralReleasesTests Assert.That(MistralReleases.Of(new ModelId("mistral-medium-3"), SOME_LATEST_RELEASE), Is.EqualTo(2505)); Assert.That(MistralReleases.Of(new ModelId("mistral-medium-3.5"), SOME_LATEST_RELEASE), Is.EqualTo(2604)); Assert.That(MistralReleases.Of(new ModelId("mistral-medium-3-5"), SOME_LATEST_RELEASE), Is.EqualTo(2604), "Mistral writes the version separator both ways for the same model."); + Assert.That(MistralReleases.Of(new ModelId("mistral-large-4"), SOME_LATEST_RELEASE), Is.EqualTo(2610)); + Assert.That(MistralReleases.Of(new ModelId("mistral-large-4-0"), SOME_LATEST_RELEASE), Is.EqualTo(2610), "The model card names it with a minor version, which changes nothing about the release."); }); } @@ -81,6 +83,33 @@ public sealed class MistralReleasesTests }); } + [TestCase("mistral-large-4", TestName = "Mistral Large 4 under the name of Mistral's changelog")] + [TestCase("mistral-large-4-0", TestName = "Mistral Large 4 under the name of its model card")] + public void MistralLargeFourSeesThinksAndReadsAMillionTokens(string modelId) + { + // + // Its names carry the generation and no release. Without its version name, it would get + // the answer for a release nobody can read and offer neither images nor reasoning. + // + var profile = ModelRegistry.Shared.Profile(LLMProviders.MISTRAL, modelId); + + Assert.Multiple(() => + { + Assert.That(profile.Has(Capability.MULTIPLE_IMAGE_INPUT), Is.True); + Assert.That(profile.Reasoning, Is.EqualTo(ReasoningSupport.OPTIONAL)); + Assert.That(profile.Context.DefaultTokens, Is.EqualTo(1_000_000)); + }); + } + + [TestCase("mistral-large-2512", TestName = "Mistral Large 3 keeps its own window")] + [TestCase("mistral-large-latest", TestName = "The latest alias keeps the window of the release it points at")] + public void TheMillionTokenWindowBelongsToMistralLargeFourAlone(string modelId) + { + var profile = ModelRegistry.Shared.Profile(LLMProviders.MISTRAL, modelId); + + Assert.That(profile.Context.DefaultTokens, Is.EqualTo(256_000)); + } + [Test] public void AReleaseWhichCannotBeReadGrantsNothing() {