Skip to content

Update OllamaModel with Mistral AI's recent models#6319

Open
nicolaskrier wants to merge 1 commit into
spring-projects:mainfrom
nicolaskrier:update-ollama-model-with-mistral-recent-models
Open

Update OllamaModel with Mistral AI's recent models#6319
nicolaskrier wants to merge 1 commit into
spring-projects:mainfrom
nicolaskrier:update-ollama-model-with-mistral-recent-models

Conversation

@nicolaskrier

@nicolaskrier nicolaskrier commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

Description

  • Remove Mistral deprecated model
  • Add Ministral 3 model family
  • Polish unit tests

Explanations

Recently integration tests have failed for Ollama model due to model mistral not 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

@nicolaskrier nicolaskrier force-pushed the update-ollama-model-with-mistral-recent-models branch 3 times, most recently from 09c1049 to 91ce75c Compare June 7, 2026 11:13
@nicolaskrier nicolaskrier changed the title Update OllamaModel with Mistal AI's recent models Update OllamaModel with Mistral AI's recent models Jun 7, 2026
@kuntal1461

Copy link
Copy Markdown
Contributor

Code Review

The motivation here is correct — the mistral model being unavailable on Ollama's registry was breaking integration tests and this needs to be fixed. The new Ministral 3 additions are the right direction. However, there are two critical issues that need to be addressed before this can merge.


🔴 Critical: Hard removal of public enum constants without deprecation

MISTRAL and MISTRAL_NEMO are removed outright, which breaks compilation for any downstream code referencing OllamaModel.MISTRAL or OllamaModel.MISTRAL_NEMO.

The project's own precedent in MistralAiApi.ChatModel is clear:

@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 @Deprecated(forRemoval = true)) in this PR, and the hard removal should happen in a subsequent release.


🔴 Critical: Silent behavioral change to the default model

OllamaChatOptions.java line 96:

// 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 OllamaChatOptions without setting a model explicitly. Users who relied on the default will silently receive responses from a different model with no warning and no migration path.

The root cause of the failing tests is in the integration test setup, not in the production default. The correct fix is to update OllamaChatModelIT to set an explicit model, leaving the production fallback unchanged.


🟡 Major: Naming convention inconsistency

The existing Qwen3 constants in the same file use QWEN3_7B (no underscore between family name and generation number). The new constants use MINISTRAL_3_8B, which is inconsistent. Consistent naming would be MINISTRAL3_3B, MINISTRAL3_8B, MINISTRAL3_14B to match the established pattern.


🟡 Minor: Removed test coverage without replacement

In OllamaChatOptionsTests.testBasicOptions(), two builder lines were removed:

// Removed
var b1 = OllamaChatOptions.builder().model("model").mainGPU(12);
var b  = OllamaChatOptions.builder().mainGPU(12).model("model");

These were the only lines exercising mainGPU() and verifying that the fluent builder accepts method calls in any order. If they were considered dead code, they should be replaced with explicit assertions rather than silently deleted:

assertThat(OllamaChatOptions.builder().model("model").mainGPU(12).build()).isNotNull();
assertThat(OllamaChatOptions.builder().mainGPU(12).model("model").build()).isNotNull();

🟢 Good changes

  • @EnumSource over @ValueSource(strings = {...}) in the parameterized test is a genuine improvement — it catches invalid enum names at compile time rather than at runtime via OllamaModel.valueOf().
  • Adding private to the @Mock field is correct Java style.
  • The <p> tag fix in javadoc is correct HTML formatting.
  • Author attribution (@author Nicolas Krier) follows project contribution guidelines.

Suggested path forward

  1. Keep MISTRAL and MISTRAL_NEMO, annotate with @Deprecated(forRemoval = true), add the new constants alongside them.
  2. Revert the default model change in OllamaChatOptions; update OllamaChatModelIT directly to use a non-deprecated model.
  3. Rename MINISTRAL_3_8BMINISTRAL3_8B etc. to match QWEN3_7B.
  4. Restore or assert on the removed builder lines.

@kuntal1461 kuntal1461 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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"),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 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"),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
*/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 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;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 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" })

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 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)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Good — correct HTML Javadoc paragraph formatting. Nice catch.

@nicolaskrier

Copy link
Copy Markdown
Contributor Author

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.

https://github.com/spring-projects/spring-ai-integration-tests/actions/runs/27118143948/job/80029169371

@nicolaskrier nicolaskrier force-pushed the update-ollama-model-with-mistral-recent-models branch from 91ce75c to 1ff695b Compare June 9, 2026 17:35
- Remove Mistral deprecated model
- Add Ministral 3 model family
- Polish unit tests

Signed-off-by: Nicolas Krier <7557886+nicolaskrier@users.noreply.github.com>
@nicolaskrier nicolaskrier force-pushed the update-ollama-model-with-mistral-recent-models branch from 1ff695b to 08137ca Compare June 9, 2026 17:42
@nicolaskrier

Copy link
Copy Markdown
Contributor Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants