diff --git a/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaChatModel.java b/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaChatModel.java index f970249ab7e..b5743d80bfd 100644 --- a/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaChatModel.java +++ b/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaChatModel.java @@ -34,6 +34,7 @@ import org.springframework.ai.model.tool.ToolExecutionResult; import org.springframework.ai.tool.definition.ToolDefinition; import org.springframework.ai.util.json.JsonParser; +import org.springframework.lang.Nullable; import reactor.core.publisher.Flux; import org.springframework.ai.chat.messages.AssistantMessage; @@ -125,8 +126,9 @@ public class OllamaChatModel extends AbstractToolCallSupport implements ChatMode @Deprecated public OllamaChatModel(OllamaApi ollamaApi, OllamaOptions defaultOptions, - FunctionCallbackResolver functionCallbackResolver, List toolFunctionCallbacks, - ObservationRegistry observationRegistry, ModelManagementOptions modelManagementOptions) { + @Nullable FunctionCallbackResolver functionCallbackResolver, + @Nullable List toolFunctionCallbacks, ObservationRegistry observationRegistry, + ModelManagementOptions modelManagementOptions) { super(functionCallbackResolver, defaultOptions, toolFunctionCallbacks); Assert.notNull(ollamaApi, "ollamaApi must not be null"); Assert.notNull(defaultOptions, "defaultOptions must not be null"); diff --git a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatModelTests.java b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatModelTests.java index f5ca4e68636..dc5b9bfb725 100644 --- a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatModelTests.java +++ b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatModelTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 the original author or authors. + * Copyright 2023-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import java.time.Instant; import java.util.List; +import io.micrometer.observation.ObservationRegistry; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; @@ -27,10 +28,13 @@ import org.springframework.ai.chat.metadata.ChatResponseMetadata; import org.springframework.ai.chat.metadata.DefaultUsage; +import org.springframework.ai.chat.model.ChatModel; import org.springframework.ai.chat.model.ChatResponse; +import org.springframework.ai.model.tool.ToolCallingManager; import org.springframework.ai.ollama.api.OllamaApi; import org.springframework.ai.ollama.api.OllamaModel; import org.springframework.ai.ollama.api.OllamaOptions; +import org.springframework.ai.ollama.management.ModelManagementOptions; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -40,16 +44,39 @@ * @author Jihoon Kim * @author Christian Tzolov * @author Alexandros Pappas + * @author Thomas Vitale * @since 1.0.0 */ @ExtendWith(MockitoExtension.class) -public class OllamaChatModelTests { +class OllamaChatModelTests { @Mock OllamaApi ollamaApi; @Test - public void buildOllamaChatModel() { + void buildOllamaChatModelWithDeprecatedConstructor() { + ChatModel chatModel = new OllamaChatModel(this.ollamaApi, + OllamaOptions.builder().model(OllamaModel.MISTRAL).build(), null, null, ObservationRegistry.NOOP, + ModelManagementOptions.builder().build()); + assertThat(chatModel).isNotNull(); + } + + @Test + void buildOllamaChatModelWithConstructor() { + ChatModel chatModel = new OllamaChatModel(this.ollamaApi, + OllamaOptions.builder().model(OllamaModel.MISTRAL).build(), ToolCallingManager.builder().build(), + ObservationRegistry.NOOP, ModelManagementOptions.builder().build()); + assertThat(chatModel).isNotNull(); + } + + @Test + void buildOllamaChatModelWithBuilder() { + ChatModel chatModel = OllamaChatModel.builder().ollamaApi(ollamaApi).build(); + assertThat(chatModel).isNotNull(); + } + + @Test + void buildOllamaChatModel() { Exception exception = assertThrows(IllegalArgumentException.class, () -> OllamaChatModel.builder() .ollamaApi(this.ollamaApi) @@ -60,7 +87,7 @@ public void buildOllamaChatModel() { } @Test - public void buildChatResponseMetadata() { + void buildChatResponseMetadata() { Long evalDuration = 1000L; Integer evalCount = 101; @@ -83,7 +110,7 @@ public void buildChatResponseMetadata() { } @Test - public void buildChatResponseMetadataAggregationWithNonEmptyMetadata() { + void buildChatResponseMetadataAggregationWithNonEmptyMetadata() { Long evalDuration = 1000L; Integer evalCount = 101; diff --git a/spring-ai-core/src/main/java/org/springframework/ai/model/tool/LegacyToolCallingManager.java b/spring-ai-core/src/main/java/org/springframework/ai/model/tool/LegacyToolCallingManager.java index f0356bcacfa..4176c6c7c22 100644 --- a/spring-ai-core/src/main/java/org/springframework/ai/model/tool/LegacyToolCallingManager.java +++ b/spring-ai-core/src/main/java/org/springframework/ai/model/tool/LegacyToolCallingManager.java @@ -55,6 +55,7 @@ @Deprecated public class LegacyToolCallingManager implements ToolCallingManager { + @Nullable private final FunctionCallbackResolver functionCallbackResolver; private final Map functionCallbacks = new HashMap<>(); @@ -64,11 +65,11 @@ public class LegacyToolCallingManager implements ToolCallingManager { .build(); public LegacyToolCallingManager(@Nullable FunctionCallbackResolver functionCallbackResolver, - List functionCallbacks) { - Assert.notNull(functionCallbacks, "functionCallbacks cannot be null"); - Assert.noNullElements(functionCallbacks.toArray(), "functionCallbacks cannot contain null elements"); + @Nullable List functionCallbacks) { this.functionCallbackResolver = functionCallbackResolver; - functionCallbacks.forEach(toolCallback -> this.functionCallbacks.put(toolCallback.getName(), toolCallback)); + if (functionCallbacks != null) { + functionCallbacks.forEach(toolCallback -> this.functionCallbacks.put(toolCallback.getName(), toolCallback)); + } } @Override