diff --git a/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaChatClient.java b/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaChatClient.java index 26ef069ba..273d98866 100644 --- a/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaChatClient.java +++ b/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaChatClient.java @@ -87,6 +87,7 @@ public class OllamaChatClient implements ChatClient, StreamingChatClient { /** * @deprecated Use {@link OllamaOptions} constructor instead. */ + @Deprecated public OllamaChatClient withDefaultOptions(OllamaOptions options) { this.defaultOptions = options; return this; diff --git a/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaEmbeddingClient.java b/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaEmbeddingClient.java index 296498e50..1748709aa 100644 --- a/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaEmbeddingClient.java +++ b/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaEmbeddingClient.java @@ -66,6 +66,11 @@ public class OllamaEmbeddingClient extends AbstractEmbeddingClient { this.ollamaApi = ollamaApi; } + public OllamaEmbeddingClient(OllamaApi ollamaApi, OllamaOptions defaultOptions) { + this.ollamaApi = ollamaApi; + this.defaultOptions = defaultOptions; + } + /** * @deprecated Use {@link OllamaOptions#setModel} instead. */ @@ -75,6 +80,10 @@ public class OllamaEmbeddingClient extends AbstractEmbeddingClient { return this; } + /** + * @deprecated Use {@link OllamaOptions} constructor instead. + */ + @Deprecated public OllamaEmbeddingClient withDefaultOptions(OllamaOptions options) { this.defaultOptions = options; return this; diff --git a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatClientMultimodalIT.java b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatClientMultimodalIT.java index 0061ea4b3..8599cfe9e 100644 --- a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatClientMultimodalIT.java +++ b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatClientMultimodalIT.java @@ -25,8 +25,8 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.ollama.OllamaContainer; -import org.springframework.ai.chat.ChatResponse; import org.springframework.ai.chat.messages.Media; import org.springframework.ai.chat.messages.UserMessage; import org.springframework.ai.chat.prompt.Prompt; @@ -38,7 +38,6 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.Bean; import org.springframework.core.io.ClassPathResource; import org.springframework.util.MimeTypeUtils; -import org.testcontainers.ollama.OllamaContainer; import static org.assertj.core.api.Assertions.assertThat; diff --git a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatRequestTests.java b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatRequestTests.java index 1a6b720c7..f78b8f2fc 100644 --- a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatRequestTests.java +++ b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatRequestTests.java @@ -30,7 +30,7 @@ import static org.assertj.core.api.Assertions.assertThat; */ public class OllamaChatRequestTests { - OllamaChatClient client = new OllamaChatClient(new OllamaApi()).withDefaultOptions( + OllamaChatClient client = new OllamaChatClient(new OllamaApi(), new OllamaOptions().withModel("MODEL_NAME").withTopK(99).withTemperature(66.6f).withNumGPU(1)); @Test @@ -105,8 +105,8 @@ public class OllamaChatRequestTests { @Test public void createRequestWithDefaultOptionsModelOverride() { - OllamaChatClient client2 = new OllamaChatClient(new OllamaApi()) - .withDefaultOptions(new OllamaOptions().withModel("DEFAULT_OPTIONS_MODEL")); + OllamaChatClient client2 = new OllamaChatClient(new OllamaApi(), + new OllamaOptions().withModel("DEFAULT_OPTIONS_MODEL")); var request = client2.ollamaChatRequest(new Prompt("Test message content"), true); diff --git a/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatClient.java b/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatClient.java index dfb2a14bc..4091cdd36 100644 --- a/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatClient.java +++ b/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatClient.java @@ -99,7 +99,11 @@ public class VertexAiGeminiChatClient GEMINI_PRO_VISION("gemini-pro-vision"), - GEMINI_PRO("gemini-pro"); + GEMINI_PRO("gemini-pro"), + + GEMINI_PRO_1_5_PRO("gemini-1.5-pro-preview-0514"), + + GEMINI_PRO_1_5_FLASH("gemini-1.5-flash-preview-0514"); ChatModel(String value) { this.value = value; diff --git a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/function/VertexAiGeminiChatClientFunctionCallingIT.java b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/function/VertexAiGeminiChatClientFunctionCallingIT.java index 4b424db2c..2026729e3 100644 --- a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/function/VertexAiGeminiChatClientFunctionCallingIT.java +++ b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/function/VertexAiGeminiChatClientFunctionCallingIT.java @@ -68,7 +68,7 @@ public class VertexAiGeminiChatClientFunctionCallingIT { } @Test - @Disabled("Google Vertex AI degraded support for parallel function calls") + // @Disabled("Google Vertex AI degraded support for parallel function calls") public void functionCallExplicitOpenApiSchema() { UserMessage userMessage = new UserMessage( @@ -98,7 +98,8 @@ public class VertexAiGeminiChatClientFunctionCallingIT { """; var promptOptions = VertexAiGeminiChatOptions.builder() - .withModel(VertexAiGeminiChatClient.ChatModel.GEMINI_PRO.getValue()) + // .withModel(VertexAiGeminiChatClient.ChatModel.GEMINI_PRO.getValue()) + .withModel(VertexAiGeminiChatClient.ChatModel.GEMINI_PRO_1_5_PRO.getValue()) .withFunctionCallbacks(List.of(FunctionCallbackWrapper.builder(new MockWeatherService()) .withName("get_current_weather") .withDescription("Get the current weather in a given location") @@ -125,7 +126,8 @@ public class VertexAiGeminiChatClientFunctionCallingIT { List messages = new ArrayList<>(List.of(userMessage)); var promptOptions = VertexAiGeminiChatOptions.builder() - .withModel(VertexAiGeminiChatClient.ChatModel.GEMINI_PRO.getValue()) + .withModel(VertexAiGeminiChatClient.ChatModel.GEMINI_PRO_1_5_PRO.getValue()) + // .withModel(VertexAiGeminiChatClient.ChatModel.GEMINI_PRO.getValue()) .withFunctionCallbacks(List.of( FunctionCallbackWrapper.builder(new MockWeatherService()) .withSchemaType(SchemaType.OPEN_API_SCHEMA) diff --git a/pom.xml b/pom.xml index 873b77ce2..32af3af00 100644 --- a/pom.xml +++ b/pom.xml @@ -129,7 +129,7 @@ 2.16.1 0.26.0 1.17.0 - 26.37.0 + 26.39.0 1.9.1 2.0.5 9.20.0 diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/ollama-chat.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/ollama-chat.adoc index 8071a745d..de61f8851 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/ollama-chat.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/ollama-chat.adoc @@ -249,8 +249,8 @@ Next, create an `OllamaChatClient` instance and use it to text generations reque ---- var ollamaApi = new OllamaApi(); -var chatClient = new OllamaChatClient(ollamaApi).withModel(MODEL) - .withDefaultOptions(OllamaOptions.create() +var chatClient = new OllamaChatClient(ollamaApi, + OllamaOptions.create() .withModel(OllamaOptions.DEFAULT_MODEL) .withTemperature(0.9f)); @@ -274,6 +274,8 @@ image::ollama-chat-completion-api.jpg[OllamaApi Chat Completion API Diagram, 800 Here is a simple snippet showing how to use the API programmatically: +NOTE: The `OllamaApi` is low level api and is not recommended for direct use. Use the `OllamaChatClient` instead. + [source,java] ---- OllamaApi ollamaApi = diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/ollama/OllamaAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/ollama/OllamaAutoConfiguration.java index d3378ec88..8b788e73b 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/ollama/OllamaAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/ollama/OllamaAutoConfiguration.java @@ -57,9 +57,7 @@ public class OllamaAutoConfiguration { @ConditionalOnProperty(prefix = OllamaChatProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true) public OllamaChatClient ollamaChatClient(OllamaApi ollamaApi, OllamaChatProperties properties) { - - return new OllamaChatClient(ollamaApi).withModel(properties.getModel()) - .withDefaultOptions(properties.getOptions()); + return new OllamaChatClient(ollamaApi, properties.getOptions()); } @Bean @@ -68,8 +66,7 @@ public class OllamaAutoConfiguration { matchIfMissing = true) public OllamaEmbeddingClient ollamaEmbeddingClient(OllamaApi ollamaApi, OllamaEmbeddingProperties properties) { - return new OllamaEmbeddingClient(ollamaApi).withModel(properties.getModel()) - .withDefaultOptions(properties.getOptions()); + return new OllamaEmbeddingClient(ollamaApi, properties.getOptions()); } private static class PropertiesOllamaConnectionDetails implements OllamaConnectionDetails { diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vertexai/gemini/tool/FunctionCallWithFunctionBeanIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vertexai/gemini/tool/FunctionCallWithFunctionBeanIT.java index d2066f0b2..908445675 100644 --- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vertexai/gemini/tool/FunctionCallWithFunctionBeanIT.java +++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vertexai/gemini/tool/FunctionCallWithFunctionBeanIT.java @@ -54,9 +54,10 @@ class FunctionCallWithFunctionBeanIT { @Test void functionCallTest() { - contextRunner - .withPropertyValues("spring.ai.vertex.ai.gemini.chat.options.model=" - + VertexAiGeminiChatClient.ChatModel.GEMINI_PRO.getValue()) + contextRunner.withPropertyValues("spring.ai.vertex.ai.gemini.chat.options.model=" + // + VertexAiGeminiChatClient.ChatModel.GEMINI_PRO.getValue()) + + VertexAiGeminiChatClient.ChatModel.GEMINI_PRO_1_5_PRO.getValue()) + // + VertexAiGeminiChatClient.ChatModel.GEMINI_PRO_1_5_FLASH.getValue()) .run(context -> { VertexAiGeminiChatClient chatClient = context.getBean(VertexAiGeminiChatClient.class); @@ -67,15 +68,22 @@ class FunctionCallWithFunctionBeanIT { If the information was not fetched call the function again. Repeat at most 3 times. """); var userMessage = new UserMessage( - "What's the weather like in San Francisco, Paris and in Tokyo (Japan)?"); + // "What's the weather like in San Francisco, Paris and in Tokyo? + // Please let me know how many function calls you've preformed."); + "What's the weather like in San Francisco, Paris and in Tokyo?"); ChatResponse response = chatClient.call(new Prompt(List.of(systemMessage, userMessage), VertexAiGeminiChatOptions.builder().withFunction("weatherFunction").build())); + // ChatResponse response = chatClient.call(new + // Prompt(List.of(userMessage), + // VertexAiGeminiChatOptions.builder().withFunction("weatherFunction").build())); logger.info("Response: {}", response); assertThat(response.getResult().getOutput().getContent()).contains("30", "10", "15"); + Thread.sleep(10000); + response = chatClient.call(new Prompt(List.of(systemMessage, userMessage), VertexAiGeminiChatOptions.builder().withFunction("weatherFunction3").build()));