Update OllamaModel with Mistral AI's recent models#6319
Conversation
09c1049 to
91ce75c
Compare
Code ReviewThe motivation here is correct — the 🔴 Critical: Hard removal of public enum constants without deprecation
The project's own precedent in @Deprecated(forRemoval = true) // Retirement planned the 31st of July 2026
MAGISTRAL_MEDIUM("magistral-medium-latest"),The new constants should be added alongside the old ones (marked 🔴 Critical: Silent behavioral change to the default model
// Before
this.model = model != null ? model : OllamaModel.MISTRAL.id();
// After
this.model = model != null ? model : OllamaModel.MINISTRAL_3_8B.id();This changes the fallback model for every application that builds The root cause of the failing tests is in the integration test setup, not in the production default. The correct fix is to update 🟡 Major: Naming convention inconsistencyThe existing Qwen3 constants in the same file use 🟡 Minor: Removed test coverage without replacementIn // Removed
var b1 = OllamaChatOptions.builder().model("model").mainGPU(12);
var b = OllamaChatOptions.builder().mainGPU(12).model("model");These were the only lines exercising assertThat(OllamaChatOptions.builder().model("model").mainGPU(12).build()).isNotNull();
assertThat(OllamaChatOptions.builder().mainGPU(12).model("model").build()).isNotNull();🟢 Good changes
Suggested path forward
|
kuntal1461
left a comment
There was a problem hiding this comment.
The motivation is correct — the mistral model being unavailable on Ollama's registry breaks integration tests and the new Ministral 3 family is the right replacement. However, there are two critical API-breaking issues that must be addressed before merge, plus a naming convention mismatch. Inline comments below point to the exact lines.
| */ | ||
| MISTRAL("mistral"), | ||
| MINISTRAL_3_3B("ministral-3:3b"), | ||
|
|
There was a problem hiding this comment.
🔴 Critical — hard removal without deprecation cycle
MISTRAL is deleted outright. Any downstream code referencing OllamaModel.MISTRAL will fail to compile.
The project's own precedent in MistralAiApi.ChatModel uses @Deprecated(forRemoval = true) before removal:
@Deprecated(forRemoval = true) // Retirement planned the 31st of July 2026
MAGISTRAL_MEDIUM("magistral-medium-latest"),Please keep MISTRAL("mistral") in this PR, mark it @Deprecated(forRemoval = true), and add MINISTRAL_3_3B alongside it. Hard removal can follow in a later release.
| */ | ||
| MISTRAL_NEMO("mistral-nemo"), | ||
| MINISTRAL_3_8B("ministral-3:8b"), | ||
|
|
There was a problem hiding this comment.
🔴 Critical — same issue for MISTRAL_NEMO
Same as above: MISTRAL_NEMO should be kept and annotated @Deprecated(forRemoval = true) rather than removed outright.
🟡 Major — naming convention inconsistency
The existing Qwen3 constants use QWEN3_7B (no underscore between family name and generation number). This constant introduces MINISTRAL_3_8B which breaks that pattern:
| Existing | New (this PR) | Consistent would be |
|---|---|---|
QWEN3_7B |
MINISTRAL_3_8B |
MINISTRAL3_8B |
QWEN3_4B |
MINISTRAL_3_3B |
MINISTRAL3_3B |
Please rename to MINISTRAL3_3B, MINISTRAL3_8B, MINISTRAL3_14B.
There was a problem hiding this comment.
Maybe we should keep Mistral Nemo for now and only deprecate it.
There are Qwen models following the same naming convention than the one I used for Ministral models.
There was a problem hiding this comment.
Thanks for checking in on the naming! You're right — QWEN_2_5_3B and QWEN_3_1_7_B do follow the same underscore-separated pattern as MINISTRAL_3_8B, so I withdraw that part of the comment. The existing naming is already mixed in the enum (QWEN3_7B vs QWEN_2_5_3B), so I'll defer to the maintainers on whichever they prefer .
On deprecation: glad we agree on keeping MISTRAL_NEMO. The same applies to MISTRAL as well — the PR diff hard-removes both. Please keep MISTRAL("mistral") too and annotate it with @Deprecated(forRemoval = true), not just MISTRAL_NEMO.
|
|
||
| /** | ||
| * The Ministral 3 14B language model from Mistral AI. | ||
| */ |
There was a problem hiding this comment.
🟡 Minor — sparse Javadoc
The old MISTRAL_NEMO entry documented meaningful facts: "A 12B model with 128k context length, built by Mistral AI in collaboration with NVIDIA."
The new entries only say "The Ministral 3 14B language model from Mistral AI." — missing: context window size, key capabilities, and an Ollama registry link. Suggestion:
/**
* The Ministral 3 14B language model from Mistral AI.
* Supports a 128k context window.
* @see <a href="https://ollama.com/library/ministral-3">Ollama: ministral-3</a>
*/| this.stop = stop != null ? List.copyOf(stop) : null; | ||
| this.model = model != null ? model : OllamaModel.MISTRAL.id(); | ||
| this.model = model != null ? model : OllamaModel.MINISTRAL_3_8B.id(); | ||
| this.format = format; |
There was a problem hiding this comment.
🔴 Critical — silent behavioral change to the production default
This changes the fallback model for every application that builds OllamaChatOptions without an explicit model. Users relying on the Mistral 7B default will silently receive responses from a completely different model — with no warning and no migration path.
The root cause (failing integration tests) is in the test setup, not the production default. The correct fix is to update OllamaChatModelIT to specify the new model explicitly, leaving this fallback unchanged.
If a default must change here, it also needs a migration note in the release notes and ideally a @since comment.
| @Mock | ||
| OllamaApi ollamaApi; | ||
| private OllamaApi ollamaApi; | ||
|
|
There was a problem hiding this comment.
🟢 Good — adding private to the @Mock field is correct Java style for test classes.
| @ValueSource(strings = { "LLAMA2", "MISTRAL", "CODELLAMA", "LLAMA3", "GEMMA" }) | ||
| void buildOllamaChatModelWithDifferentModels(String modelName) { | ||
| OllamaModel model = OllamaModel.valueOf(modelName); | ||
| @EnumSource(value = OllamaModel.class, names = { "LLAMA2", "MINISTRAL_3_8B", "CODELLAMA", "LLAMA3", "GEMMA" }) |
There was a problem hiding this comment.
🟢 Good improvement — replacing @ValueSource(strings = {...}) + OllamaModel.valueOf(modelName) with @EnumSource gives compile-time safety. Typos in enum names now fail at compile time instead of at runtime.
| // Test that the builder creates immutable instances | ||
| OllamaChatOptions options = OllamaChatOptions.builder().model(OllamaModel.MISTRAL).temperature(0.5).build(); | ||
| OllamaChatOptions options = OllamaChatOptions.builder() | ||
| .model(OllamaModel.MINISTRAL_3_14B) |
There was a problem hiding this comment.
🟡 Minor — inconsistent model size between tests
This test uses MINISTRAL_3_14B while buildOllamaChatModelWithConstructor uses MINISTRAL_3_8B. Since both tests only verify construction (not model behavior), there is no clear rationale for using two different sizes. Consider standardizing to one constant, or add a comment explaining the intent.
| @Test | ||
| void testBasicOptions() { | ||
| var b1 = OllamaChatOptions.builder().model("model").mainGPU(12); | ||
|
|
There was a problem hiding this comment.
🟡 Minor — removed test coverage without replacement
These two lines were the only ones exercising mainGPU() and verifying that the fluent builder accepts method calls in any order without throwing. Even as passive smoke-tests, removing them silently reduces coverage of the builder API.
Suggestion — convert to explicit assertions instead of deleting:
assertThat(OllamaChatOptions.builder().model("model").mainGPU(12).build()).isNotNull();
assertThat(OllamaChatOptions.builder().mainGPU(12).model("model").build()).isNotNull();| @@ -272,9 +268,10 @@ void testZeroValuesIncludedInMap() { | |||
|
|
|||
There was a problem hiding this comment.
🟢 Good — correct HTML Javadoc paragraph formatting. Nice catch.
|
Hi @ilayaperumalg, could you have a look at this PR? I have tried to fix Ollama's integration tests failures by using Mistral AI's recent models. |
91ce75c to
1ff695b
Compare
- Remove Mistral deprecated model - Add Ministral 3 model family - Polish unit tests Signed-off-by: Nicolas Krier <7557886+nicolaskrier@users.noreply.github.com>
1ff695b to
08137ca
Compare
|
Hi @sdeleuze, could you have a look at this PR? It is an attempt to fix failing integration tests for Ollama. I have removed only the model that isn't available anymore. |
Description
Explanations
Recently integration tests have failed for Ollama model due to model
mistralnot found:Error: Errors: Error: org.springframework.ai.ollama.OllamaChatModelIT.jsonStructuredOutputWithFormatOption Error: Run 1: OllamaChatModelIT.jsonStructuredOutputWithFormatOption:284 » NonTransientAi 404 - {"error":"model 'mistral' not found"} Error: Run 2: OllamaChatModelIT.jsonStructuredOutputWithFormatOption:284 » NonTransientAi 404 - {"error":"model 'mistral' not found"} Error: Run 3: OllamaChatModelIT.jsonStructuredOutputWithFormatOption:284 » NonTransientAi 404 - {"error":"model 'mistral' not found"} [INFO] Error: org.springframework.ai.ollama.OllamaChatModelIT.jsonStructuredOutputWithOutputSchemaOption Error: Run 1: OllamaChatModelIT.jsonStructuredOutputWithOutputSchemaOption:300 » NonTransientAi 404 - {"error":"model 'mistral' not found"} Error: Run 2: OllamaChatModelIT.jsonStructuredOutputWithOutputSchemaOption:300 » NonTransientAi 404 - {"error":"model 'mistral' not found"} Error: Run 3: OllamaChatModelIT.jsonStructuredOutputWithOutputSchemaOption:300 » NonTransientAi 404 - {"error":"model 'mistral' not found"} [INFO] Error: org.springframework.ai.ollama.OllamaChatModelIT.roleTest Error: Run 1: OllamaChatModelIT.roleTest:130 » NonTransientAi 404 - {"error":"model 'mistral' not found"} Error: Run 2: OllamaChatModelIT.roleTest:130 » NonTransientAi 404 - {"error":"model 'mistral' not found"} Error: Run 3: OllamaChatModelIT.roleTest:130 » NonTransientAi 404 - {"error":"model 'mistral' not found"}Proposed milestone
2.0.0