From d5d21bfb6451100f615c341998bd407de80a4c6b Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Sun, 18 Feb 2024 18:08:46 +0800 Subject: [PATCH 01/49] Support Azure OpenAI --- .../pom.xml | 73 +++++++++++ .../azure/openai/spring/AutoConfig.java | 92 +++++++++++++ .../openai/spring/ChatModelProperties.java | 31 +++++ .../spring/EmbeddingModelProperties.java | 21 +++ .../openai/spring/ImageModelProperties.java | 27 ++++ .../azure/openai/spring/Properties.java | 26 ++++ .../main/resources/META-INF/spring.factories | 1 + ...ot.autoconfigure.AutoConfiguration.imports | 1 + .../azure/openai/AutoConfigIT.java | 121 ++++++++++++++++++ pom.xml | 1 + 10 files changed, 394 insertions(+) create mode 100644 langchain4j-azure-open-ai-spring-boot-starter/pom.xml create mode 100644 langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java create mode 100644 langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java create mode 100644 langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java create mode 100644 langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java create mode 100644 langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java create mode 100644 langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring.factories create mode 100644 langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java diff --git a/langchain4j-azure-open-ai-spring-boot-starter/pom.xml b/langchain4j-azure-open-ai-spring-boot-starter/pom.xml new file mode 100644 index 0000000..81727dd --- /dev/null +++ b/langchain4j-azure-open-ai-spring-boot-starter/pom.xml @@ -0,0 +1,73 @@ + + + 4.0.0 + + + dev.langchain4j + langchain4j-spring + 0.27.0-SNAPSHOT + ../pom.xml + + + langchain4j-azure-open-ai-spring-boot-starter + LangChain4j Spring Boot starter for Azure OpenAI + jar + + + + + dev.langchain4j + langchain4j-azure-open-ai + ${project.version} + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-autoconfigure-processor + true + + + + + org.projectlombok + lombok + provided + + + com.azure + azure-core + 1.45.1 + + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + Apache-2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + A business-friendly OSS license + + + + \ No newline at end of file diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java new file mode 100644 index 0000000..d0bf828 --- /dev/null +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java @@ -0,0 +1,92 @@ +package dev.langchain4j.azure.openai.spring; + +import com.azure.core.util.Configuration; +import dev.langchain4j.model.azure.*; +import com.azure.core.http.ProxyOptions; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; + +import static dev.langchain4j.azure.openai.spring.Properties.PREFIX; + +@AutoConfiguration +@EnableConfigurationProperties(Properties.class) +public class AutoConfig { + + @Bean + @ConditionalOnProperty(PREFIX + ".chat-model.api-key") + AzureOpenAiChatModel openAiChatModel(Properties properties) { + ChatModelProperties chatModelProperties = properties.getChatModel(); + return AzureOpenAiChatModel.builder() + .endpoint(chatModelProperties.getEndpoint()) + .apiKey(chatModelProperties.getApiKey()) + .deploymentName(chatModelProperties.getDeploymentName()) + .temperature(chatModelProperties.getTemperature()) + .topP(chatModelProperties.getTopP()) + .stop(chatModelProperties.getStop()) + .maxTokens(chatModelProperties.getMaxTokens()) + .presencePenalty(chatModelProperties.getPresencePenalty()) + .frequencyPenalty(chatModelProperties.getFrequencyPenalty()) + .timeout(chatModelProperties.getTimeout()) + .maxRetries(chatModelProperties.getMaxRetries()) + .proxyOptions(ProxyOptions.fromConfiguration(Configuration.getGlobalConfiguration())) + .logRequestsAndResponses(chatModelProperties.getLogRequestsAndResponses() != null && chatModelProperties.getLogRequestsAndResponses()) + .build(); + } + + @Bean + @ConditionalOnProperty(PREFIX + ".streaming-chat-model.api-key") + AzureOpenAiStreamingChatModel openAiStreamingChatModel(Properties properties) { + ChatModelProperties chatModelProperties = properties.getStreamingChatModel(); + return AzureOpenAiStreamingChatModel.builder() + .endpoint(chatModelProperties.getEndpoint()) + .apiKey(chatModelProperties.getApiKey()) + .deploymentName(chatModelProperties.getDeploymentName()) + .temperature(chatModelProperties.getTemperature()) + .topP(chatModelProperties.getTopP()) + .stop(chatModelProperties.getStop()) + .maxTokens(chatModelProperties.getMaxTokens()) + .presencePenalty(chatModelProperties.getPresencePenalty()) + .frequencyPenalty(chatModelProperties.getFrequencyPenalty()) + .timeout(chatModelProperties.getTimeout()) + .proxyOptions(ProxyOptions.fromConfiguration(Configuration.getGlobalConfiguration())) + .logRequestsAndResponses(chatModelProperties.getLogRequestsAndResponses() != null && chatModelProperties.getLogRequestsAndResponses()) + .build(); + } + + @Bean + @ConditionalOnProperty(PREFIX + ".embedding-model.api-key") + AzureOpenAiEmbeddingModel openAiEmbeddingModel(Properties properties) { + EmbeddingModelProperties embeddingModelProperties = properties.getEmbeddingModel(); + return AzureOpenAiEmbeddingModel.builder() + .endpoint(embeddingModelProperties.getEndpoint()) + .apiKey(embeddingModelProperties.getApiKey()) + .deploymentName(embeddingModelProperties.getDeploymentName()) + .timeout(embeddingModelProperties.getTimeout()) + .maxRetries(embeddingModelProperties.getMaxRetries()) + .proxyOptions(ProxyOptions.fromConfiguration(Configuration.getGlobalConfiguration())) + .logRequestsAndResponses(embeddingModelProperties.getLogRequestsAndResponses() != null && embeddingModelProperties.getLogRequestsAndResponses()) + .build(); + } + + @Bean + @ConditionalOnProperty(PREFIX + ".image-model.api-key") + AzureOpenAiImageModel openAiImageModel(Properties properties) { + ImageModelProperties imageModelProperties = properties.getImageModel(); + return AzureOpenAiImageModel.builder() + .endpoint(imageModelProperties.getEndpoint()) + .apiKey(imageModelProperties.getApiKey()) + .deploymentName(imageModelProperties.getDeploymentName()) + .size(imageModelProperties.getSize()) + .quality(imageModelProperties.getQuality()) + .style(imageModelProperties.getStyle()) + .user(imageModelProperties.getUser()) + .responseFormat(imageModelProperties.getResponseFormat()) + .timeout(imageModelProperties.getTimeout()) + .maxRetries(imageModelProperties.getMaxRetries()) + .proxyOptions(ProxyOptions.fromConfiguration(Configuration.getGlobalConfiguration())) + .logRequestsAndResponses(imageModelProperties.getLogRequestsAndResponses()!=null&&imageModelProperties.getLogRequestsAndResponses()) + .build(); + } +} \ No newline at end of file diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java new file mode 100644 index 0000000..b2a4e0a --- /dev/null +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java @@ -0,0 +1,31 @@ +package dev.langchain4j.azure.openai.spring; + +import lombok.Getter; +import lombok.Setter; + +import java.time.Duration; +import java.util.List; +import java.util.Map; + +@Getter +@Setter +class ChatModelProperties { + + String endpoint; + String apiKey; + String organizationId; + String deploymentName; + Double temperature; + Double topP; + List stop; + Integer maxTokens; + Double presencePenalty; + Double frequencyPenalty; + Map logitBias; + String responseFormat; + Integer seed; + String user; + Duration timeout; + Integer maxRetries; + Boolean logRequestsAndResponses; +} \ No newline at end of file diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java new file mode 100644 index 0000000..f3c2a7c --- /dev/null +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java @@ -0,0 +1,21 @@ +package dev.langchain4j.azure.openai.spring; + +import lombok.Getter; +import lombok.Setter; + +import java.time.Duration; + +@Getter +@Setter +class EmbeddingModelProperties { + + String endpoint; + String apiKey; + String organizationId; + String deploymentName; + Integer dimensions; + String user; + Duration timeout; + Integer maxRetries; + Boolean logRequestsAndResponses; +} \ No newline at end of file diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java new file mode 100644 index 0000000..41d15ea --- /dev/null +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java @@ -0,0 +1,27 @@ +package dev.langchain4j.azure.openai.spring; + +import lombok.Getter; +import lombok.Setter; + +import java.nio.file.Path; +import java.time.Duration; + +@Getter +@Setter +class ImageModelProperties { + + String endpoint; + String apiKey; + String organizationId; + String deploymentName; + String size; + String quality; + String style; + String user; + String responseFormat; + Duration timeout; + Integer maxRetries; + Boolean logRequestsAndResponses; + Boolean withPersisting; + Path persistTo; +} \ No newline at end of file diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java new file mode 100644 index 0000000..e2e6995 --- /dev/null +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java @@ -0,0 +1,26 @@ +package dev.langchain4j.azure.openai.spring; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.NestedConfigurationProperty; + +@Getter +@Setter +@ConfigurationProperties(prefix = Properties.PREFIX) +public class Properties { + + static final String PREFIX = "langchain4j.azure.open-ai"; + + @NestedConfigurationProperty + ChatModelProperties chatModel; + + @NestedConfigurationProperty + ChatModelProperties streamingChatModel; + + @NestedConfigurationProperty + EmbeddingModelProperties embeddingModel; + + @NestedConfigurationProperty + ImageModelProperties imageModel; +} diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring.factories b/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..b5b2137 --- /dev/null +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring.factories @@ -0,0 +1 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=dev.langchain4j.azure.openai.spring.AutoConfig \ No newline at end of file diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..4ab7c73 --- /dev/null +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +dev.langchain4j.azure.openai.spring.AutoConfig \ No newline at end of file diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java b/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java new file mode 100644 index 0000000..197f8d2 --- /dev/null +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java @@ -0,0 +1,121 @@ +package dev.langchain4j.azure.openai; + +import dev.langchain4j.data.message.AiMessage; +import dev.langchain4j.model.StreamingResponseHandler; +import dev.langchain4j.model.azure.*; +import dev.langchain4j.model.chat.ChatLanguageModel; +import dev.langchain4j.model.chat.StreamingChatLanguageModel; +import dev.langchain4j.model.embedding.EmbeddingModel; +import dev.langchain4j.model.image.ImageModel; +import dev.langchain4j.model.output.Response; +import dev.langchain4j.azure.openai.spring.AutoConfig; +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; + +import java.util.concurrent.CompletableFuture; + +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.assertj.core.api.Assertions.assertThat; + +class AutoConfigIT { + + private static final String AZURE_OPENAI_KEY = System.getenv("AZURE_OPENAI_KEY"); + private static final String AZURE_OPENAI_ENDPOINT = System.getenv("AZURE_OPENAI_ENDPOINT"); + private static final String AZURE_OPENAI_DEPLOYMENT_NAME = System.getenv("AZURE_OPENAI_DEPLOYMENT_NAME"); + private static final String AZURE_DALLE3_DEPLOYMENT_NAME = System.getenv("AZURE_DALLE3_DEPLOYMENT_NAME"); + private static final String AZURE_EMBEDDING_DEPLOYMENT_NAME = System.getenv("AZURE_EMBEDDING_DEPLOYMENT_NAME"); + + ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(AutoConfig.class)); + + @Test + void should_provide_chat_model() { + contextRunner + .withPropertyValues( + "langchain4j.azure.open-ai.chat-model.api-key=" + AZURE_OPENAI_KEY, + "langchain4j.azure.open-ai.chat-model.endpoint=" + AZURE_OPENAI_ENDPOINT, + "langchain4j.azure.open-ai.chat-model.deployment-name=" + AZURE_OPENAI_DEPLOYMENT_NAME, + "langchain4j.azure.open-ai.chat-model.max-tokens=20" + ) + .run(context -> { + + ChatLanguageModel chatLanguageModel = context.getBean(AzureOpenAiChatModel.class); + assertThat(chatLanguageModel).isInstanceOf(AzureOpenAiChatModel.class); + assertThat(chatLanguageModel.generate("What is the capital of Germany?")).contains("Berlin"); + + assertThat(context.getBean(AzureOpenAiChatModel.class)).isSameAs(chatLanguageModel); + }); + } + + @Test + void should_provide_streaming_chat_model() { + contextRunner + .withPropertyValues( + "langchain4j.azure.open-ai.streaming-chat-model.api-key=" + AZURE_OPENAI_KEY, + "langchain4j.azure.open-ai.streaming-chat-model.endpoint=" + AZURE_OPENAI_ENDPOINT, + "langchain4j.azure.open-ai.streaming-chat-model.deployment-name=" + AZURE_OPENAI_DEPLOYMENT_NAME, + "langchain4j.azure.open-ai.streaming-chat-model.max-tokens=20" + ) + .run(context -> { + + StreamingChatLanguageModel streamingChatLanguageModel = context.getBean(AzureOpenAiStreamingChatModel.class); + assertThat(streamingChatLanguageModel).isInstanceOf(AzureOpenAiStreamingChatModel.class); + CompletableFuture> future = new CompletableFuture<>(); + streamingChatLanguageModel.generate("What is the capital of Germany?", new StreamingResponseHandler() { + + @Override + public void onNext(String token) { + } + + @Override + public void onComplete(Response response) { + future.complete(response); + } + + @Override + public void onError(Throwable error) { + } + }); + Response response = future.get(60, SECONDS); + assertThat(response.content().text()).contains("Berlin"); + + assertThat(context.getBean(AzureOpenAiStreamingChatModel.class)).isSameAs(streamingChatLanguageModel); + }); + } + + + @Test + void should_provide_embedding_model() { + contextRunner + .withPropertyValues("langchain4j.azure.open-ai.embedding-model.api-key=" + AZURE_OPENAI_KEY, + "langchain4j.azure.open-ai.embedding-model.endpoint=" + AZURE_OPENAI_ENDPOINT, + "langchain4j.azure.open-ai.embedding-model.deployment-name=" + AZURE_EMBEDDING_DEPLOYMENT_NAME) + .run(context -> { + + EmbeddingModel embeddingModel = context.getBean(AzureOpenAiEmbeddingModel.class); + assertThat(embeddingModel).isInstanceOf(AzureOpenAiEmbeddingModel.class); + assertThat(embeddingModel.embed("hi").content().dimension()).isEqualTo(1536); + + assertThat(context.getBean(AzureOpenAiEmbeddingModel.class)).isSameAs(embeddingModel); + }); + } + + @Test + void should_provide_image_model() { + contextRunner + .withPropertyValues( + "langchain4j.azure.open-ai.image-model.api-key=" + AZURE_OPENAI_KEY, + "langchain4j.azure.open-ai.image-model.endpoint=" + AZURE_OPENAI_ENDPOINT, + "langchain4j.azure.open-ai.image-model.deployment-name=" + AZURE_DALLE3_DEPLOYMENT_NAME + ) + .run(context -> { + + ImageModel imageModel = context.getBean(ImageModel.class); + assertThat(imageModel).isInstanceOf(AzureOpenAiImageModel.class); + assertThat(imageModel.generate("banana").content().url()).isNotNull(); + + assertThat(context.getBean(AzureOpenAiImageModel.class)).isSameAs(imageModel); + }); + } +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index 242f7ad..ec8aae6 100644 --- a/pom.xml +++ b/pom.xml @@ -16,6 +16,7 @@ langchain4j-ollama-spring-boot-starter langchain4j-open-ai-spring-boot-starter + langchain4j-azure-open-ai-spring-boot-starter From bba8850958d4c70a999459203c50dcb1b4bce208 Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Fri, 15 Mar 2024 09:36:38 +0800 Subject: [PATCH 02/49] Update langchain4j-azure-open-ai-spring-boot-starter/pom.xml Co-authored-by: LangChain4j --- langchain4j-azure-open-ai-spring-boot-starter/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langchain4j-azure-open-ai-spring-boot-starter/pom.xml b/langchain4j-azure-open-ai-spring-boot-starter/pom.xml index 81727dd..012827d 100644 --- a/langchain4j-azure-open-ai-spring-boot-starter/pom.xml +++ b/langchain4j-azure-open-ai-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ dev.langchain4j langchain4j-spring - 0.27.0-SNAPSHOT + 0.29.0-SNAPSHOT ../pom.xml From 2b8167180e3bb5bca85e469ef47c1a1f710eedc6 Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Fri, 15 Mar 2024 09:38:52 +0800 Subject: [PATCH 03/49] Update langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java Co-authored-by: LangChain4j --- .../test/java/dev/langchain4j/azure/openai/AutoConfigIT.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java b/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java index 197f8d2..0180cd2 100644 --- a/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java @@ -40,7 +40,7 @@ void should_provide_chat_model() { ) .run(context -> { - ChatLanguageModel chatLanguageModel = context.getBean(AzureOpenAiChatModel.class); + ChatLanguageModel chatLanguageModel = context.getBean(ChatLanguageModel.class); assertThat(chatLanguageModel).isInstanceOf(AzureOpenAiChatModel.class); assertThat(chatLanguageModel.generate("What is the capital of Germany?")).contains("Berlin"); From 9d01db08a466d68dc35d2d696514ac93a4a9a52f Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Fri, 15 Mar 2024 09:39:26 +0800 Subject: [PATCH 04/49] Update langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java Co-authored-by: LangChain4j --- .../test/java/dev/langchain4j/azure/openai/AutoConfigIT.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java b/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java index 0180cd2..9fc5196 100644 --- a/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java @@ -93,7 +93,7 @@ void should_provide_embedding_model() { "langchain4j.azure.open-ai.embedding-model.deployment-name=" + AZURE_EMBEDDING_DEPLOYMENT_NAME) .run(context -> { - EmbeddingModel embeddingModel = context.getBean(AzureOpenAiEmbeddingModel.class); + EmbeddingModel embeddingModel = context.getBean(EmbeddingModel.class); assertThat(embeddingModel).isInstanceOf(AzureOpenAiEmbeddingModel.class); assertThat(embeddingModel.embed("hi").content().dimension()).isEqualTo(1536); From 2f0053abdaf0a4f1d3ad534d54c7d2e0ec9a0645 Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Fri, 15 Mar 2024 09:39:38 +0800 Subject: [PATCH 05/49] Update langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java Co-authored-by: LangChain4j --- .../test/java/dev/langchain4j/azure/openai/AutoConfigIT.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java b/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java index 9fc5196..869c403 100644 --- a/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java @@ -59,7 +59,7 @@ void should_provide_streaming_chat_model() { ) .run(context -> { - StreamingChatLanguageModel streamingChatLanguageModel = context.getBean(AzureOpenAiStreamingChatModel.class); + StreamingChatLanguageModel streamingChatLanguageModel = context.getBean(StreamingChatLanguageModel.class); assertThat(streamingChatLanguageModel).isInstanceOf(AzureOpenAiStreamingChatModel.class); CompletableFuture> future = new CompletableFuture<>(); streamingChatLanguageModel.generate("What is the capital of Germany?", new StreamingResponseHandler() { From e0de25c25a7126c3404f629dc103011f8b834ca2 Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Fri, 15 Mar 2024 12:20:05 +0800 Subject: [PATCH 06/49] remove the azure core lib --- langchain4j-azure-open-ai-spring-boot-starter/pom.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/langchain4j-azure-open-ai-spring-boot-starter/pom.xml b/langchain4j-azure-open-ai-spring-boot-starter/pom.xml index 012827d..ca8eb49 100644 --- a/langchain4j-azure-open-ai-spring-boot-starter/pom.xml +++ b/langchain4j-azure-open-ai-spring-boot-starter/pom.xml @@ -40,11 +40,6 @@ lombok provided - - com.azure - azure-core - 1.45.1 - From a423557cfd611f528069242f17391f52aa77cd0e Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Fri, 15 Mar 2024 13:38:43 +0800 Subject: [PATCH 07/49] Add Azure AI Search support --- .../main/resources/META-INF/spring.factories | 1 - ...ot.autoconfigure.AutoConfiguration.imports | 1 - .../pom.xml | 9 +++- .../azure/aisearch/spring/AutoConfig.java | 25 +++++++++++ .../azure/aisearch/spring/Properties.java | 18 ++++++++ .../azure/openai/spring/AutoConfig.java | 0 .../openai/spring/ChatModelProperties.java | 0 .../spring/EmbeddingModelProperties.java | 0 .../openai/spring/ImageModelProperties.java | 0 .../azure/openai/spring/Properties.java | 0 .../main/resources/META-INF/spring.factories | 3 ++ ...ot.autoconfigure.AutoConfiguration.imports | 2 + .../azure/aisearch/spring/AutoConfigIT.java | 41 +++++++++++++++++++ .../azure/openai/AutoConfigIT.java | 0 pom.xml | 4 +- 15 files changed, 98 insertions(+), 6 deletions(-) delete mode 100644 langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring.factories delete mode 100644 langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports rename {langchain4j-azure-open-ai-spring-boot-starter => langchain4j-azure-spring-boot-starter}/pom.xml (86%) create mode 100644 langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java create mode 100644 langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java rename {langchain4j-azure-open-ai-spring-boot-starter => langchain4j-azure-spring-boot-starter}/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java (100%) rename {langchain4j-azure-open-ai-spring-boot-starter => langchain4j-azure-spring-boot-starter}/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java (100%) rename {langchain4j-azure-open-ai-spring-boot-starter => langchain4j-azure-spring-boot-starter}/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java (100%) rename {langchain4j-azure-open-ai-spring-boot-starter => langchain4j-azure-spring-boot-starter}/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java (100%) rename {langchain4j-azure-open-ai-spring-boot-starter => langchain4j-azure-spring-boot-starter}/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java (100%) create mode 100644 langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring.factories create mode 100644 langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 langchain4j-azure-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java rename {langchain4j-azure-open-ai-spring-boot-starter => langchain4j-azure-spring-boot-starter}/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java (100%) diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring.factories b/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring.factories deleted file mode 100644 index b5b2137..0000000 --- a/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=dev.langchain4j.azure.openai.spring.AutoConfig \ No newline at end of file diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports deleted file mode 100644 index 4ab7c73..0000000 --- a/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ /dev/null @@ -1 +0,0 @@ -dev.langchain4j.azure.openai.spring.AutoConfig \ No newline at end of file diff --git a/langchain4j-azure-open-ai-spring-boot-starter/pom.xml b/langchain4j-azure-spring-boot-starter/pom.xml similarity index 86% rename from langchain4j-azure-open-ai-spring-boot-starter/pom.xml rename to langchain4j-azure-spring-boot-starter/pom.xml index ca8eb49..0609661 100644 --- a/langchain4j-azure-open-ai-spring-boot-starter/pom.xml +++ b/langchain4j-azure-spring-boot-starter/pom.xml @@ -11,8 +11,8 @@ ../pom.xml - langchain4j-azure-open-ai-spring-boot-starter - LangChain4j Spring Boot starter for Azure OpenAI + langchain4j-azure-spring-boot-starter + LangChain4j Spring Boot starter for Azure jar @@ -22,6 +22,11 @@ langchain4j-azure-open-ai ${project.version} + + dev.langchain4j + langchain4j-azure-ai-search + ${project.version} + org.springframework.boot diff --git a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java b/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java new file mode 100644 index 0000000..703f06a --- /dev/null +++ b/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java @@ -0,0 +1,25 @@ +package dev.langchain4j.azure.aisearch.spring; + +import dev.langchain4j.store.embedding.azure.search.AzureAiSearchEmbeddingStore; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; + +import static dev.langchain4j.azure.aisearch.spring.Properties.PREFIX; + +@AutoConfiguration +@EnableConfigurationProperties(Properties.class) +public class AutoConfig { + + @Bean + @ConditionalOnProperty(PREFIX + ".api-key") + public AzureAiSearchEmbeddingStore azureAiSearchEmbeddingStore(Properties properties) { + return AzureAiSearchEmbeddingStore.builder() + .endpoint(properties.getEndpoint()) + .apiKey(properties.getApiKey()) + .dimensions(properties.getDimensions()) + .setupIndex(properties.isSetupIndex()) + .build(); + } +} \ No newline at end of file diff --git a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java b/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java new file mode 100644 index 0000000..8271a17 --- /dev/null +++ b/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java @@ -0,0 +1,18 @@ +package dev.langchain4j.azure.aisearch.spring; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; + +@Getter +@Setter +@ConfigurationProperties(prefix = Properties.PREFIX) +public class Properties { + + static final String PREFIX = "langchain4j.azure.ai-search"; + + String endpoint; + String apiKey; + int dimensions; + boolean setupIndex; +} diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java b/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java similarity index 100% rename from langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java rename to langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java b/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java similarity index 100% rename from langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java rename to langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java b/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java similarity index 100% rename from langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java rename to langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java b/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java similarity index 100% rename from langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java rename to langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java b/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java similarity index 100% rename from langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java rename to langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java diff --git a/langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring.factories b/langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..4136150 --- /dev/null +++ b/langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +dev.langchain4j.azure.openai.spring.AutoConfig,\ +dev.langchain4j.azure.aisearch.spring.AutoConfig \ No newline at end of file diff --git a/langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..3b674a8 --- /dev/null +++ b/langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,2 @@ +dev.langchain4j.azure.openai.spring.AutoConfig +dev.langchain4j.azure.aisearch.spring.AutoConfig \ No newline at end of file diff --git a/langchain4j-azure-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java b/langchain4j-azure-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java new file mode 100644 index 0000000..97abde4 --- /dev/null +++ b/langchain4j-azure-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java @@ -0,0 +1,41 @@ +package dev.langchain4j.azure.aisearch.spring; + +import dev.langchain4j.data.segment.TextSegment; +import dev.langchain4j.store.embedding.EmbeddingStore; +import dev.langchain4j.store.embedding.azure.search.AzureAiSearchEmbeddingStore; +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +class AutoConfigIT { + + private static final String AZURE_AISEARCH_API_KEY = System.getenv("AZURE_AISEARCH_API_KEY"); + private static final String AZURE_AISEARCH_ENDPOINT = System.getenv("AZURE_AISEARCH_ENDPOINT"); + private static final String AZURE_AISEARCH_DIMENSIONS = System.getenv("AZURE_AISEARCH_DIMENSIONS"); + private static final String AZURE_AISEARCH_SETUP_INDEX = System.getenv("AZURE_AISEARCH_SETUP_INDEX"); + + + ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(AutoConfig.class)); + + @Test + void should_provide_ai_search_store() { + contextRunner + .withPropertyValues( + "langchain4j.azure.ai-search.api-key=" + AZURE_AISEARCH_API_KEY, + "langchain4j.azure.ai-search.endpoint=" + AZURE_AISEARCH_ENDPOINT, + "langchain4j.azure.ai-search.dimensions=" + AZURE_AISEARCH_DIMENSIONS, + "langchain4j.azure.ai-search.setup-index=" + AZURE_AISEARCH_SETUP_INDEX + ) + .run(context -> { + + EmbeddingStore azureAiSearchEmbeddingStore = context.getBean(AzureAiSearchEmbeddingStore.class); + assertThat(azureAiSearchEmbeddingStore).isInstanceOf(AzureAiSearchEmbeddingStore.class); + + assertThat(context.getBean(AzureAiSearchEmbeddingStore.class)).isSameAs(azureAiSearchEmbeddingStore); + }); + } + +} \ No newline at end of file diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java b/langchain4j-azure-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java similarity index 100% rename from langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java rename to langchain4j-azure-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java diff --git a/pom.xml b/pom.xml index 3bf709a..c7b11e7 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ dev.langchain4j langchain4j-spring - 0.28.0-SNAPSHOT + 0.29.0-SNAPSHOT pom langchain4j-spring parent POM @@ -16,7 +16,7 @@ langchain4j-ollama-spring-boot-starter langchain4j-open-ai-spring-boot-starter - langchain4j-azure-open-ai-spring-boot-starter + langchain4j-azure-spring-boot-starter From 436f5053e8cea7b99870f18cf913e8dfc283ecc9 Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Fri, 15 Mar 2024 13:50:09 +0800 Subject: [PATCH 08/49] Format the code --- .../dev/langchain4j/azure/openai/spring/AutoConfig.java | 9 ++++++--- .../java/dev/langchain4j/azure/openai/AutoConfigIT.java | 7 +++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java b/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java index d0bf828..db91ffb 100644 --- a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java +++ b/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java @@ -1,8 +1,11 @@ package dev.langchain4j.azure.openai.spring; -import com.azure.core.util.Configuration; -import dev.langchain4j.model.azure.*; import com.azure.core.http.ProxyOptions; +import com.azure.core.util.Configuration; +import dev.langchain4j.model.azure.AzureOpenAiChatModel; +import dev.langchain4j.model.azure.AzureOpenAiEmbeddingModel; +import dev.langchain4j.model.azure.AzureOpenAiImageModel; +import dev.langchain4j.model.azure.AzureOpenAiStreamingChatModel; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -86,7 +89,7 @@ AzureOpenAiImageModel openAiImageModel(Properties properties) { .timeout(imageModelProperties.getTimeout()) .maxRetries(imageModelProperties.getMaxRetries()) .proxyOptions(ProxyOptions.fromConfiguration(Configuration.getGlobalConfiguration())) - .logRequestsAndResponses(imageModelProperties.getLogRequestsAndResponses()!=null&&imageModelProperties.getLogRequestsAndResponses()) + .logRequestsAndResponses(imageModelProperties.getLogRequestsAndResponses() != null && imageModelProperties.getLogRequestsAndResponses()) .build(); } } \ No newline at end of file diff --git a/langchain4j-azure-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java b/langchain4j-azure-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java index 869c403..e58f74d 100644 --- a/langchain4j-azure-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java +++ b/langchain4j-azure-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java @@ -1,14 +1,17 @@ package dev.langchain4j.azure.openai; +import dev.langchain4j.azure.openai.spring.AutoConfig; import dev.langchain4j.data.message.AiMessage; import dev.langchain4j.model.StreamingResponseHandler; -import dev.langchain4j.model.azure.*; +import dev.langchain4j.model.azure.AzureOpenAiChatModel; +import dev.langchain4j.model.azure.AzureOpenAiEmbeddingModel; +import dev.langchain4j.model.azure.AzureOpenAiImageModel; +import dev.langchain4j.model.azure.AzureOpenAiStreamingChatModel; import dev.langchain4j.model.chat.ChatLanguageModel; import dev.langchain4j.model.chat.StreamingChatLanguageModel; import dev.langchain4j.model.embedding.EmbeddingModel; import dev.langchain4j.model.image.ImageModel; import dev.langchain4j.model.output.Response; -import dev.langchain4j.azure.openai.spring.AutoConfig; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; From 546b0f1bfe3723af47860d9f4167dae76fd6cc56 Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Wed, 20 Mar 2024 23:34:38 +0800 Subject: [PATCH 09/49] use latest ai search --- .../java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java | 2 +- .../java/dev/langchain4j/azure/aisearch/spring/Properties.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java b/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java index 703f06a..1e24039 100644 --- a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java +++ b/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java @@ -19,7 +19,7 @@ public AzureAiSearchEmbeddingStore azureAiSearchEmbeddingStore(Properties proper .endpoint(properties.getEndpoint()) .apiKey(properties.getApiKey()) .dimensions(properties.getDimensions()) - .setupIndex(properties.isSetupIndex()) + .createOrUpdateIndex(properties.isCreateOrUpdateIndex()) .build(); } } \ No newline at end of file diff --git a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java b/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java index 8271a17..fce5fd8 100644 --- a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java +++ b/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java @@ -14,5 +14,5 @@ public class Properties { String endpoint; String apiKey; int dimensions; - boolean setupIndex; + boolean createOrUpdateIndex; } From 8e3be8c8fc990d11a32e878a7a1b7e1d73f49ffd Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Fri, 22 Mar 2024 11:21:35 +0800 Subject: [PATCH 10/49] decouple as different resource --- .../pom.xml | 9 +-- .../azure/aisearch/spring/AutoConfig.java | 13 +++- .../azure/aisearch/spring/Properties.java | 0 .../main/resources/META-INF/spring.factories | 2 + ...ot.autoconfigure.AutoConfiguration.imports | 1 + .../azure/aisearch/spring/AutoConfigIT.java | 18 +++++ .../pom.xml | 68 +++++++++++++++++++ .../azure/openai/spring/AutoConfig.java | 0 .../openai/spring/ChatModelProperties.java | 0 .../spring/EmbeddingModelProperties.java | 0 .../openai/spring/ImageModelProperties.java | 0 .../azure/openai/spring/Properties.java | 0 .../main/resources/META-INF/spring.factories | 2 + ...ot.autoconfigure.AutoConfiguration.imports | 1 + .../azure/openai/AutoConfigIT.java | 0 .../main/resources/META-INF/spring.factories | 3 - ...ot.autoconfigure.AutoConfiguration.imports | 2 - .../pom.xml | 2 +- .../pom.xml | 2 +- pom.xml | 12 ++-- 20 files changed, 115 insertions(+), 20 deletions(-) rename {langchain4j-azure-spring-boot-starter => langchain4j-azure-aisearch-spring-boot-starter}/pom.xml (86%) rename {langchain4j-azure-spring-boot-starter => langchain4j-azure-aisearch-spring-boot-starter}/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java (63%) rename {langchain4j-azure-spring-boot-starter => langchain4j-azure-aisearch-spring-boot-starter}/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java (100%) create mode 100644 langchain4j-azure-aisearch-spring-boot-starter/src/main/resources/META-INF/spring.factories create mode 100644 langchain4j-azure-aisearch-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports rename {langchain4j-azure-spring-boot-starter => langchain4j-azure-aisearch-spring-boot-starter}/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java (67%) create mode 100644 langchain4j-azure-openai-spring-boot-starter/pom.xml rename {langchain4j-azure-spring-boot-starter => langchain4j-azure-openai-spring-boot-starter}/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java (100%) rename {langchain4j-azure-spring-boot-starter => langchain4j-azure-openai-spring-boot-starter}/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java (100%) rename {langchain4j-azure-spring-boot-starter => langchain4j-azure-openai-spring-boot-starter}/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java (100%) rename {langchain4j-azure-spring-boot-starter => langchain4j-azure-openai-spring-boot-starter}/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java (100%) rename {langchain4j-azure-spring-boot-starter => langchain4j-azure-openai-spring-boot-starter}/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java (100%) create mode 100644 langchain4j-azure-openai-spring-boot-starter/src/main/resources/META-INF/spring.factories create mode 100644 langchain4j-azure-openai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports rename {langchain4j-azure-spring-boot-starter => langchain4j-azure-openai-spring-boot-starter}/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java (100%) delete mode 100644 langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring.factories delete mode 100644 langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports diff --git a/langchain4j-azure-spring-boot-starter/pom.xml b/langchain4j-azure-aisearch-spring-boot-starter/pom.xml similarity index 86% rename from langchain4j-azure-spring-boot-starter/pom.xml rename to langchain4j-azure-aisearch-spring-boot-starter/pom.xml index 0609661..8b36b50 100644 --- a/langchain4j-azure-spring-boot-starter/pom.xml +++ b/langchain4j-azure-aisearch-spring-boot-starter/pom.xml @@ -11,17 +11,12 @@ ../pom.xml - langchain4j-azure-spring-boot-starter - LangChain4j Spring Boot starter for Azure + langchain4j-azure-aisearch-spring-boot-starter + LangChain4j Spring Boot starter for Azure AI Search jar - - dev.langchain4j - langchain4j-azure-open-ai - ${project.version} - dev.langchain4j langchain4j-azure-ai-search diff --git a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java b/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java similarity index 63% rename from langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java rename to langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java index 1e24039..804e722 100644 --- a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java +++ b/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java @@ -1,5 +1,6 @@ package dev.langchain4j.azure.aisearch.spring; +import dev.langchain4j.rag.content.retriever.azure.search.AzureAiSearchContentRetriever; import dev.langchain4j.store.embedding.azure.search.AzureAiSearchEmbeddingStore; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -19,7 +20,17 @@ public AzureAiSearchEmbeddingStore azureAiSearchEmbeddingStore(Properties proper .endpoint(properties.getEndpoint()) .apiKey(properties.getApiKey()) .dimensions(properties.getDimensions()) - .createOrUpdateIndex(properties.isCreateOrUpdateIndex()) +// .createOrUpdateIndex(properties.isCreateOrUpdateIndex()) + .build(); + } + + @Bean + @ConditionalOnProperty(PREFIX + ".api-key") + public AzureAiSearchContentRetriever azureAiSearchContentRetriever(Properties properties) { + return AzureAiSearchContentRetriever.builder() + .endpoint(properties.getEndpoint()) + .apiKey(properties.getApiKey()) + .dimensions(properties.getDimensions()) .build(); } } \ No newline at end of file diff --git a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java b/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java similarity index 100% rename from langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java rename to langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java diff --git a/langchain4j-azure-aisearch-spring-boot-starter/src/main/resources/META-INF/spring.factories b/langchain4j-azure-aisearch-spring-boot-starter/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..a776ce4 --- /dev/null +++ b/langchain4j-azure-aisearch-spring-boot-starter/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +dev.langchain4j.azure.aisearch.spring.AutoConfig \ No newline at end of file diff --git a/langchain4j-azure-aisearch-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/langchain4j-azure-aisearch-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..79ce989 --- /dev/null +++ b/langchain4j-azure-aisearch-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +dev.langchain4j.azure.aisearch.spring.AutoConfig \ No newline at end of file diff --git a/langchain4j-azure-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java b/langchain4j-azure-aisearch-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java similarity index 67% rename from langchain4j-azure-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java rename to langchain4j-azure-aisearch-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java index 97abde4..9adb1a9 100644 --- a/langchain4j-azure-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java +++ b/langchain4j-azure-aisearch-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java @@ -1,6 +1,8 @@ package dev.langchain4j.azure.aisearch.spring; import dev.langchain4j.data.segment.TextSegment; +import dev.langchain4j.rag.content.retriever.ContentRetriever; +import dev.langchain4j.rag.content.retriever.azure.search.AzureAiSearchContentRetriever; import dev.langchain4j.store.embedding.EmbeddingStore; import dev.langchain4j.store.embedding.azure.search.AzureAiSearchEmbeddingStore; import org.junit.jupiter.api.Test; @@ -38,4 +40,20 @@ void should_provide_ai_search_store() { }); } + @Test + void should_provide_ai_search_retriver() { + contextRunner + .withPropertyValues( + "langchain4j.azure.ai-search.api-key=" + AZURE_AISEARCH_API_KEY, + "langchain4j.azure.ai-search.endpoint=" + AZURE_AISEARCH_ENDPOINT, + "langchain4j.azure.ai-search.dimensions=" + AZURE_AISEARCH_DIMENSIONS + ) + .run(context -> { + ContentRetriever contentRetriever = context.getBean(AzureAiSearchContentRetriever.class); + assertThat(contentRetriever).isInstanceOf(AzureAiSearchContentRetriever.class); + + assertThat(context.getBean(ContentRetriever.class)).isSameAs(contentRetriever); + }); + } + } \ No newline at end of file diff --git a/langchain4j-azure-openai-spring-boot-starter/pom.xml b/langchain4j-azure-openai-spring-boot-starter/pom.xml new file mode 100644 index 0000000..f2417b9 --- /dev/null +++ b/langchain4j-azure-openai-spring-boot-starter/pom.xml @@ -0,0 +1,68 @@ + + + 4.0.0 + + + dev.langchain4j + langchain4j-spring + 0.29.0-SNAPSHOT + ../pom.xml + + + langchain4j-azure-openai-spring-boot-starter + LangChain4j Spring Boot starter for Azure OpenAI + jar + + + + + dev.langchain4j + langchain4j-azure-open-ai + ${project.version} + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-autoconfigure-processor + true + + + + + org.projectlombok + lombok + provided + + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + Apache-2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + A business-friendly OSS license + + + + \ No newline at end of file diff --git a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java b/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java similarity index 100% rename from langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java rename to langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java diff --git a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java b/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java similarity index 100% rename from langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java rename to langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java diff --git a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java b/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java similarity index 100% rename from langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java rename to langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java diff --git a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java b/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java similarity index 100% rename from langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java rename to langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java diff --git a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java b/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java similarity index 100% rename from langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java rename to langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java diff --git a/langchain4j-azure-openai-spring-boot-starter/src/main/resources/META-INF/spring.factories b/langchain4j-azure-openai-spring-boot-starter/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..4db50a7 --- /dev/null +++ b/langchain4j-azure-openai-spring-boot-starter/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +dev.langchain4j.azure.openai.spring.AutoConfig \ No newline at end of file diff --git a/langchain4j-azure-openai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/langchain4j-azure-openai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..4ab7c73 --- /dev/null +++ b/langchain4j-azure-openai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +dev.langchain4j.azure.openai.spring.AutoConfig \ No newline at end of file diff --git a/langchain4j-azure-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java b/langchain4j-azure-openai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java similarity index 100% rename from langchain4j-azure-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java rename to langchain4j-azure-openai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java diff --git a/langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring.factories b/langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 4136150..0000000 --- a/langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,3 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -dev.langchain4j.azure.openai.spring.AutoConfig,\ -dev.langchain4j.azure.aisearch.spring.AutoConfig \ No newline at end of file diff --git a/langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports deleted file mode 100644 index 3b674a8..0000000 --- a/langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ /dev/null @@ -1,2 +0,0 @@ -dev.langchain4j.azure.openai.spring.AutoConfig -dev.langchain4j.azure.aisearch.spring.AutoConfig \ No newline at end of file diff --git a/langchain4j-ollama-spring-boot-starter/pom.xml b/langchain4j-ollama-spring-boot-starter/pom.xml index 5715436..96d898a 100644 --- a/langchain4j-ollama-spring-boot-starter/pom.xml +++ b/langchain4j-ollama-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ dev.langchain4j langchain4j-spring - 0.28.0-SNAPSHOT + 0.29.0-SNAPSHOT ../pom.xml diff --git a/langchain4j-open-ai-spring-boot-starter/pom.xml b/langchain4j-open-ai-spring-boot-starter/pom.xml index 0c22824..91c738a 100644 --- a/langchain4j-open-ai-spring-boot-starter/pom.xml +++ b/langchain4j-open-ai-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ dev.langchain4j langchain4j-spring - 0.28.0-SNAPSHOT + 0.29.0-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index c7b11e7..88a23ad 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,8 @@ langchain4j-ollama-spring-boot-starter langchain4j-open-ai-spring-boot-starter - langchain4j-azure-spring-boot-starter + langchain4j-azure-aisearch-spring-boot-starter + langchain4j-azure-openai-spring-boot-starter @@ -174,11 +175,12 @@ + - - ossrh - https://s01.oss.sonatype.org/content/repositories/snapshots - + + github + https://maven.pkg.github.com/showpune/langchain4j + From 48dcf22b6ff46fdcd929e7d0ae0a225386a4d2b9 Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Tue, 26 Mar 2024 12:50:02 +0800 Subject: [PATCH 11/49] decouple as different resource --- .github/ISSUE_TEMPLATE/bug_report.md | 1 + README.md | 1 + .../pom.xml | 6 +++ .../azure/aisearch/spring/AutoConfig.java | 20 +++---- .../azure/aisearch/spring/Properties.java | 4 ++ .../azure/aisearch/spring/AutoConfigIT.java | 54 ++++++++++++++----- .../pom.xml | 4 +- pom.xml | 4 +- 8 files changed, 63 insertions(+), 31 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index b23448f..b419ba3 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -23,6 +23,7 @@ Please provide a relevant code snippets to reproduce this bug. A clear and concise description of what you expected to happen. **Please complete the following information:** + - LangChain4j version: e.g. 0.27.0 - Java version: e.g. 11 - Spring Boot version: e.g. 2.7.18 diff --git a/README.md b/README.md index c277b28..a843373 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ # langchain4j-spring + LangChain4j integration with Spring diff --git a/langchain4j-azure-aisearch-spring-boot-starter/pom.xml b/langchain4j-azure-aisearch-spring-boot-starter/pom.xml index 8b36b50..db398e9 100644 --- a/langchain4j-azure-aisearch-spring-boot-starter/pom.xml +++ b/langchain4j-azure-aisearch-spring-boot-starter/pom.xml @@ -53,6 +53,12 @@ spring-boot-starter-test test + + dev.langchain4j + langchain4j-embeddings-all-minilm-l6-v2 + 0.29.0-SNAPSHOT + test + diff --git a/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java b/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java index 804e722..2a779b4 100644 --- a/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java +++ b/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java @@ -1,7 +1,7 @@ package dev.langchain4j.azure.aisearch.spring; +import dev.langchain4j.model.embedding.EmbeddingModel; import dev.langchain4j.rag.content.retriever.azure.search.AzureAiSearchContentRetriever; -import dev.langchain4j.store.embedding.azure.search.AzureAiSearchEmbeddingStore; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -15,22 +15,16 @@ public class AutoConfig { @Bean @ConditionalOnProperty(PREFIX + ".api-key") - public AzureAiSearchEmbeddingStore azureAiSearchEmbeddingStore(Properties properties) { - return AzureAiSearchEmbeddingStore.builder() - .endpoint(properties.getEndpoint()) - .apiKey(properties.getApiKey()) - .dimensions(properties.getDimensions()) -// .createOrUpdateIndex(properties.isCreateOrUpdateIndex()) - .build(); - } - - @Bean - @ConditionalOnProperty(PREFIX + ".api-key") - public AzureAiSearchContentRetriever azureAiSearchContentRetriever(Properties properties) { + public AzureAiSearchContentRetriever azureAiSearchContentRetriever(Properties properties, EmbeddingModel embeddingModel) { return AzureAiSearchContentRetriever.builder() .endpoint(properties.getEndpoint()) .apiKey(properties.getApiKey()) + .createOrUpdateIndex(properties.isCreateOrUpdateIndex()) + .embeddingModel(embeddingModel) .dimensions(properties.getDimensions()) + .maxResults(properties.getMaxResults()) + .minScore(properties.getMinScore()) + .queryType(properties.getQueryType()) .build(); } } \ No newline at end of file diff --git a/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java b/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java index fce5fd8..adbc290 100644 --- a/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java +++ b/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java @@ -1,5 +1,6 @@ package dev.langchain4j.azure.aisearch.spring; +import dev.langchain4j.rag.content.retriever.azure.search.AzureAiSearchQueryType; import lombok.Getter; import lombok.Setter; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -15,4 +16,7 @@ public class Properties { String apiKey; int dimensions; boolean createOrUpdateIndex; + int maxResults = 1; + double minScore = 0.6; + AzureAiSearchQueryType queryType; } diff --git a/langchain4j-azure-aisearch-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java b/langchain4j-azure-aisearch-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java index 9adb1a9..4813071 100644 --- a/langchain4j-azure-aisearch-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java +++ b/langchain4j-azure-aisearch-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java @@ -1,10 +1,9 @@ package dev.langchain4j.azure.aisearch.spring; -import dev.langchain4j.data.segment.TextSegment; +import dev.langchain4j.model.embedding.AllMiniLmL6V2EmbeddingModel; +import dev.langchain4j.model.embedding.EmbeddingModel; import dev.langchain4j.rag.content.retriever.ContentRetriever; import dev.langchain4j.rag.content.retriever.azure.search.AzureAiSearchContentRetriever; -import dev.langchain4j.store.embedding.EmbeddingStore; -import dev.langchain4j.store.embedding.azure.search.AzureAiSearchEmbeddingStore; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -17,37 +16,64 @@ class AutoConfigIT { private static final String AZURE_AISEARCH_ENDPOINT = System.getenv("AZURE_AISEARCH_ENDPOINT"); private static final String AZURE_AISEARCH_DIMENSIONS = System.getenv("AZURE_AISEARCH_DIMENSIONS"); private static final String AZURE_AISEARCH_SETUP_INDEX = System.getenv("AZURE_AISEARCH_SETUP_INDEX"); + private static final String AZURE_AISEARCH_MAX_RESULTS = System.getenv("AZURE_AISEARCH_MAX_RESULTS"); + private static final String AZURE_AISEARCH_MIN_SCORE = System.getenv("AZURE_AISEARCH_MIN_SCORE"); + private static final String AZURE_AISEARCH_QUERY_TYPE = System.getenv("AZURE_AISEARCH_QUERY_TYPE"); ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(AutoConfig.class)); +// @Test +// void should_provide_ai_search_store() { +// contextRunner +// .withPropertyValues( +// "langchain4j.azure.ai-search.api-key=" + AZURE_AISEARCH_API_KEY, +// "langchain4j.azure.ai-search.endpoint=" + AZURE_AISEARCH_ENDPOINT, +// "langchain4j.azure.ai-search.dimensions=" + AZURE_AISEARCH_DIMENSIONS, +// "langchain4j.azure.ai-search.setup-index=" + AZURE_AISEARCH_SETUP_INDEX +// ) +// .run(context -> { +// +// EmbeddingStore azureAiSearchEmbeddingStore = context.getBean(AzureAiSearchEmbeddingStore.class); +// assertThat(azureAiSearchEmbeddingStore).isInstanceOf(AzureAiSearchEmbeddingStore.class); +// +// assertThat(context.getBean(AzureAiSearchEmbeddingStore.class)).isSameAs(azureAiSearchEmbeddingStore); +// }); +// } + @Test - void should_provide_ai_search_store() { + void should_provide_ai_search_retriver_only_search() { contextRunner .withPropertyValues( "langchain4j.azure.ai-search.api-key=" + AZURE_AISEARCH_API_KEY, "langchain4j.azure.ai-search.endpoint=" + AZURE_AISEARCH_ENDPOINT, - "langchain4j.azure.ai-search.dimensions=" + AZURE_AISEARCH_DIMENSIONS, - "langchain4j.azure.ai-search.setup-index=" + AZURE_AISEARCH_SETUP_INDEX - ) + "langchain4j.azure.ai-search.dimensions=" + "0", + "langchain4j.azure.ai-search.create-or-update-index=" + "false", + "langchain4j.azure.ai-search.max-results=" + AZURE_AISEARCH_MAX_RESULTS, + "langchain4j.azure.ai-search.min-score=" + AZURE_AISEARCH_MIN_SCORE, + "langchain4j.azure.ai-search.query-type=" + "FULL_TEXT" + ).withBean(EmbeddingModel.class, AllMiniLmL6V2EmbeddingModel::new) .run(context -> { + ContentRetriever contentRetriever = context.getBean(AzureAiSearchContentRetriever.class); + assertThat(contentRetriever).isInstanceOf(AzureAiSearchContentRetriever.class); - EmbeddingStore azureAiSearchEmbeddingStore = context.getBean(AzureAiSearchEmbeddingStore.class); - assertThat(azureAiSearchEmbeddingStore).isInstanceOf(AzureAiSearchEmbeddingStore.class); - - assertThat(context.getBean(AzureAiSearchEmbeddingStore.class)).isSameAs(azureAiSearchEmbeddingStore); + assertThat(context.getBean(ContentRetriever.class)).isSameAs(contentRetriever); }); } @Test - void should_provide_ai_search_retriver() { + void should_provide_ai_search_retrive_create_or_uodate_indexr() { contextRunner .withPropertyValues( "langchain4j.azure.ai-search.api-key=" + AZURE_AISEARCH_API_KEY, "langchain4j.azure.ai-search.endpoint=" + AZURE_AISEARCH_ENDPOINT, - "langchain4j.azure.ai-search.dimensions=" + AZURE_AISEARCH_DIMENSIONS - ) + "langchain4j.azure.ai-search.dimensions=" + AZURE_AISEARCH_DIMENSIONS, + "langchain4j.azure.ai-search.create-or-update-index=" + "true", + "langchain4j.azure.ai-search.max-results=" + AZURE_AISEARCH_MAX_RESULTS, + "langchain4j.azure.ai-search.min-score=" + AZURE_AISEARCH_MIN_SCORE, + "langchain4j.azure.ai-search.query-type=" + "VECTOR" + ).withBean(EmbeddingModel.class, AllMiniLmL6V2EmbeddingModel::new) .run(context -> { ContentRetriever contentRetriever = context.getBean(AzureAiSearchContentRetriever.class); assertThat(contentRetriever).isInstanceOf(AzureAiSearchContentRetriever.class); diff --git a/langchain4j-open-ai-spring-boot-starter/pom.xml b/langchain4j-open-ai-spring-boot-starter/pom.xml index 91c738a..0a6590e 100644 --- a/langchain4j-open-ai-spring-boot-starter/pom.xml +++ b/langchain4j-open-ai-spring-boot-starter/pom.xml @@ -1,6 +1,6 @@ - 4.0.0 diff --git a/pom.xml b/pom.xml index 88a23ad..dce245e 100644 --- a/pom.xml +++ b/pom.xml @@ -1,6 +1,6 @@ - 4.0.0 From ed5be1b1526298f959d6cccafdc4048db839d813 Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Tue, 26 Mar 2024 12:56:17 +0800 Subject: [PATCH 12/49] Revert "bumped to 0.29.0-SNAPSHOT" This reverts commit a7fa4aca1a377a63327f914b7efad2ff7680ba45. --- langchain4j-ollama-spring-boot-starter/pom.xml | 2 +- langchain4j-open-ai-spring-boot-starter/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/langchain4j-ollama-spring-boot-starter/pom.xml b/langchain4j-ollama-spring-boot-starter/pom.xml index 26e911c..a5d55ff 100644 --- a/langchain4j-ollama-spring-boot-starter/pom.xml +++ b/langchain4j-ollama-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ dev.langchain4j langchain4j-spring - 0.29.0-SNAPSHOT + 0.28.0 ../pom.xml diff --git a/langchain4j-open-ai-spring-boot-starter/pom.xml b/langchain4j-open-ai-spring-boot-starter/pom.xml index 7a3861b..e023c08 100644 --- a/langchain4j-open-ai-spring-boot-starter/pom.xml +++ b/langchain4j-open-ai-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ dev.langchain4j langchain4j-spring - 0.29.0-SNAPSHOT + 0.28.0 ../pom.xml diff --git a/pom.xml b/pom.xml index 210cf78..b863004 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ dev.langchain4j langchain4j-spring - 0.29.0-SNAPSHOT + 0.28.0 pom langchain4j-spring parent POM From 165d27ee7e3938c1e22037be2ff0c17b25c1711e Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Tue, 26 Mar 2024 12:58:35 +0800 Subject: [PATCH 13/49] rollback the distributionManagement --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index b863004..991f935 100644 --- a/pom.xml +++ b/pom.xml @@ -180,10 +180,10 @@ - - github - https://maven.pkg.github.com/showpune/langchain4j - + + ossrh + https://s01.oss.sonatype.org/content/repositories/snapshots + From bbe199d5717d850dadc3c2d9cefff3dba1b3fa22 Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Tue, 26 Mar 2024 12:59:33 +0800 Subject: [PATCH 14/49] Reapply "bumped to 0.29.0-SNAPSHOT" This reverts commit ed5be1b1526298f959d6cccafdc4048db839d813. --- langchain4j-ollama-spring-boot-starter/pom.xml | 2 +- langchain4j-open-ai-spring-boot-starter/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/langchain4j-ollama-spring-boot-starter/pom.xml b/langchain4j-ollama-spring-boot-starter/pom.xml index a5d55ff..26e911c 100644 --- a/langchain4j-ollama-spring-boot-starter/pom.xml +++ b/langchain4j-ollama-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ dev.langchain4j langchain4j-spring - 0.28.0 + 0.29.0-SNAPSHOT ../pom.xml diff --git a/langchain4j-open-ai-spring-boot-starter/pom.xml b/langchain4j-open-ai-spring-boot-starter/pom.xml index e023c08..7a3861b 100644 --- a/langchain4j-open-ai-spring-boot-starter/pom.xml +++ b/langchain4j-open-ai-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ dev.langchain4j langchain4j-spring - 0.28.0 + 0.29.0-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index 991f935..9d65ea4 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ dev.langchain4j langchain4j-spring - 0.28.0 + 0.29.0-SNAPSHOT pom langchain4j-spring parent POM From f8c6eae3667ae6b905c9579429a59776b5ee036e Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Tue, 26 Mar 2024 13:14:42 +0800 Subject: [PATCH 15/49] Add Default value support --- .../java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java | 1 - 1 file changed, 1 deletion(-) diff --git a/langchain4j-azure-aisearch-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java b/langchain4j-azure-aisearch-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java index 4813071..fcb9e34 100644 --- a/langchain4j-azure-aisearch-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java +++ b/langchain4j-azure-aisearch-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java @@ -51,7 +51,6 @@ void should_provide_ai_search_retriver_only_search() { "langchain4j.azure.ai-search.dimensions=" + "0", "langchain4j.azure.ai-search.create-or-update-index=" + "false", "langchain4j.azure.ai-search.max-results=" + AZURE_AISEARCH_MAX_RESULTS, - "langchain4j.azure.ai-search.min-score=" + AZURE_AISEARCH_MIN_SCORE, "langchain4j.azure.ai-search.query-type=" + "FULL_TEXT" ).withBean(EmbeddingModel.class, AllMiniLmL6V2EmbeddingModel::new) .run(context -> { From 99581d032b7503d36c6aeab321d62e2b50f9e760 Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Tue, 26 Mar 2024 13:18:02 +0800 Subject: [PATCH 16/49] Rollback the other components --- .github/ISSUE_TEMPLATE/bug_report.md | 1 - langchain4j-ollama-spring-boot-starter/pom.xml | 3 ++- langchain4j-open-ai-spring-boot-starter/pom.xml | 7 ++++--- pom.xml | 5 ++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index b419ba3..b23448f 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -23,7 +23,6 @@ Please provide a relevant code snippets to reproduce this bug. A clear and concise description of what you expected to happen. **Please complete the following information:** - - LangChain4j version: e.g. 0.27.0 - Java version: e.g. 11 - Spring Boot version: e.g. 2.7.18 diff --git a/langchain4j-ollama-spring-boot-starter/pom.xml b/langchain4j-ollama-spring-boot-starter/pom.xml index 26e911c..5715436 100644 --- a/langchain4j-ollama-spring-boot-starter/pom.xml +++ b/langchain4j-ollama-spring-boot-starter/pom.xml @@ -7,12 +7,13 @@ dev.langchain4j langchain4j-spring - 0.29.0-SNAPSHOT + 0.28.0-SNAPSHOT ../pom.xml langchain4j-ollama-spring-boot-starter LangChain4j Spring Boot starter for Ollama + jar diff --git a/langchain4j-open-ai-spring-boot-starter/pom.xml b/langchain4j-open-ai-spring-boot-starter/pom.xml index 7a3861b..0c22824 100644 --- a/langchain4j-open-ai-spring-boot-starter/pom.xml +++ b/langchain4j-open-ai-spring-boot-starter/pom.xml @@ -1,18 +1,19 @@ - 4.0.0 dev.langchain4j langchain4j-spring - 0.29.0-SNAPSHOT + 0.28.0-SNAPSHOT ../pom.xml langchain4j-open-ai-spring-boot-starter LangChain4j Spring Boot starter for OpenAI + jar diff --git a/pom.xml b/pom.xml index 9d65ea4..809fd34 100644 --- a/pom.xml +++ b/pom.xml @@ -1,6 +1,6 @@ - 4.0.0 @@ -178,7 +178,6 @@ - ossrh From 8552bb7810922013c70f0fd93674ccd6da203764 Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Sun, 18 Feb 2024 18:08:46 +0800 Subject: [PATCH 17/49] Support Azure OpenAI --- .../pom.xml | 73 +++++++++++ .../azure/openai/spring/AutoConfig.java | 92 +++++++++++++ .../openai/spring/ChatModelProperties.java | 31 +++++ .../spring/EmbeddingModelProperties.java | 21 +++ .../openai/spring/ImageModelProperties.java | 27 ++++ .../azure/openai/spring/Properties.java | 26 ++++ .../main/resources/META-INF/spring.factories | 1 + ...ot.autoconfigure.AutoConfiguration.imports | 1 + .../azure/openai/AutoConfigIT.java | 121 ++++++++++++++++++ pom.xml | 1 + 10 files changed, 394 insertions(+) create mode 100644 langchain4j-azure-open-ai-spring-boot-starter/pom.xml create mode 100644 langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java create mode 100644 langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java create mode 100644 langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java create mode 100644 langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java create mode 100644 langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java create mode 100644 langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring.factories create mode 100644 langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java diff --git a/langchain4j-azure-open-ai-spring-boot-starter/pom.xml b/langchain4j-azure-open-ai-spring-boot-starter/pom.xml new file mode 100644 index 0000000..81727dd --- /dev/null +++ b/langchain4j-azure-open-ai-spring-boot-starter/pom.xml @@ -0,0 +1,73 @@ + + + 4.0.0 + + + dev.langchain4j + langchain4j-spring + 0.27.0-SNAPSHOT + ../pom.xml + + + langchain4j-azure-open-ai-spring-boot-starter + LangChain4j Spring Boot starter for Azure OpenAI + jar + + + + + dev.langchain4j + langchain4j-azure-open-ai + ${project.version} + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-autoconfigure-processor + true + + + + + org.projectlombok + lombok + provided + + + com.azure + azure-core + 1.45.1 + + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + Apache-2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + A business-friendly OSS license + + + + \ No newline at end of file diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java new file mode 100644 index 0000000..d0bf828 --- /dev/null +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java @@ -0,0 +1,92 @@ +package dev.langchain4j.azure.openai.spring; + +import com.azure.core.util.Configuration; +import dev.langchain4j.model.azure.*; +import com.azure.core.http.ProxyOptions; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; + +import static dev.langchain4j.azure.openai.spring.Properties.PREFIX; + +@AutoConfiguration +@EnableConfigurationProperties(Properties.class) +public class AutoConfig { + + @Bean + @ConditionalOnProperty(PREFIX + ".chat-model.api-key") + AzureOpenAiChatModel openAiChatModel(Properties properties) { + ChatModelProperties chatModelProperties = properties.getChatModel(); + return AzureOpenAiChatModel.builder() + .endpoint(chatModelProperties.getEndpoint()) + .apiKey(chatModelProperties.getApiKey()) + .deploymentName(chatModelProperties.getDeploymentName()) + .temperature(chatModelProperties.getTemperature()) + .topP(chatModelProperties.getTopP()) + .stop(chatModelProperties.getStop()) + .maxTokens(chatModelProperties.getMaxTokens()) + .presencePenalty(chatModelProperties.getPresencePenalty()) + .frequencyPenalty(chatModelProperties.getFrequencyPenalty()) + .timeout(chatModelProperties.getTimeout()) + .maxRetries(chatModelProperties.getMaxRetries()) + .proxyOptions(ProxyOptions.fromConfiguration(Configuration.getGlobalConfiguration())) + .logRequestsAndResponses(chatModelProperties.getLogRequestsAndResponses() != null && chatModelProperties.getLogRequestsAndResponses()) + .build(); + } + + @Bean + @ConditionalOnProperty(PREFIX + ".streaming-chat-model.api-key") + AzureOpenAiStreamingChatModel openAiStreamingChatModel(Properties properties) { + ChatModelProperties chatModelProperties = properties.getStreamingChatModel(); + return AzureOpenAiStreamingChatModel.builder() + .endpoint(chatModelProperties.getEndpoint()) + .apiKey(chatModelProperties.getApiKey()) + .deploymentName(chatModelProperties.getDeploymentName()) + .temperature(chatModelProperties.getTemperature()) + .topP(chatModelProperties.getTopP()) + .stop(chatModelProperties.getStop()) + .maxTokens(chatModelProperties.getMaxTokens()) + .presencePenalty(chatModelProperties.getPresencePenalty()) + .frequencyPenalty(chatModelProperties.getFrequencyPenalty()) + .timeout(chatModelProperties.getTimeout()) + .proxyOptions(ProxyOptions.fromConfiguration(Configuration.getGlobalConfiguration())) + .logRequestsAndResponses(chatModelProperties.getLogRequestsAndResponses() != null && chatModelProperties.getLogRequestsAndResponses()) + .build(); + } + + @Bean + @ConditionalOnProperty(PREFIX + ".embedding-model.api-key") + AzureOpenAiEmbeddingModel openAiEmbeddingModel(Properties properties) { + EmbeddingModelProperties embeddingModelProperties = properties.getEmbeddingModel(); + return AzureOpenAiEmbeddingModel.builder() + .endpoint(embeddingModelProperties.getEndpoint()) + .apiKey(embeddingModelProperties.getApiKey()) + .deploymentName(embeddingModelProperties.getDeploymentName()) + .timeout(embeddingModelProperties.getTimeout()) + .maxRetries(embeddingModelProperties.getMaxRetries()) + .proxyOptions(ProxyOptions.fromConfiguration(Configuration.getGlobalConfiguration())) + .logRequestsAndResponses(embeddingModelProperties.getLogRequestsAndResponses() != null && embeddingModelProperties.getLogRequestsAndResponses()) + .build(); + } + + @Bean + @ConditionalOnProperty(PREFIX + ".image-model.api-key") + AzureOpenAiImageModel openAiImageModel(Properties properties) { + ImageModelProperties imageModelProperties = properties.getImageModel(); + return AzureOpenAiImageModel.builder() + .endpoint(imageModelProperties.getEndpoint()) + .apiKey(imageModelProperties.getApiKey()) + .deploymentName(imageModelProperties.getDeploymentName()) + .size(imageModelProperties.getSize()) + .quality(imageModelProperties.getQuality()) + .style(imageModelProperties.getStyle()) + .user(imageModelProperties.getUser()) + .responseFormat(imageModelProperties.getResponseFormat()) + .timeout(imageModelProperties.getTimeout()) + .maxRetries(imageModelProperties.getMaxRetries()) + .proxyOptions(ProxyOptions.fromConfiguration(Configuration.getGlobalConfiguration())) + .logRequestsAndResponses(imageModelProperties.getLogRequestsAndResponses()!=null&&imageModelProperties.getLogRequestsAndResponses()) + .build(); + } +} \ No newline at end of file diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java new file mode 100644 index 0000000..b2a4e0a --- /dev/null +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java @@ -0,0 +1,31 @@ +package dev.langchain4j.azure.openai.spring; + +import lombok.Getter; +import lombok.Setter; + +import java.time.Duration; +import java.util.List; +import java.util.Map; + +@Getter +@Setter +class ChatModelProperties { + + String endpoint; + String apiKey; + String organizationId; + String deploymentName; + Double temperature; + Double topP; + List stop; + Integer maxTokens; + Double presencePenalty; + Double frequencyPenalty; + Map logitBias; + String responseFormat; + Integer seed; + String user; + Duration timeout; + Integer maxRetries; + Boolean logRequestsAndResponses; +} \ No newline at end of file diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java new file mode 100644 index 0000000..f3c2a7c --- /dev/null +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java @@ -0,0 +1,21 @@ +package dev.langchain4j.azure.openai.spring; + +import lombok.Getter; +import lombok.Setter; + +import java.time.Duration; + +@Getter +@Setter +class EmbeddingModelProperties { + + String endpoint; + String apiKey; + String organizationId; + String deploymentName; + Integer dimensions; + String user; + Duration timeout; + Integer maxRetries; + Boolean logRequestsAndResponses; +} \ No newline at end of file diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java new file mode 100644 index 0000000..41d15ea --- /dev/null +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java @@ -0,0 +1,27 @@ +package dev.langchain4j.azure.openai.spring; + +import lombok.Getter; +import lombok.Setter; + +import java.nio.file.Path; +import java.time.Duration; + +@Getter +@Setter +class ImageModelProperties { + + String endpoint; + String apiKey; + String organizationId; + String deploymentName; + String size; + String quality; + String style; + String user; + String responseFormat; + Duration timeout; + Integer maxRetries; + Boolean logRequestsAndResponses; + Boolean withPersisting; + Path persistTo; +} \ No newline at end of file diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java new file mode 100644 index 0000000..e2e6995 --- /dev/null +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java @@ -0,0 +1,26 @@ +package dev.langchain4j.azure.openai.spring; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.NestedConfigurationProperty; + +@Getter +@Setter +@ConfigurationProperties(prefix = Properties.PREFIX) +public class Properties { + + static final String PREFIX = "langchain4j.azure.open-ai"; + + @NestedConfigurationProperty + ChatModelProperties chatModel; + + @NestedConfigurationProperty + ChatModelProperties streamingChatModel; + + @NestedConfigurationProperty + EmbeddingModelProperties embeddingModel; + + @NestedConfigurationProperty + ImageModelProperties imageModel; +} diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring.factories b/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..b5b2137 --- /dev/null +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring.factories @@ -0,0 +1 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=dev.langchain4j.azure.openai.spring.AutoConfig \ No newline at end of file diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..4ab7c73 --- /dev/null +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +dev.langchain4j.azure.openai.spring.AutoConfig \ No newline at end of file diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java b/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java new file mode 100644 index 0000000..197f8d2 --- /dev/null +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java @@ -0,0 +1,121 @@ +package dev.langchain4j.azure.openai; + +import dev.langchain4j.data.message.AiMessage; +import dev.langchain4j.model.StreamingResponseHandler; +import dev.langchain4j.model.azure.*; +import dev.langchain4j.model.chat.ChatLanguageModel; +import dev.langchain4j.model.chat.StreamingChatLanguageModel; +import dev.langchain4j.model.embedding.EmbeddingModel; +import dev.langchain4j.model.image.ImageModel; +import dev.langchain4j.model.output.Response; +import dev.langchain4j.azure.openai.spring.AutoConfig; +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; + +import java.util.concurrent.CompletableFuture; + +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.assertj.core.api.Assertions.assertThat; + +class AutoConfigIT { + + private static final String AZURE_OPENAI_KEY = System.getenv("AZURE_OPENAI_KEY"); + private static final String AZURE_OPENAI_ENDPOINT = System.getenv("AZURE_OPENAI_ENDPOINT"); + private static final String AZURE_OPENAI_DEPLOYMENT_NAME = System.getenv("AZURE_OPENAI_DEPLOYMENT_NAME"); + private static final String AZURE_DALLE3_DEPLOYMENT_NAME = System.getenv("AZURE_DALLE3_DEPLOYMENT_NAME"); + private static final String AZURE_EMBEDDING_DEPLOYMENT_NAME = System.getenv("AZURE_EMBEDDING_DEPLOYMENT_NAME"); + + ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(AutoConfig.class)); + + @Test + void should_provide_chat_model() { + contextRunner + .withPropertyValues( + "langchain4j.azure.open-ai.chat-model.api-key=" + AZURE_OPENAI_KEY, + "langchain4j.azure.open-ai.chat-model.endpoint=" + AZURE_OPENAI_ENDPOINT, + "langchain4j.azure.open-ai.chat-model.deployment-name=" + AZURE_OPENAI_DEPLOYMENT_NAME, + "langchain4j.azure.open-ai.chat-model.max-tokens=20" + ) + .run(context -> { + + ChatLanguageModel chatLanguageModel = context.getBean(AzureOpenAiChatModel.class); + assertThat(chatLanguageModel).isInstanceOf(AzureOpenAiChatModel.class); + assertThat(chatLanguageModel.generate("What is the capital of Germany?")).contains("Berlin"); + + assertThat(context.getBean(AzureOpenAiChatModel.class)).isSameAs(chatLanguageModel); + }); + } + + @Test + void should_provide_streaming_chat_model() { + contextRunner + .withPropertyValues( + "langchain4j.azure.open-ai.streaming-chat-model.api-key=" + AZURE_OPENAI_KEY, + "langchain4j.azure.open-ai.streaming-chat-model.endpoint=" + AZURE_OPENAI_ENDPOINT, + "langchain4j.azure.open-ai.streaming-chat-model.deployment-name=" + AZURE_OPENAI_DEPLOYMENT_NAME, + "langchain4j.azure.open-ai.streaming-chat-model.max-tokens=20" + ) + .run(context -> { + + StreamingChatLanguageModel streamingChatLanguageModel = context.getBean(AzureOpenAiStreamingChatModel.class); + assertThat(streamingChatLanguageModel).isInstanceOf(AzureOpenAiStreamingChatModel.class); + CompletableFuture> future = new CompletableFuture<>(); + streamingChatLanguageModel.generate("What is the capital of Germany?", new StreamingResponseHandler() { + + @Override + public void onNext(String token) { + } + + @Override + public void onComplete(Response response) { + future.complete(response); + } + + @Override + public void onError(Throwable error) { + } + }); + Response response = future.get(60, SECONDS); + assertThat(response.content().text()).contains("Berlin"); + + assertThat(context.getBean(AzureOpenAiStreamingChatModel.class)).isSameAs(streamingChatLanguageModel); + }); + } + + + @Test + void should_provide_embedding_model() { + contextRunner + .withPropertyValues("langchain4j.azure.open-ai.embedding-model.api-key=" + AZURE_OPENAI_KEY, + "langchain4j.azure.open-ai.embedding-model.endpoint=" + AZURE_OPENAI_ENDPOINT, + "langchain4j.azure.open-ai.embedding-model.deployment-name=" + AZURE_EMBEDDING_DEPLOYMENT_NAME) + .run(context -> { + + EmbeddingModel embeddingModel = context.getBean(AzureOpenAiEmbeddingModel.class); + assertThat(embeddingModel).isInstanceOf(AzureOpenAiEmbeddingModel.class); + assertThat(embeddingModel.embed("hi").content().dimension()).isEqualTo(1536); + + assertThat(context.getBean(AzureOpenAiEmbeddingModel.class)).isSameAs(embeddingModel); + }); + } + + @Test + void should_provide_image_model() { + contextRunner + .withPropertyValues( + "langchain4j.azure.open-ai.image-model.api-key=" + AZURE_OPENAI_KEY, + "langchain4j.azure.open-ai.image-model.endpoint=" + AZURE_OPENAI_ENDPOINT, + "langchain4j.azure.open-ai.image-model.deployment-name=" + AZURE_DALLE3_DEPLOYMENT_NAME + ) + .run(context -> { + + ImageModel imageModel = context.getBean(ImageModel.class); + assertThat(imageModel).isInstanceOf(AzureOpenAiImageModel.class); + assertThat(imageModel.generate("banana").content().url()).isNotNull(); + + assertThat(context.getBean(AzureOpenAiImageModel.class)).isSameAs(imageModel); + }); + } +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index 64d7a81..8891bb0 100644 --- a/pom.xml +++ b/pom.xml @@ -19,6 +19,7 @@ langchain4j-anthropic-spring-boot-starter langchain4j-ollama-spring-boot-starter langchain4j-open-ai-spring-boot-starter + langchain4j-azure-open-ai-spring-boot-starter From 7f288ea39cbebb4a1ecdd3b4115127f811b73ada Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Fri, 15 Mar 2024 09:36:38 +0800 Subject: [PATCH 18/49] Update langchain4j-azure-open-ai-spring-boot-starter/pom.xml Co-authored-by: LangChain4j --- langchain4j-azure-open-ai-spring-boot-starter/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langchain4j-azure-open-ai-spring-boot-starter/pom.xml b/langchain4j-azure-open-ai-spring-boot-starter/pom.xml index 81727dd..012827d 100644 --- a/langchain4j-azure-open-ai-spring-boot-starter/pom.xml +++ b/langchain4j-azure-open-ai-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ dev.langchain4j langchain4j-spring - 0.27.0-SNAPSHOT + 0.29.0-SNAPSHOT ../pom.xml From 501aadf80520569a46097e9a4a6bdbd0a28ece89 Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Fri, 15 Mar 2024 09:38:52 +0800 Subject: [PATCH 19/49] Update langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java Co-authored-by: LangChain4j --- .../test/java/dev/langchain4j/azure/openai/AutoConfigIT.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java b/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java index 197f8d2..0180cd2 100644 --- a/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java @@ -40,7 +40,7 @@ void should_provide_chat_model() { ) .run(context -> { - ChatLanguageModel chatLanguageModel = context.getBean(AzureOpenAiChatModel.class); + ChatLanguageModel chatLanguageModel = context.getBean(ChatLanguageModel.class); assertThat(chatLanguageModel).isInstanceOf(AzureOpenAiChatModel.class); assertThat(chatLanguageModel.generate("What is the capital of Germany?")).contains("Berlin"); From 141634e5639629d9ef7665f3e55b942463374a06 Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Fri, 15 Mar 2024 09:39:26 +0800 Subject: [PATCH 20/49] Update langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java Co-authored-by: LangChain4j --- .../test/java/dev/langchain4j/azure/openai/AutoConfigIT.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java b/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java index 0180cd2..9fc5196 100644 --- a/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java @@ -93,7 +93,7 @@ void should_provide_embedding_model() { "langchain4j.azure.open-ai.embedding-model.deployment-name=" + AZURE_EMBEDDING_DEPLOYMENT_NAME) .run(context -> { - EmbeddingModel embeddingModel = context.getBean(AzureOpenAiEmbeddingModel.class); + EmbeddingModel embeddingModel = context.getBean(EmbeddingModel.class); assertThat(embeddingModel).isInstanceOf(AzureOpenAiEmbeddingModel.class); assertThat(embeddingModel.embed("hi").content().dimension()).isEqualTo(1536); From 46d64e8f75fc19022b6339a8c00f496e664bce74 Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Fri, 15 Mar 2024 09:39:38 +0800 Subject: [PATCH 21/49] Update langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java Co-authored-by: LangChain4j --- .../test/java/dev/langchain4j/azure/openai/AutoConfigIT.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java b/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java index 9fc5196..869c403 100644 --- a/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java @@ -59,7 +59,7 @@ void should_provide_streaming_chat_model() { ) .run(context -> { - StreamingChatLanguageModel streamingChatLanguageModel = context.getBean(AzureOpenAiStreamingChatModel.class); + StreamingChatLanguageModel streamingChatLanguageModel = context.getBean(StreamingChatLanguageModel.class); assertThat(streamingChatLanguageModel).isInstanceOf(AzureOpenAiStreamingChatModel.class); CompletableFuture> future = new CompletableFuture<>(); streamingChatLanguageModel.generate("What is the capital of Germany?", new StreamingResponseHandler() { From 877cf224329f5a06dde3fb5b6584f7deafada793 Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Fri, 15 Mar 2024 12:20:05 +0800 Subject: [PATCH 22/49] remove the azure core lib --- langchain4j-azure-open-ai-spring-boot-starter/pom.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/langchain4j-azure-open-ai-spring-boot-starter/pom.xml b/langchain4j-azure-open-ai-spring-boot-starter/pom.xml index 012827d..ca8eb49 100644 --- a/langchain4j-azure-open-ai-spring-boot-starter/pom.xml +++ b/langchain4j-azure-open-ai-spring-boot-starter/pom.xml @@ -40,11 +40,6 @@ lombok provided - - com.azure - azure-core - 1.45.1 - From 615f561b25166f309f8308bb1089f3fdc4a2ea56 Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Fri, 15 Mar 2024 13:38:43 +0800 Subject: [PATCH 23/49] Add Azure AI Search support --- .../main/resources/META-INF/spring.factories | 1 - ...ot.autoconfigure.AutoConfiguration.imports | 1 - .../pom.xml | 9 +++- .../azure/aisearch/spring/AutoConfig.java | 25 +++++++++++ .../azure/aisearch/spring/Properties.java | 18 ++++++++ .../azure/openai/spring/AutoConfig.java | 0 .../openai/spring/ChatModelProperties.java | 0 .../spring/EmbeddingModelProperties.java | 0 .../openai/spring/ImageModelProperties.java | 0 .../azure/openai/spring/Properties.java | 0 .../main/resources/META-INF/spring.factories | 3 ++ ...ot.autoconfigure.AutoConfiguration.imports | 2 + .../azure/aisearch/spring/AutoConfigIT.java | 41 +++++++++++++++++++ .../azure/openai/AutoConfigIT.java | 0 pom.xml | 2 +- 15 files changed, 97 insertions(+), 5 deletions(-) delete mode 100644 langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring.factories delete mode 100644 langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports rename {langchain4j-azure-open-ai-spring-boot-starter => langchain4j-azure-spring-boot-starter}/pom.xml (86%) create mode 100644 langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java create mode 100644 langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java rename {langchain4j-azure-open-ai-spring-boot-starter => langchain4j-azure-spring-boot-starter}/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java (100%) rename {langchain4j-azure-open-ai-spring-boot-starter => langchain4j-azure-spring-boot-starter}/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java (100%) rename {langchain4j-azure-open-ai-spring-boot-starter => langchain4j-azure-spring-boot-starter}/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java (100%) rename {langchain4j-azure-open-ai-spring-boot-starter => langchain4j-azure-spring-boot-starter}/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java (100%) rename {langchain4j-azure-open-ai-spring-boot-starter => langchain4j-azure-spring-boot-starter}/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java (100%) create mode 100644 langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring.factories create mode 100644 langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 langchain4j-azure-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java rename {langchain4j-azure-open-ai-spring-boot-starter => langchain4j-azure-spring-boot-starter}/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java (100%) diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring.factories b/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring.factories deleted file mode 100644 index b5b2137..0000000 --- a/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=dev.langchain4j.azure.openai.spring.AutoConfig \ No newline at end of file diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports deleted file mode 100644 index 4ab7c73..0000000 --- a/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ /dev/null @@ -1 +0,0 @@ -dev.langchain4j.azure.openai.spring.AutoConfig \ No newline at end of file diff --git a/langchain4j-azure-open-ai-spring-boot-starter/pom.xml b/langchain4j-azure-spring-boot-starter/pom.xml similarity index 86% rename from langchain4j-azure-open-ai-spring-boot-starter/pom.xml rename to langchain4j-azure-spring-boot-starter/pom.xml index ca8eb49..0609661 100644 --- a/langchain4j-azure-open-ai-spring-boot-starter/pom.xml +++ b/langchain4j-azure-spring-boot-starter/pom.xml @@ -11,8 +11,8 @@ ../pom.xml - langchain4j-azure-open-ai-spring-boot-starter - LangChain4j Spring Boot starter for Azure OpenAI + langchain4j-azure-spring-boot-starter + LangChain4j Spring Boot starter for Azure jar @@ -22,6 +22,11 @@ langchain4j-azure-open-ai ${project.version} + + dev.langchain4j + langchain4j-azure-ai-search + ${project.version} + org.springframework.boot diff --git a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java b/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java new file mode 100644 index 0000000..703f06a --- /dev/null +++ b/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java @@ -0,0 +1,25 @@ +package dev.langchain4j.azure.aisearch.spring; + +import dev.langchain4j.store.embedding.azure.search.AzureAiSearchEmbeddingStore; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; + +import static dev.langchain4j.azure.aisearch.spring.Properties.PREFIX; + +@AutoConfiguration +@EnableConfigurationProperties(Properties.class) +public class AutoConfig { + + @Bean + @ConditionalOnProperty(PREFIX + ".api-key") + public AzureAiSearchEmbeddingStore azureAiSearchEmbeddingStore(Properties properties) { + return AzureAiSearchEmbeddingStore.builder() + .endpoint(properties.getEndpoint()) + .apiKey(properties.getApiKey()) + .dimensions(properties.getDimensions()) + .setupIndex(properties.isSetupIndex()) + .build(); + } +} \ No newline at end of file diff --git a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java b/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java new file mode 100644 index 0000000..8271a17 --- /dev/null +++ b/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java @@ -0,0 +1,18 @@ +package dev.langchain4j.azure.aisearch.spring; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; + +@Getter +@Setter +@ConfigurationProperties(prefix = Properties.PREFIX) +public class Properties { + + static final String PREFIX = "langchain4j.azure.ai-search"; + + String endpoint; + String apiKey; + int dimensions; + boolean setupIndex; +} diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java b/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java similarity index 100% rename from langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java rename to langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java b/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java similarity index 100% rename from langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java rename to langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java b/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java similarity index 100% rename from langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java rename to langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java b/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java similarity index 100% rename from langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java rename to langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java b/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java similarity index 100% rename from langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java rename to langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java diff --git a/langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring.factories b/langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..4136150 --- /dev/null +++ b/langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +dev.langchain4j.azure.openai.spring.AutoConfig,\ +dev.langchain4j.azure.aisearch.spring.AutoConfig \ No newline at end of file diff --git a/langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..3b674a8 --- /dev/null +++ b/langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,2 @@ +dev.langchain4j.azure.openai.spring.AutoConfig +dev.langchain4j.azure.aisearch.spring.AutoConfig \ No newline at end of file diff --git a/langchain4j-azure-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java b/langchain4j-azure-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java new file mode 100644 index 0000000..97abde4 --- /dev/null +++ b/langchain4j-azure-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java @@ -0,0 +1,41 @@ +package dev.langchain4j.azure.aisearch.spring; + +import dev.langchain4j.data.segment.TextSegment; +import dev.langchain4j.store.embedding.EmbeddingStore; +import dev.langchain4j.store.embedding.azure.search.AzureAiSearchEmbeddingStore; +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +class AutoConfigIT { + + private static final String AZURE_AISEARCH_API_KEY = System.getenv("AZURE_AISEARCH_API_KEY"); + private static final String AZURE_AISEARCH_ENDPOINT = System.getenv("AZURE_AISEARCH_ENDPOINT"); + private static final String AZURE_AISEARCH_DIMENSIONS = System.getenv("AZURE_AISEARCH_DIMENSIONS"); + private static final String AZURE_AISEARCH_SETUP_INDEX = System.getenv("AZURE_AISEARCH_SETUP_INDEX"); + + + ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(AutoConfig.class)); + + @Test + void should_provide_ai_search_store() { + contextRunner + .withPropertyValues( + "langchain4j.azure.ai-search.api-key=" + AZURE_AISEARCH_API_KEY, + "langchain4j.azure.ai-search.endpoint=" + AZURE_AISEARCH_ENDPOINT, + "langchain4j.azure.ai-search.dimensions=" + AZURE_AISEARCH_DIMENSIONS, + "langchain4j.azure.ai-search.setup-index=" + AZURE_AISEARCH_SETUP_INDEX + ) + .run(context -> { + + EmbeddingStore azureAiSearchEmbeddingStore = context.getBean(AzureAiSearchEmbeddingStore.class); + assertThat(azureAiSearchEmbeddingStore).isInstanceOf(AzureAiSearchEmbeddingStore.class); + + assertThat(context.getBean(AzureAiSearchEmbeddingStore.class)).isSameAs(azureAiSearchEmbeddingStore); + }); + } + +} \ No newline at end of file diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java b/langchain4j-azure-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java similarity index 100% rename from langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java rename to langchain4j-azure-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java diff --git a/pom.xml b/pom.xml index 8891bb0..171079c 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ langchain4j-anthropic-spring-boot-starter langchain4j-ollama-spring-boot-starter langchain4j-open-ai-spring-boot-starter - langchain4j-azure-open-ai-spring-boot-starter + langchain4j-azure-spring-boot-starter From 317771147014a54a7d7826bb9e0b524b69b0cf7b Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Fri, 15 Mar 2024 13:50:09 +0800 Subject: [PATCH 24/49] Format the code --- .../dev/langchain4j/azure/openai/spring/AutoConfig.java | 9 ++++++--- .../java/dev/langchain4j/azure/openai/AutoConfigIT.java | 7 +++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java b/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java index d0bf828..db91ffb 100644 --- a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java +++ b/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java @@ -1,8 +1,11 @@ package dev.langchain4j.azure.openai.spring; -import com.azure.core.util.Configuration; -import dev.langchain4j.model.azure.*; import com.azure.core.http.ProxyOptions; +import com.azure.core.util.Configuration; +import dev.langchain4j.model.azure.AzureOpenAiChatModel; +import dev.langchain4j.model.azure.AzureOpenAiEmbeddingModel; +import dev.langchain4j.model.azure.AzureOpenAiImageModel; +import dev.langchain4j.model.azure.AzureOpenAiStreamingChatModel; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -86,7 +89,7 @@ AzureOpenAiImageModel openAiImageModel(Properties properties) { .timeout(imageModelProperties.getTimeout()) .maxRetries(imageModelProperties.getMaxRetries()) .proxyOptions(ProxyOptions.fromConfiguration(Configuration.getGlobalConfiguration())) - .logRequestsAndResponses(imageModelProperties.getLogRequestsAndResponses()!=null&&imageModelProperties.getLogRequestsAndResponses()) + .logRequestsAndResponses(imageModelProperties.getLogRequestsAndResponses() != null && imageModelProperties.getLogRequestsAndResponses()) .build(); } } \ No newline at end of file diff --git a/langchain4j-azure-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java b/langchain4j-azure-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java index 869c403..e58f74d 100644 --- a/langchain4j-azure-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java +++ b/langchain4j-azure-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java @@ -1,14 +1,17 @@ package dev.langchain4j.azure.openai; +import dev.langchain4j.azure.openai.spring.AutoConfig; import dev.langchain4j.data.message.AiMessage; import dev.langchain4j.model.StreamingResponseHandler; -import dev.langchain4j.model.azure.*; +import dev.langchain4j.model.azure.AzureOpenAiChatModel; +import dev.langchain4j.model.azure.AzureOpenAiEmbeddingModel; +import dev.langchain4j.model.azure.AzureOpenAiImageModel; +import dev.langchain4j.model.azure.AzureOpenAiStreamingChatModel; import dev.langchain4j.model.chat.ChatLanguageModel; import dev.langchain4j.model.chat.StreamingChatLanguageModel; import dev.langchain4j.model.embedding.EmbeddingModel; import dev.langchain4j.model.image.ImageModel; import dev.langchain4j.model.output.Response; -import dev.langchain4j.azure.openai.spring.AutoConfig; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; From f8dc8679ec3b74637a35558dde254c178544dd50 Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Wed, 20 Mar 2024 23:34:38 +0800 Subject: [PATCH 25/49] use latest ai search --- .../java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java | 2 +- .../java/dev/langchain4j/azure/aisearch/spring/Properties.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java b/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java index 703f06a..1e24039 100644 --- a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java +++ b/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java @@ -19,7 +19,7 @@ public AzureAiSearchEmbeddingStore azureAiSearchEmbeddingStore(Properties proper .endpoint(properties.getEndpoint()) .apiKey(properties.getApiKey()) .dimensions(properties.getDimensions()) - .setupIndex(properties.isSetupIndex()) + .createOrUpdateIndex(properties.isCreateOrUpdateIndex()) .build(); } } \ No newline at end of file diff --git a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java b/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java index 8271a17..fce5fd8 100644 --- a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java +++ b/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java @@ -14,5 +14,5 @@ public class Properties { String endpoint; String apiKey; int dimensions; - boolean setupIndex; + boolean createOrUpdateIndex; } From 615a2f91c076c845ff2bdeeab6b4a358e8d84370 Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Fri, 22 Mar 2024 11:21:35 +0800 Subject: [PATCH 26/49] decouple as different resource --- .../pom.xml | 9 +-- .../azure/aisearch/spring/AutoConfig.java | 13 +++- .../azure/aisearch/spring/Properties.java | 0 .../main/resources/META-INF/spring.factories | 2 + ...ot.autoconfigure.AutoConfiguration.imports | 1 + .../azure/aisearch/spring/AutoConfigIT.java | 18 +++++ .../pom.xml | 68 +++++++++++++++++++ .../azure/openai/spring/AutoConfig.java | 0 .../openai/spring/ChatModelProperties.java | 0 .../spring/EmbeddingModelProperties.java | 0 .../openai/spring/ImageModelProperties.java | 0 .../azure/openai/spring/Properties.java | 0 .../main/resources/META-INF/spring.factories | 2 + ...ot.autoconfigure.AutoConfiguration.imports | 1 + .../azure/openai/AutoConfigIT.java | 0 .../main/resources/META-INF/spring.factories | 3 - ...ot.autoconfigure.AutoConfiguration.imports | 2 - pom.xml | 12 ++-- 18 files changed, 113 insertions(+), 18 deletions(-) rename {langchain4j-azure-spring-boot-starter => langchain4j-azure-aisearch-spring-boot-starter}/pom.xml (86%) rename {langchain4j-azure-spring-boot-starter => langchain4j-azure-aisearch-spring-boot-starter}/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java (63%) rename {langchain4j-azure-spring-boot-starter => langchain4j-azure-aisearch-spring-boot-starter}/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java (100%) create mode 100644 langchain4j-azure-aisearch-spring-boot-starter/src/main/resources/META-INF/spring.factories create mode 100644 langchain4j-azure-aisearch-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports rename {langchain4j-azure-spring-boot-starter => langchain4j-azure-aisearch-spring-boot-starter}/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java (67%) create mode 100644 langchain4j-azure-openai-spring-boot-starter/pom.xml rename {langchain4j-azure-spring-boot-starter => langchain4j-azure-openai-spring-boot-starter}/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java (100%) rename {langchain4j-azure-spring-boot-starter => langchain4j-azure-openai-spring-boot-starter}/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java (100%) rename {langchain4j-azure-spring-boot-starter => langchain4j-azure-openai-spring-boot-starter}/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java (100%) rename {langchain4j-azure-spring-boot-starter => langchain4j-azure-openai-spring-boot-starter}/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java (100%) rename {langchain4j-azure-spring-boot-starter => langchain4j-azure-openai-spring-boot-starter}/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java (100%) create mode 100644 langchain4j-azure-openai-spring-boot-starter/src/main/resources/META-INF/spring.factories create mode 100644 langchain4j-azure-openai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports rename {langchain4j-azure-spring-boot-starter => langchain4j-azure-openai-spring-boot-starter}/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java (100%) delete mode 100644 langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring.factories delete mode 100644 langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports diff --git a/langchain4j-azure-spring-boot-starter/pom.xml b/langchain4j-azure-aisearch-spring-boot-starter/pom.xml similarity index 86% rename from langchain4j-azure-spring-boot-starter/pom.xml rename to langchain4j-azure-aisearch-spring-boot-starter/pom.xml index 0609661..8b36b50 100644 --- a/langchain4j-azure-spring-boot-starter/pom.xml +++ b/langchain4j-azure-aisearch-spring-boot-starter/pom.xml @@ -11,17 +11,12 @@ ../pom.xml - langchain4j-azure-spring-boot-starter - LangChain4j Spring Boot starter for Azure + langchain4j-azure-aisearch-spring-boot-starter + LangChain4j Spring Boot starter for Azure AI Search jar - - dev.langchain4j - langchain4j-azure-open-ai - ${project.version} - dev.langchain4j langchain4j-azure-ai-search diff --git a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java b/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java similarity index 63% rename from langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java rename to langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java index 1e24039..804e722 100644 --- a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java +++ b/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java @@ -1,5 +1,6 @@ package dev.langchain4j.azure.aisearch.spring; +import dev.langchain4j.rag.content.retriever.azure.search.AzureAiSearchContentRetriever; import dev.langchain4j.store.embedding.azure.search.AzureAiSearchEmbeddingStore; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -19,7 +20,17 @@ public AzureAiSearchEmbeddingStore azureAiSearchEmbeddingStore(Properties proper .endpoint(properties.getEndpoint()) .apiKey(properties.getApiKey()) .dimensions(properties.getDimensions()) - .createOrUpdateIndex(properties.isCreateOrUpdateIndex()) +// .createOrUpdateIndex(properties.isCreateOrUpdateIndex()) + .build(); + } + + @Bean + @ConditionalOnProperty(PREFIX + ".api-key") + public AzureAiSearchContentRetriever azureAiSearchContentRetriever(Properties properties) { + return AzureAiSearchContentRetriever.builder() + .endpoint(properties.getEndpoint()) + .apiKey(properties.getApiKey()) + .dimensions(properties.getDimensions()) .build(); } } \ No newline at end of file diff --git a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java b/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java similarity index 100% rename from langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java rename to langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java diff --git a/langchain4j-azure-aisearch-spring-boot-starter/src/main/resources/META-INF/spring.factories b/langchain4j-azure-aisearch-spring-boot-starter/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..a776ce4 --- /dev/null +++ b/langchain4j-azure-aisearch-spring-boot-starter/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +dev.langchain4j.azure.aisearch.spring.AutoConfig \ No newline at end of file diff --git a/langchain4j-azure-aisearch-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/langchain4j-azure-aisearch-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..79ce989 --- /dev/null +++ b/langchain4j-azure-aisearch-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +dev.langchain4j.azure.aisearch.spring.AutoConfig \ No newline at end of file diff --git a/langchain4j-azure-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java b/langchain4j-azure-aisearch-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java similarity index 67% rename from langchain4j-azure-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java rename to langchain4j-azure-aisearch-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java index 97abde4..9adb1a9 100644 --- a/langchain4j-azure-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java +++ b/langchain4j-azure-aisearch-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java @@ -1,6 +1,8 @@ package dev.langchain4j.azure.aisearch.spring; import dev.langchain4j.data.segment.TextSegment; +import dev.langchain4j.rag.content.retriever.ContentRetriever; +import dev.langchain4j.rag.content.retriever.azure.search.AzureAiSearchContentRetriever; import dev.langchain4j.store.embedding.EmbeddingStore; import dev.langchain4j.store.embedding.azure.search.AzureAiSearchEmbeddingStore; import org.junit.jupiter.api.Test; @@ -38,4 +40,20 @@ void should_provide_ai_search_store() { }); } + @Test + void should_provide_ai_search_retriver() { + contextRunner + .withPropertyValues( + "langchain4j.azure.ai-search.api-key=" + AZURE_AISEARCH_API_KEY, + "langchain4j.azure.ai-search.endpoint=" + AZURE_AISEARCH_ENDPOINT, + "langchain4j.azure.ai-search.dimensions=" + AZURE_AISEARCH_DIMENSIONS + ) + .run(context -> { + ContentRetriever contentRetriever = context.getBean(AzureAiSearchContentRetriever.class); + assertThat(contentRetriever).isInstanceOf(AzureAiSearchContentRetriever.class); + + assertThat(context.getBean(ContentRetriever.class)).isSameAs(contentRetriever); + }); + } + } \ No newline at end of file diff --git a/langchain4j-azure-openai-spring-boot-starter/pom.xml b/langchain4j-azure-openai-spring-boot-starter/pom.xml new file mode 100644 index 0000000..f2417b9 --- /dev/null +++ b/langchain4j-azure-openai-spring-boot-starter/pom.xml @@ -0,0 +1,68 @@ + + + 4.0.0 + + + dev.langchain4j + langchain4j-spring + 0.29.0-SNAPSHOT + ../pom.xml + + + langchain4j-azure-openai-spring-boot-starter + LangChain4j Spring Boot starter for Azure OpenAI + jar + + + + + dev.langchain4j + langchain4j-azure-open-ai + ${project.version} + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-autoconfigure-processor + true + + + + + org.projectlombok + lombok + provided + + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + Apache-2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + A business-friendly OSS license + + + + \ No newline at end of file diff --git a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java b/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java similarity index 100% rename from langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java rename to langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java diff --git a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java b/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java similarity index 100% rename from langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java rename to langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java diff --git a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java b/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java similarity index 100% rename from langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java rename to langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java diff --git a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java b/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java similarity index 100% rename from langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java rename to langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java diff --git a/langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java b/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java similarity index 100% rename from langchain4j-azure-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java rename to langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java diff --git a/langchain4j-azure-openai-spring-boot-starter/src/main/resources/META-INF/spring.factories b/langchain4j-azure-openai-spring-boot-starter/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..4db50a7 --- /dev/null +++ b/langchain4j-azure-openai-spring-boot-starter/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +dev.langchain4j.azure.openai.spring.AutoConfig \ No newline at end of file diff --git a/langchain4j-azure-openai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/langchain4j-azure-openai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..4ab7c73 --- /dev/null +++ b/langchain4j-azure-openai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +dev.langchain4j.azure.openai.spring.AutoConfig \ No newline at end of file diff --git a/langchain4j-azure-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java b/langchain4j-azure-openai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java similarity index 100% rename from langchain4j-azure-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java rename to langchain4j-azure-openai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java diff --git a/langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring.factories b/langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 4136150..0000000 --- a/langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,3 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -dev.langchain4j.azure.openai.spring.AutoConfig,\ -dev.langchain4j.azure.aisearch.spring.AutoConfig \ No newline at end of file diff --git a/langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports deleted file mode 100644 index 3b674a8..0000000 --- a/langchain4j-azure-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ /dev/null @@ -1,2 +0,0 @@ -dev.langchain4j.azure.openai.spring.AutoConfig -dev.langchain4j.azure.aisearch.spring.AutoConfig \ No newline at end of file diff --git a/pom.xml b/pom.xml index 171079c..02d5fc3 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,8 @@ langchain4j-anthropic-spring-boot-starter langchain4j-ollama-spring-boot-starter langchain4j-open-ai-spring-boot-starter - langchain4j-azure-spring-boot-starter + langchain4j-azure-aisearch-spring-boot-starter + langchain4j-azure-openai-spring-boot-starter @@ -177,11 +178,12 @@ + - - ossrh - https://s01.oss.sonatype.org/content/repositories/snapshots - + + github + https://maven.pkg.github.com/showpune/langchain4j + From 4078e31485a6afc9385407b5a623e8acfe137797 Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Tue, 26 Mar 2024 12:50:02 +0800 Subject: [PATCH 27/49] decouple as different resource --- .../pom.xml | 6 +++ .../azure/aisearch/spring/AutoConfig.java | 20 +++---- .../azure/aisearch/spring/Properties.java | 4 ++ .../azure/aisearch/spring/AutoConfigIT.java | 54 ++++++++++++++----- .../pom.xml | 4 +- pom.xml | 4 +- 6 files changed, 61 insertions(+), 31 deletions(-) diff --git a/langchain4j-azure-aisearch-spring-boot-starter/pom.xml b/langchain4j-azure-aisearch-spring-boot-starter/pom.xml index 8b36b50..db398e9 100644 --- a/langchain4j-azure-aisearch-spring-boot-starter/pom.xml +++ b/langchain4j-azure-aisearch-spring-boot-starter/pom.xml @@ -53,6 +53,12 @@ spring-boot-starter-test test + + dev.langchain4j + langchain4j-embeddings-all-minilm-l6-v2 + 0.29.0-SNAPSHOT + test + diff --git a/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java b/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java index 804e722..2a779b4 100644 --- a/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java +++ b/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java @@ -1,7 +1,7 @@ package dev.langchain4j.azure.aisearch.spring; +import dev.langchain4j.model.embedding.EmbeddingModel; import dev.langchain4j.rag.content.retriever.azure.search.AzureAiSearchContentRetriever; -import dev.langchain4j.store.embedding.azure.search.AzureAiSearchEmbeddingStore; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -15,22 +15,16 @@ public class AutoConfig { @Bean @ConditionalOnProperty(PREFIX + ".api-key") - public AzureAiSearchEmbeddingStore azureAiSearchEmbeddingStore(Properties properties) { - return AzureAiSearchEmbeddingStore.builder() - .endpoint(properties.getEndpoint()) - .apiKey(properties.getApiKey()) - .dimensions(properties.getDimensions()) -// .createOrUpdateIndex(properties.isCreateOrUpdateIndex()) - .build(); - } - - @Bean - @ConditionalOnProperty(PREFIX + ".api-key") - public AzureAiSearchContentRetriever azureAiSearchContentRetriever(Properties properties) { + public AzureAiSearchContentRetriever azureAiSearchContentRetriever(Properties properties, EmbeddingModel embeddingModel) { return AzureAiSearchContentRetriever.builder() .endpoint(properties.getEndpoint()) .apiKey(properties.getApiKey()) + .createOrUpdateIndex(properties.isCreateOrUpdateIndex()) + .embeddingModel(embeddingModel) .dimensions(properties.getDimensions()) + .maxResults(properties.getMaxResults()) + .minScore(properties.getMinScore()) + .queryType(properties.getQueryType()) .build(); } } \ No newline at end of file diff --git a/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java b/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java index fce5fd8..adbc290 100644 --- a/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java +++ b/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java @@ -1,5 +1,6 @@ package dev.langchain4j.azure.aisearch.spring; +import dev.langchain4j.rag.content.retriever.azure.search.AzureAiSearchQueryType; import lombok.Getter; import lombok.Setter; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -15,4 +16,7 @@ public class Properties { String apiKey; int dimensions; boolean createOrUpdateIndex; + int maxResults = 1; + double minScore = 0.6; + AzureAiSearchQueryType queryType; } diff --git a/langchain4j-azure-aisearch-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java b/langchain4j-azure-aisearch-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java index 9adb1a9..4813071 100644 --- a/langchain4j-azure-aisearch-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java +++ b/langchain4j-azure-aisearch-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java @@ -1,10 +1,9 @@ package dev.langchain4j.azure.aisearch.spring; -import dev.langchain4j.data.segment.TextSegment; +import dev.langchain4j.model.embedding.AllMiniLmL6V2EmbeddingModel; +import dev.langchain4j.model.embedding.EmbeddingModel; import dev.langchain4j.rag.content.retriever.ContentRetriever; import dev.langchain4j.rag.content.retriever.azure.search.AzureAiSearchContentRetriever; -import dev.langchain4j.store.embedding.EmbeddingStore; -import dev.langchain4j.store.embedding.azure.search.AzureAiSearchEmbeddingStore; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -17,37 +16,64 @@ class AutoConfigIT { private static final String AZURE_AISEARCH_ENDPOINT = System.getenv("AZURE_AISEARCH_ENDPOINT"); private static final String AZURE_AISEARCH_DIMENSIONS = System.getenv("AZURE_AISEARCH_DIMENSIONS"); private static final String AZURE_AISEARCH_SETUP_INDEX = System.getenv("AZURE_AISEARCH_SETUP_INDEX"); + private static final String AZURE_AISEARCH_MAX_RESULTS = System.getenv("AZURE_AISEARCH_MAX_RESULTS"); + private static final String AZURE_AISEARCH_MIN_SCORE = System.getenv("AZURE_AISEARCH_MIN_SCORE"); + private static final String AZURE_AISEARCH_QUERY_TYPE = System.getenv("AZURE_AISEARCH_QUERY_TYPE"); ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(AutoConfig.class)); +// @Test +// void should_provide_ai_search_store() { +// contextRunner +// .withPropertyValues( +// "langchain4j.azure.ai-search.api-key=" + AZURE_AISEARCH_API_KEY, +// "langchain4j.azure.ai-search.endpoint=" + AZURE_AISEARCH_ENDPOINT, +// "langchain4j.azure.ai-search.dimensions=" + AZURE_AISEARCH_DIMENSIONS, +// "langchain4j.azure.ai-search.setup-index=" + AZURE_AISEARCH_SETUP_INDEX +// ) +// .run(context -> { +// +// EmbeddingStore azureAiSearchEmbeddingStore = context.getBean(AzureAiSearchEmbeddingStore.class); +// assertThat(azureAiSearchEmbeddingStore).isInstanceOf(AzureAiSearchEmbeddingStore.class); +// +// assertThat(context.getBean(AzureAiSearchEmbeddingStore.class)).isSameAs(azureAiSearchEmbeddingStore); +// }); +// } + @Test - void should_provide_ai_search_store() { + void should_provide_ai_search_retriver_only_search() { contextRunner .withPropertyValues( "langchain4j.azure.ai-search.api-key=" + AZURE_AISEARCH_API_KEY, "langchain4j.azure.ai-search.endpoint=" + AZURE_AISEARCH_ENDPOINT, - "langchain4j.azure.ai-search.dimensions=" + AZURE_AISEARCH_DIMENSIONS, - "langchain4j.azure.ai-search.setup-index=" + AZURE_AISEARCH_SETUP_INDEX - ) + "langchain4j.azure.ai-search.dimensions=" + "0", + "langchain4j.azure.ai-search.create-or-update-index=" + "false", + "langchain4j.azure.ai-search.max-results=" + AZURE_AISEARCH_MAX_RESULTS, + "langchain4j.azure.ai-search.min-score=" + AZURE_AISEARCH_MIN_SCORE, + "langchain4j.azure.ai-search.query-type=" + "FULL_TEXT" + ).withBean(EmbeddingModel.class, AllMiniLmL6V2EmbeddingModel::new) .run(context -> { + ContentRetriever contentRetriever = context.getBean(AzureAiSearchContentRetriever.class); + assertThat(contentRetriever).isInstanceOf(AzureAiSearchContentRetriever.class); - EmbeddingStore azureAiSearchEmbeddingStore = context.getBean(AzureAiSearchEmbeddingStore.class); - assertThat(azureAiSearchEmbeddingStore).isInstanceOf(AzureAiSearchEmbeddingStore.class); - - assertThat(context.getBean(AzureAiSearchEmbeddingStore.class)).isSameAs(azureAiSearchEmbeddingStore); + assertThat(context.getBean(ContentRetriever.class)).isSameAs(contentRetriever); }); } @Test - void should_provide_ai_search_retriver() { + void should_provide_ai_search_retrive_create_or_uodate_indexr() { contextRunner .withPropertyValues( "langchain4j.azure.ai-search.api-key=" + AZURE_AISEARCH_API_KEY, "langchain4j.azure.ai-search.endpoint=" + AZURE_AISEARCH_ENDPOINT, - "langchain4j.azure.ai-search.dimensions=" + AZURE_AISEARCH_DIMENSIONS - ) + "langchain4j.azure.ai-search.dimensions=" + AZURE_AISEARCH_DIMENSIONS, + "langchain4j.azure.ai-search.create-or-update-index=" + "true", + "langchain4j.azure.ai-search.max-results=" + AZURE_AISEARCH_MAX_RESULTS, + "langchain4j.azure.ai-search.min-score=" + AZURE_AISEARCH_MIN_SCORE, + "langchain4j.azure.ai-search.query-type=" + "VECTOR" + ).withBean(EmbeddingModel.class, AllMiniLmL6V2EmbeddingModel::new) .run(context -> { ContentRetriever contentRetriever = context.getBean(AzureAiSearchContentRetriever.class); assertThat(contentRetriever).isInstanceOf(AzureAiSearchContentRetriever.class); diff --git a/langchain4j-open-ai-spring-boot-starter/pom.xml b/langchain4j-open-ai-spring-boot-starter/pom.xml index da853fe..7a3861b 100644 --- a/langchain4j-open-ai-spring-boot-starter/pom.xml +++ b/langchain4j-open-ai-spring-boot-starter/pom.xml @@ -1,6 +1,6 @@ - 4.0.0 diff --git a/pom.xml b/pom.xml index 02d5fc3..210cf78 100644 --- a/pom.xml +++ b/pom.xml @@ -1,6 +1,6 @@ - 4.0.0 From 16864e16d9e9a910c424fc3e72c3f026119f885f Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Tue, 26 Mar 2024 12:56:17 +0800 Subject: [PATCH 28/49] Revert "bumped to 0.29.0-SNAPSHOT" This reverts commit a7fa4aca1a377a63327f914b7efad2ff7680ba45. --- langchain4j-ollama-spring-boot-starter/pom.xml | 2 +- langchain4j-open-ai-spring-boot-starter/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/langchain4j-ollama-spring-boot-starter/pom.xml b/langchain4j-ollama-spring-boot-starter/pom.xml index 26e911c..a5d55ff 100644 --- a/langchain4j-ollama-spring-boot-starter/pom.xml +++ b/langchain4j-ollama-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ dev.langchain4j langchain4j-spring - 0.29.0-SNAPSHOT + 0.28.0 ../pom.xml diff --git a/langchain4j-open-ai-spring-boot-starter/pom.xml b/langchain4j-open-ai-spring-boot-starter/pom.xml index 7a3861b..e023c08 100644 --- a/langchain4j-open-ai-spring-boot-starter/pom.xml +++ b/langchain4j-open-ai-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ dev.langchain4j langchain4j-spring - 0.29.0-SNAPSHOT + 0.28.0 ../pom.xml diff --git a/pom.xml b/pom.xml index 210cf78..b863004 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ dev.langchain4j langchain4j-spring - 0.29.0-SNAPSHOT + 0.28.0 pom langchain4j-spring parent POM From 6296d25d371a681ea27095897b0a1ebedfec33fb Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Tue, 26 Mar 2024 12:58:35 +0800 Subject: [PATCH 29/49] rollback the distributionManagement --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index b863004..991f935 100644 --- a/pom.xml +++ b/pom.xml @@ -180,10 +180,10 @@ - - github - https://maven.pkg.github.com/showpune/langchain4j - + + ossrh + https://s01.oss.sonatype.org/content/repositories/snapshots + From ec6edbc039bfec552f4dd939fda26c7e6f73d072 Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Tue, 26 Mar 2024 12:59:33 +0800 Subject: [PATCH 30/49] Reapply "bumped to 0.29.0-SNAPSHOT" This reverts commit ed5be1b1526298f959d6cccafdc4048db839d813. --- langchain4j-ollama-spring-boot-starter/pom.xml | 2 +- langchain4j-open-ai-spring-boot-starter/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/langchain4j-ollama-spring-boot-starter/pom.xml b/langchain4j-ollama-spring-boot-starter/pom.xml index a5d55ff..26e911c 100644 --- a/langchain4j-ollama-spring-boot-starter/pom.xml +++ b/langchain4j-ollama-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ dev.langchain4j langchain4j-spring - 0.28.0 + 0.29.0-SNAPSHOT ../pom.xml diff --git a/langchain4j-open-ai-spring-boot-starter/pom.xml b/langchain4j-open-ai-spring-boot-starter/pom.xml index e023c08..7a3861b 100644 --- a/langchain4j-open-ai-spring-boot-starter/pom.xml +++ b/langchain4j-open-ai-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ dev.langchain4j langchain4j-spring - 0.28.0 + 0.29.0-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index 991f935..9d65ea4 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ dev.langchain4j langchain4j-spring - 0.28.0 + 0.29.0-SNAPSHOT pom langchain4j-spring parent POM From bf227f2def93d3954c858f1364cb8cc7499f6ed4 Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Tue, 26 Mar 2024 13:14:42 +0800 Subject: [PATCH 31/49] Add Default value support --- .../java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java | 1 - 1 file changed, 1 deletion(-) diff --git a/langchain4j-azure-aisearch-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java b/langchain4j-azure-aisearch-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java index 4813071..fcb9e34 100644 --- a/langchain4j-azure-aisearch-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java +++ b/langchain4j-azure-aisearch-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java @@ -51,7 +51,6 @@ void should_provide_ai_search_retriver_only_search() { "langchain4j.azure.ai-search.dimensions=" + "0", "langchain4j.azure.ai-search.create-or-update-index=" + "false", "langchain4j.azure.ai-search.max-results=" + AZURE_AISEARCH_MAX_RESULTS, - "langchain4j.azure.ai-search.min-score=" + AZURE_AISEARCH_MIN_SCORE, "langchain4j.azure.ai-search.query-type=" + "FULL_TEXT" ).withBean(EmbeddingModel.class, AllMiniLmL6V2EmbeddingModel::new) .run(context -> { From 9c475aa7a608c17a52550b7bc7daf98c96d72687 Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Tue, 26 Mar 2024 13:18:02 +0800 Subject: [PATCH 32/49] Rollback the other components --- langchain4j-ollama-spring-boot-starter/pom.xml | 3 ++- langchain4j-open-ai-spring-boot-starter/pom.xml | 7 ++++--- pom.xml | 5 ++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/langchain4j-ollama-spring-boot-starter/pom.xml b/langchain4j-ollama-spring-boot-starter/pom.xml index 26e911c..5715436 100644 --- a/langchain4j-ollama-spring-boot-starter/pom.xml +++ b/langchain4j-ollama-spring-boot-starter/pom.xml @@ -7,12 +7,13 @@ dev.langchain4j langchain4j-spring - 0.29.0-SNAPSHOT + 0.28.0-SNAPSHOT ../pom.xml langchain4j-ollama-spring-boot-starter LangChain4j Spring Boot starter for Ollama + jar diff --git a/langchain4j-open-ai-spring-boot-starter/pom.xml b/langchain4j-open-ai-spring-boot-starter/pom.xml index 7a3861b..0c22824 100644 --- a/langchain4j-open-ai-spring-boot-starter/pom.xml +++ b/langchain4j-open-ai-spring-boot-starter/pom.xml @@ -1,18 +1,19 @@ - 4.0.0 dev.langchain4j langchain4j-spring - 0.29.0-SNAPSHOT + 0.28.0-SNAPSHOT ../pom.xml langchain4j-open-ai-spring-boot-starter LangChain4j Spring Boot starter for OpenAI + jar diff --git a/pom.xml b/pom.xml index 9d65ea4..809fd34 100644 --- a/pom.xml +++ b/pom.xml @@ -1,6 +1,6 @@ - 4.0.0 @@ -178,7 +178,6 @@ - ossrh From 7b9364eccb8b4589c0793b425fb332b9342fd756 Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Tue, 26 Mar 2024 13:29:58 +0800 Subject: [PATCH 33/49] Rollback the other components --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- langchain4j-ollama-spring-boot-starter/pom.xml | 3 +-- langchain4j-open-ai-spring-boot-starter/pom.xml | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index b23448f..ccd0f27 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -23,7 +23,7 @@ Please provide a relevant code snippets to reproduce this bug. A clear and concise description of what you expected to happen. **Please complete the following information:** -- LangChain4j version: e.g. 0.27.0 +- LangChain4j version: e.g. 0.28.0 - Java version: e.g. 11 - Spring Boot version: e.g. 2.7.18 diff --git a/langchain4j-ollama-spring-boot-starter/pom.xml b/langchain4j-ollama-spring-boot-starter/pom.xml index 5715436..26e911c 100644 --- a/langchain4j-ollama-spring-boot-starter/pom.xml +++ b/langchain4j-ollama-spring-boot-starter/pom.xml @@ -7,13 +7,12 @@ dev.langchain4j langchain4j-spring - 0.28.0-SNAPSHOT + 0.29.0-SNAPSHOT ../pom.xml langchain4j-ollama-spring-boot-starter LangChain4j Spring Boot starter for Ollama - jar diff --git a/langchain4j-open-ai-spring-boot-starter/pom.xml b/langchain4j-open-ai-spring-boot-starter/pom.xml index 0c22824..da853fe 100644 --- a/langchain4j-open-ai-spring-boot-starter/pom.xml +++ b/langchain4j-open-ai-spring-boot-starter/pom.xml @@ -7,13 +7,12 @@ dev.langchain4j langchain4j-spring - 0.28.0-SNAPSHOT + 0.29.0-SNAPSHOT ../pom.xml langchain4j-open-ai-spring-boot-starter LangChain4j Spring Boot starter for OpenAI - jar From de2978c22d6d69c7873c229c8ad219708be4a2ce Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Tue, 26 Mar 2024 13:47:41 +0800 Subject: [PATCH 34/49] Rollback the other components --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a843373..75571b4 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ # langchain4j-spring +This repository contains Spring Boot starters for popular integrations. +Starters for other integrations will be added with time. -LangChain4j integration with Spring +### [Documentation](https://docs.langchain4j.dev/tutorials/spring-boot-integration) From 118a42954dfd9fc656aa1239ee663681f9d3c94d Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Wed, 27 Mar 2024 11:24:23 +0800 Subject: [PATCH 35/49] Add Non Azure Support --- .../azure/aisearch/spring/Properties.java | 2 +- .../azure/aisearch/spring/AutoConfigIT.java | 19 ------ .../pom.xml | 7 +++ .../azure/openai/spring/AutoConfig.java | 63 ++++++++++++------- .../openai/spring/ChatModelProperties.java | 9 +-- .../spring/EmbeddingModelProperties.java | 6 +- .../openai/spring/ImageModelProperties.java | 11 +--- .../azure/openai/AutoConfigIT.java | 8 ++- 8 files changed, 62 insertions(+), 63 deletions(-) diff --git a/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java b/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java index adbc290..7ac5438 100644 --- a/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java +++ b/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java @@ -17,6 +17,6 @@ public class Properties { int dimensions; boolean createOrUpdateIndex; int maxResults = 1; - double minScore = 0.6; + double minScore; AzureAiSearchQueryType queryType; } diff --git a/langchain4j-azure-aisearch-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java b/langchain4j-azure-aisearch-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java index fcb9e34..17726d9 100644 --- a/langchain4j-azure-aisearch-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java +++ b/langchain4j-azure-aisearch-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java @@ -20,28 +20,9 @@ class AutoConfigIT { private static final String AZURE_AISEARCH_MIN_SCORE = System.getenv("AZURE_AISEARCH_MIN_SCORE"); private static final String AZURE_AISEARCH_QUERY_TYPE = System.getenv("AZURE_AISEARCH_QUERY_TYPE"); - ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(AutoConfig.class)); -// @Test -// void should_provide_ai_search_store() { -// contextRunner -// .withPropertyValues( -// "langchain4j.azure.ai-search.api-key=" + AZURE_AISEARCH_API_KEY, -// "langchain4j.azure.ai-search.endpoint=" + AZURE_AISEARCH_ENDPOINT, -// "langchain4j.azure.ai-search.dimensions=" + AZURE_AISEARCH_DIMENSIONS, -// "langchain4j.azure.ai-search.setup-index=" + AZURE_AISEARCH_SETUP_INDEX -// ) -// .run(context -> { -// -// EmbeddingStore azureAiSearchEmbeddingStore = context.getBean(AzureAiSearchEmbeddingStore.class); -// assertThat(azureAiSearchEmbeddingStore).isInstanceOf(AzureAiSearchEmbeddingStore.class); -// -// assertThat(context.getBean(AzureAiSearchEmbeddingStore.class)).isSameAs(azureAiSearchEmbeddingStore); -// }); -// } - @Test void should_provide_ai_search_retriver_only_search() { contextRunner diff --git a/langchain4j-azure-openai-spring-boot-starter/pom.xml b/langchain4j-azure-openai-spring-boot-starter/pom.xml index f2417b9..0fad493 100644 --- a/langchain4j-azure-openai-spring-boot-starter/pom.xml +++ b/langchain4j-azure-openai-spring-boot-starter/pom.xml @@ -54,6 +54,13 @@ test + + dev.langchain4j + langchain4j-open-ai + 0.29.0-SNAPSHOT + test + + diff --git a/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java b/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java index db91ffb..3b5d900 100644 --- a/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java +++ b/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java @@ -2,15 +2,20 @@ import com.azure.core.http.ProxyOptions; import com.azure.core.util.Configuration; +import dev.langchain4j.model.Tokenizer; import dev.langchain4j.model.azure.AzureOpenAiChatModel; import dev.langchain4j.model.azure.AzureOpenAiEmbeddingModel; import dev.langchain4j.model.azure.AzureOpenAiImageModel; import dev.langchain4j.model.azure.AzureOpenAiStreamingChatModel; import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; +import java.time.Duration; + import static dev.langchain4j.azure.openai.spring.Properties.PREFIX; @AutoConfiguration @@ -18,31 +23,34 @@ public class AutoConfig { @Bean - @ConditionalOnProperty(PREFIX + ".chat-model.api-key") + @ConditionalOnProperty(PREFIX + ".chat-model.deployment-name") + @ConfigurationProperties AzureOpenAiChatModel openAiChatModel(Properties properties) { ChatModelProperties chatModelProperties = properties.getChatModel(); - return AzureOpenAiChatModel.builder() + AzureOpenAiChatModel.Builder builder = AzureOpenAiChatModel.builder() .endpoint(chatModelProperties.getEndpoint()) .apiKey(chatModelProperties.getApiKey()) .deploymentName(chatModelProperties.getDeploymentName()) .temperature(chatModelProperties.getTemperature()) .topP(chatModelProperties.getTopP()) - .stop(chatModelProperties.getStop()) .maxTokens(chatModelProperties.getMaxTokens()) .presencePenalty(chatModelProperties.getPresencePenalty()) .frequencyPenalty(chatModelProperties.getFrequencyPenalty()) - .timeout(chatModelProperties.getTimeout()) + .timeout(Duration.ofSeconds(chatModelProperties.getTimeout())) .maxRetries(chatModelProperties.getMaxRetries()) .proxyOptions(ProxyOptions.fromConfiguration(Configuration.getGlobalConfiguration())) - .logRequestsAndResponses(chatModelProperties.getLogRequestsAndResponses() != null && chatModelProperties.getLogRequestsAndResponses()) - .build(); + .logRequestsAndResponses(chatModelProperties.getLogRequestsAndResponses() != null && chatModelProperties.getLogRequestsAndResponses()); + if (chatModelProperties.getNonAzureApiKey() != null) { + builder.nonAzureApiKey(chatModelProperties.getNonAzureApiKey()); + } + return builder.build(); } @Bean - @ConditionalOnProperty(PREFIX + ".streaming-chat-model.api-key") + @ConditionalOnProperty(PREFIX + ".streaming-chat-model.deployment-name") AzureOpenAiStreamingChatModel openAiStreamingChatModel(Properties properties) { ChatModelProperties chatModelProperties = properties.getStreamingChatModel(); - return AzureOpenAiStreamingChatModel.builder() + AzureOpenAiStreamingChatModel.Builder builder= AzureOpenAiStreamingChatModel.builder() .endpoint(chatModelProperties.getEndpoint()) .apiKey(chatModelProperties.getApiKey()) .deploymentName(chatModelProperties.getDeploymentName()) @@ -52,32 +60,40 @@ AzureOpenAiStreamingChatModel openAiStreamingChatModel(Properties properties) { .maxTokens(chatModelProperties.getMaxTokens()) .presencePenalty(chatModelProperties.getPresencePenalty()) .frequencyPenalty(chatModelProperties.getFrequencyPenalty()) - .timeout(chatModelProperties.getTimeout()) + .timeout(Duration.ofSeconds(chatModelProperties.getTimeout())) .proxyOptions(ProxyOptions.fromConfiguration(Configuration.getGlobalConfiguration())) - .logRequestsAndResponses(chatModelProperties.getLogRequestsAndResponses() != null && chatModelProperties.getLogRequestsAndResponses()) - .build(); + .logRequestsAndResponses(chatModelProperties.getLogRequestsAndResponses() != null && chatModelProperties.getLogRequestsAndResponses()); + if (chatModelProperties.getNonAzureApiKey() != null) { + builder.nonAzureApiKey(chatModelProperties.getNonAzureApiKey()); + } + return builder.build(); } @Bean - @ConditionalOnProperty(PREFIX + ".embedding-model.api-key") - AzureOpenAiEmbeddingModel openAiEmbeddingModel(Properties properties) { + @ConditionalOnProperty({PREFIX + ".embedding-model.deployment-name"}) + @ConditionalOnBean(Tokenizer.class) + AzureOpenAiEmbeddingModel openAiEmbeddingModel(Properties properties, Tokenizer tokenizer) { EmbeddingModelProperties embeddingModelProperties = properties.getEmbeddingModel(); - return AzureOpenAiEmbeddingModel.builder() + AzureOpenAiEmbeddingModel.Builder builder= AzureOpenAiEmbeddingModel.builder() .endpoint(embeddingModelProperties.getEndpoint()) .apiKey(embeddingModelProperties.getApiKey()) .deploymentName(embeddingModelProperties.getDeploymentName()) - .timeout(embeddingModelProperties.getTimeout()) .maxRetries(embeddingModelProperties.getMaxRetries()) + .tokenizer(tokenizer) .proxyOptions(ProxyOptions.fromConfiguration(Configuration.getGlobalConfiguration())) - .logRequestsAndResponses(embeddingModelProperties.getLogRequestsAndResponses() != null && embeddingModelProperties.getLogRequestsAndResponses()) - .build(); + .logRequestsAndResponses(embeddingModelProperties.getLogRequestsAndResponses() != null && embeddingModelProperties.getLogRequestsAndResponses()); + + if (embeddingModelProperties.getNonAzureApiKey() != null) { + builder.nonAzureApiKey(embeddingModelProperties.getNonAzureApiKey()); + } + return builder.build(); } @Bean - @ConditionalOnProperty(PREFIX + ".image-model.api-key") + @ConditionalOnProperty(PREFIX + ".image-model.deployment-name") AzureOpenAiImageModel openAiImageModel(Properties properties) { ImageModelProperties imageModelProperties = properties.getImageModel(); - return AzureOpenAiImageModel.builder() + AzureOpenAiImageModel.Builder builder= AzureOpenAiImageModel.builder() .endpoint(imageModelProperties.getEndpoint()) .apiKey(imageModelProperties.getApiKey()) .deploymentName(imageModelProperties.getDeploymentName()) @@ -86,10 +102,13 @@ AzureOpenAiImageModel openAiImageModel(Properties properties) { .style(imageModelProperties.getStyle()) .user(imageModelProperties.getUser()) .responseFormat(imageModelProperties.getResponseFormat()) - .timeout(imageModelProperties.getTimeout()) + .timeout(Duration.ofSeconds(imageModelProperties.getTimeout())) .maxRetries(imageModelProperties.getMaxRetries()) .proxyOptions(ProxyOptions.fromConfiguration(Configuration.getGlobalConfiguration())) - .logRequestsAndResponses(imageModelProperties.getLogRequestsAndResponses() != null && imageModelProperties.getLogRequestsAndResponses()) - .build(); + .logRequestsAndResponses(imageModelProperties.getLogRequestsAndResponses() != null && imageModelProperties.getLogRequestsAndResponses()); + if (imageModelProperties.getNonAzureApiKey() != null) { + builder.nonAzureApiKey(imageModelProperties.getNonAzureApiKey()); + } + return builder.build(); } } \ No newline at end of file diff --git a/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java b/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java index b2a4e0a..cd41523 100644 --- a/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java +++ b/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java @@ -3,9 +3,7 @@ import lombok.Getter; import lombok.Setter; -import java.time.Duration; import java.util.List; -import java.util.Map; @Getter @Setter @@ -13,19 +11,18 @@ class ChatModelProperties { String endpoint; String apiKey; + String nonAzureApiKey; String organizationId; String deploymentName; Double temperature; Double topP; - List stop; Integer maxTokens; Double presencePenalty; Double frequencyPenalty; - Map logitBias; String responseFormat; Integer seed; - String user; - Duration timeout; + List stop; + int timeout; Integer maxRetries; Boolean logRequestsAndResponses; } \ No newline at end of file diff --git a/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java b/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java index f3c2a7c..8a69e31 100644 --- a/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java +++ b/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java @@ -3,19 +3,15 @@ import lombok.Getter; import lombok.Setter; -import java.time.Duration; - @Getter @Setter class EmbeddingModelProperties { String endpoint; String apiKey; - String organizationId; + String nonAzureApiKey; String deploymentName; Integer dimensions; - String user; - Duration timeout; Integer maxRetries; Boolean logRequestsAndResponses; } \ No newline at end of file diff --git a/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java b/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java index 41d15ea..5613080 100644 --- a/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java +++ b/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java @@ -3,25 +3,20 @@ import lombok.Getter; import lombok.Setter; -import java.nio.file.Path; -import java.time.Duration; - @Getter @Setter class ImageModelProperties { String endpoint; String apiKey; - String organizationId; + String nonAzureApiKey; String deploymentName; String size; String quality; String style; - String user; String responseFormat; - Duration timeout; + String user; + int timeout; Integer maxRetries; Boolean logRequestsAndResponses; - Boolean withPersisting; - Path persistTo; } \ No newline at end of file diff --git a/langchain4j-azure-openai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java b/langchain4j-azure-openai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java index e58f74d..39382be 100644 --- a/langchain4j-azure-openai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java +++ b/langchain4j-azure-openai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java @@ -11,6 +11,7 @@ import dev.langchain4j.model.chat.StreamingChatLanguageModel; import dev.langchain4j.model.embedding.EmbeddingModel; import dev.langchain4j.model.image.ImageModel; +import dev.langchain4j.model.openai.OpenAiTokenizer; import dev.langchain4j.model.output.Response; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; @@ -39,7 +40,8 @@ void should_provide_chat_model() { "langchain4j.azure.open-ai.chat-model.api-key=" + AZURE_OPENAI_KEY, "langchain4j.azure.open-ai.chat-model.endpoint=" + AZURE_OPENAI_ENDPOINT, "langchain4j.azure.open-ai.chat-model.deployment-name=" + AZURE_OPENAI_DEPLOYMENT_NAME, - "langchain4j.azure.open-ai.chat-model.max-tokens=20" + "langchain4j.azure.open-ai.chat-model.max-tokens=20", + "langchain4j.azure.open-ai.streaming-chat-model.timeout=60" ) .run(context -> { @@ -58,7 +60,8 @@ void should_provide_streaming_chat_model() { "langchain4j.azure.open-ai.streaming-chat-model.api-key=" + AZURE_OPENAI_KEY, "langchain4j.azure.open-ai.streaming-chat-model.endpoint=" + AZURE_OPENAI_ENDPOINT, "langchain4j.azure.open-ai.streaming-chat-model.deployment-name=" + AZURE_OPENAI_DEPLOYMENT_NAME, - "langchain4j.azure.open-ai.streaming-chat-model.max-tokens=20" + "langchain4j.azure.open-ai.streaming-chat-model.max-tokens=20", + "langchain4j.azure.open-ai.streaming-chat-model.timeout=60" ) .run(context -> { @@ -94,6 +97,7 @@ void should_provide_embedding_model() { .withPropertyValues("langchain4j.azure.open-ai.embedding-model.api-key=" + AZURE_OPENAI_KEY, "langchain4j.azure.open-ai.embedding-model.endpoint=" + AZURE_OPENAI_ENDPOINT, "langchain4j.azure.open-ai.embedding-model.deployment-name=" + AZURE_EMBEDDING_DEPLOYMENT_NAME) + .withBean(OpenAiTokenizer.class, () -> new OpenAiTokenizer("gpt-3.5-turbo")) .run(context -> { EmbeddingModel embeddingModel = context.getBean(EmbeddingModel.class); From 43fc5266e879d230aaff3a70a895f218ed5c5841 Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Thu, 28 Mar 2024 15:06:32 +0800 Subject: [PATCH 36/49] NonAzureKey not depends on deployment --- .../azure/openai/spring/AutoConfig.java | 56 +++++++++++++++++-- .../azure/openai/AutoConfigIT.java | 21 ++++++- 2 files changed, 72 insertions(+), 5 deletions(-) diff --git a/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java b/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java index 3b5d900..03f6f97 100644 --- a/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java +++ b/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java @@ -9,6 +9,7 @@ import dev.langchain4j.model.azure.AzureOpenAiStreamingChatModel; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -22,9 +23,21 @@ @EnableConfigurationProperties(Properties.class) public class AutoConfig { + @Bean - @ConditionalOnProperty(PREFIX + ".chat-model.deployment-name") + @ConditionalOnProperty(PREFIX + ".chat-model.api-key") @ConfigurationProperties + AzureOpenAiChatModel openAiChatModelByAPIKey(Properties properties) { + return openAiChatModel(properties); + } + + @Bean + @ConditionalOnProperty(PREFIX + ".chat-model.non-azure-api-key") + @ConditionalOnMissingBean(AzureOpenAiChatModel.class) + AzureOpenAiChatModel openAiChatModelByNonAzureApiKey(Properties properties) { + return openAiChatModel(properties); + } + AzureOpenAiChatModel openAiChatModel(Properties properties) { ChatModelProperties chatModelProperties = properties.getChatModel(); AzureOpenAiChatModel.Builder builder = AzureOpenAiChatModel.builder() @@ -47,7 +60,19 @@ AzureOpenAiChatModel openAiChatModel(Properties properties) { } @Bean - @ConditionalOnProperty(PREFIX + ".streaming-chat-model.deployment-name") + @ConditionalOnProperty(PREFIX + ".streaming-chat-model.api-key") + AzureOpenAiStreamingChatModel openAiStreamingChatModelByApiKey(Properties properties) { + return openAiStreamingChatModel(properties); + } + + @Bean + @ConditionalOnProperty(PREFIX + ".streaming-chat-model.non-azure-api-key") + @ConditionalOnMissingBean(AzureOpenAiStreamingChatModel.class) + AzureOpenAiStreamingChatModel openAiStreamingChatModelByNonAzureApiKey(Properties properties) { + return openAiStreamingChatModel(properties); + } + + AzureOpenAiStreamingChatModel openAiStreamingChatModel(Properties properties) { ChatModelProperties chatModelProperties = properties.getStreamingChatModel(); AzureOpenAiStreamingChatModel.Builder builder= AzureOpenAiStreamingChatModel.builder() @@ -70,8 +95,20 @@ AzureOpenAiStreamingChatModel openAiStreamingChatModel(Properties properties) { } @Bean - @ConditionalOnProperty({PREFIX + ".embedding-model.deployment-name"}) + @ConditionalOnProperty({PREFIX + ".embedding-model.api-key"}) @ConditionalOnBean(Tokenizer.class) + AzureOpenAiEmbeddingModel openAiEmbeddingModelByApiKey(Properties properties, Tokenizer tokenizer){ + return openAiEmbeddingModel(properties, tokenizer); + } + + @Bean + @ConditionalOnProperty({PREFIX + ".embedding-model.non-azure-api-key"}) + @ConditionalOnBean(Tokenizer.class) + @ConditionalOnMissingBean(AzureOpenAiEmbeddingModel.class) + AzureOpenAiEmbeddingModel openAiEmbeddingModelByNonAzureApiKey(Properties properties, Tokenizer tokenizer){ + return openAiEmbeddingModel(properties, tokenizer); + } + AzureOpenAiEmbeddingModel openAiEmbeddingModel(Properties properties, Tokenizer tokenizer) { EmbeddingModelProperties embeddingModelProperties = properties.getEmbeddingModel(); AzureOpenAiEmbeddingModel.Builder builder= AzureOpenAiEmbeddingModel.builder() @@ -90,7 +127,18 @@ AzureOpenAiEmbeddingModel openAiEmbeddingModel(Properties properties, Tokenizer } @Bean - @ConditionalOnProperty(PREFIX + ".image-model.deployment-name") + @ConditionalOnProperty(PREFIX + ".image-model.api-key") + AzureOpenAiImageModel openAiImageModelByApiKey(Properties properties){ + return openAiImageModel(properties); + } + + @Bean + @ConditionalOnProperty(PREFIX + ".image-model.non-azure-api-key") + @ConditionalOnMissingBean(AzureOpenAiImageModel.class) + AzureOpenAiImageModel openAiImageModelByNonAzureApiKey(Properties properties){ + return openAiImageModel(properties); + } + AzureOpenAiImageModel openAiImageModel(Properties properties) { ImageModelProperties imageModelProperties = properties.getImageModel(); AzureOpenAiImageModel.Builder builder= AzureOpenAiImageModel.builder() diff --git a/langchain4j-azure-openai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java b/langchain4j-azure-openai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java index 39382be..628db6a 100644 --- a/langchain4j-azure-openai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java +++ b/langchain4j-azure-openai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java @@ -30,6 +30,8 @@ class AutoConfigIT { private static final String AZURE_DALLE3_DEPLOYMENT_NAME = System.getenv("AZURE_DALLE3_DEPLOYMENT_NAME"); private static final String AZURE_EMBEDDING_DEPLOYMENT_NAME = System.getenv("AZURE_EMBEDDING_DEPLOYMENT_NAME"); + private static final String NO_AZURE_OPENAI_KEY = System.getenv("NO_AZURE_OPENAI_KEY"); + ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(AutoConfig.class)); @@ -40,8 +42,25 @@ void should_provide_chat_model() { "langchain4j.azure.open-ai.chat-model.api-key=" + AZURE_OPENAI_KEY, "langchain4j.azure.open-ai.chat-model.endpoint=" + AZURE_OPENAI_ENDPOINT, "langchain4j.azure.open-ai.chat-model.deployment-name=" + AZURE_OPENAI_DEPLOYMENT_NAME, + "langchain4j.azure.open-ai.chat-model.max-tokens=20" + ) + .run(context -> { + + ChatLanguageModel chatLanguageModel = context.getBean(ChatLanguageModel.class); + assertThat(chatLanguageModel).isInstanceOf(AzureOpenAiChatModel.class); + assertThat(chatLanguageModel.generate("What is the capital of Germany?")).contains("Berlin"); + + assertThat(context.getBean(AzureOpenAiChatModel.class)).isSameAs(chatLanguageModel); + }); + } + + @Test + void should_provide_chat_model_no_azure() { + contextRunner + .withPropertyValues( + "langchain4j.azure.open-ai.chat-model.non-azure-api-key=" + NO_AZURE_OPENAI_KEY, "langchain4j.azure.open-ai.chat-model.max-tokens=20", - "langchain4j.azure.open-ai.streaming-chat-model.timeout=60" + "langchain4j.azure.open-ai.chat-model.timeout=60" ) .run(context -> { From f0c5dea26753f8cc048e268ebd41f5bb8c938d98 Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Fri, 29 Mar 2024 09:28:15 +0800 Subject: [PATCH 37/49] Update langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java Co-authored-by: LangChain4j --- .../java/dev/langchain4j/azure/aisearch/spring/Properties.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java b/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java index 7ac5438..e99464c 100644 --- a/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java +++ b/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java @@ -16,7 +16,7 @@ public class Properties { String apiKey; int dimensions; boolean createOrUpdateIndex; - int maxResults = 1; + int maxResults = 3; double minScore; AzureAiSearchQueryType queryType; } From 0ad06f0613aa38884af32f40b8ccf477efc2d4ae Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Fri, 29 Mar 2024 09:28:43 +0800 Subject: [PATCH 38/49] Update langchain4j-azure-openai-spring-boot-starter/pom.xml Co-authored-by: LangChain4j --- langchain4j-azure-openai-spring-boot-starter/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langchain4j-azure-openai-spring-boot-starter/pom.xml b/langchain4j-azure-openai-spring-boot-starter/pom.xml index 0fad493..edbebf6 100644 --- a/langchain4j-azure-openai-spring-boot-starter/pom.xml +++ b/langchain4j-azure-openai-spring-boot-starter/pom.xml @@ -11,7 +11,7 @@ ../pom.xml - langchain4j-azure-openai-spring-boot-starter + langchain4j-azure-open-ai-spring-boot-starter LangChain4j Spring Boot starter for Azure OpenAI jar From a62be40be6f8b345baaaf024ac37ee02523294f7 Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Fri, 29 Mar 2024 09:28:57 +0800 Subject: [PATCH 39/49] Update pom.xml Co-authored-by: LangChain4j --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 809fd34..f9d7040 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ langchain4j-anthropic-spring-boot-starter langchain4j-ollama-spring-boot-starter langchain4j-open-ai-spring-boot-starter - langchain4j-azure-aisearch-spring-boot-starter + langchain4j-azure-ai-search-spring-boot-starter langchain4j-azure-openai-spring-boot-starter From 08cb971ff5634e6cb75fc2061488e6005d01d4d2 Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Fri, 29 Mar 2024 09:29:04 +0800 Subject: [PATCH 40/49] Update pom.xml Co-authored-by: LangChain4j --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f9d7040..533f463 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ langchain4j-ollama-spring-boot-starter langchain4j-open-ai-spring-boot-starter langchain4j-azure-ai-search-spring-boot-starter - langchain4j-azure-openai-spring-boot-starter + langchain4j-azure-open-ai-spring-boot-starter From 0e2b24d2a0462472a58fe185ef43064c678a01c6 Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Fri, 29 Mar 2024 09:29:10 +0800 Subject: [PATCH 41/49] Update langchain4j-azure-aisearch-spring-boot-starter/pom.xml Co-authored-by: LangChain4j --- langchain4j-azure-aisearch-spring-boot-starter/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langchain4j-azure-aisearch-spring-boot-starter/pom.xml b/langchain4j-azure-aisearch-spring-boot-starter/pom.xml index db398e9..2904d8b 100644 --- a/langchain4j-azure-aisearch-spring-boot-starter/pom.xml +++ b/langchain4j-azure-aisearch-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ dev.langchain4j langchain4j-spring - 0.29.0-SNAPSHOT + 0.29.0 ../pom.xml From 7dc5bfd6c41545d7307123df5fdc5a4a4c86d733 Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Fri, 29 Mar 2024 09:29:17 +0800 Subject: [PATCH 42/49] Update langchain4j-azure-aisearch-spring-boot-starter/pom.xml Co-authored-by: LangChain4j --- langchain4j-azure-aisearch-spring-boot-starter/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langchain4j-azure-aisearch-spring-boot-starter/pom.xml b/langchain4j-azure-aisearch-spring-boot-starter/pom.xml index 2904d8b..cee2c60 100644 --- a/langchain4j-azure-aisearch-spring-boot-starter/pom.xml +++ b/langchain4j-azure-aisearch-spring-boot-starter/pom.xml @@ -11,7 +11,7 @@ ../pom.xml - langchain4j-azure-aisearch-spring-boot-starter + langchain4j-azure-ai-search-spring-boot-starter LangChain4j Spring Boot starter for Azure AI Search jar From 019b56d6ec8899787337fec784a083af8bbaa43b Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Fri, 29 Mar 2024 09:29:23 +0800 Subject: [PATCH 43/49] Update langchain4j-azure-aisearch-spring-boot-starter/pom.xml Co-authored-by: LangChain4j --- langchain4j-azure-aisearch-spring-boot-starter/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langchain4j-azure-aisearch-spring-boot-starter/pom.xml b/langchain4j-azure-aisearch-spring-boot-starter/pom.xml index cee2c60..41e6ee2 100644 --- a/langchain4j-azure-aisearch-spring-boot-starter/pom.xml +++ b/langchain4j-azure-aisearch-spring-boot-starter/pom.xml @@ -56,7 +56,7 @@ dev.langchain4j langchain4j-embeddings-all-minilm-l6-v2 - 0.29.0-SNAPSHOT + 0.29.0 test From a72d00a08bcda9226d4c868b5f365bfa400ad54b Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Fri, 29 Mar 2024 14:22:57 +0800 Subject: [PATCH 44/49] Fix the review problems --- .../pom.xml | 0 .../azure/aisearch/spring/AutoConfig.java | 47 +++++++++++ .../azure/aisearch/spring/Properties.java | 33 ++++++++ .../main/resources/META-INF/spring.factories | 0 ...ot.autoconfigure.AutoConfiguration.imports | 0 .../azure/aisearch/spring/AutoConfigIT.java | 79 +++++++++++++++++++ .../azure/aisearch/spring/AutoConfig.java | 30 ------- .../azure/aisearch/spring/Properties.java | 22 ------ .../azure/aisearch/spring/AutoConfigIT.java | 65 --------------- .../pom.xml | 6 +- .../azure/openai/spring/AutoConfig.java | 0 .../openai/spring/ChatModelProperties.java | 0 .../spring/EmbeddingModelProperties.java | 0 .../openai/spring/ImageModelProperties.java | 0 .../azure/openai/spring/Properties.java | 0 .../main/resources/META-INF/spring.factories | 0 ...ot.autoconfigure.AutoConfiguration.imports | 0 .../azure/openai/AutoConfigIT.java | 5 +- 18 files changed, 166 insertions(+), 121 deletions(-) rename {langchain4j-azure-aisearch-spring-boot-starter => langchain4j-azure-ai-search-spring-boot-starter}/pom.xml (100%) create mode 100644 langchain4j-azure-ai-search-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java create mode 100644 langchain4j-azure-ai-search-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java rename {langchain4j-azure-aisearch-spring-boot-starter => langchain4j-azure-ai-search-spring-boot-starter}/src/main/resources/META-INF/spring.factories (100%) rename {langchain4j-azure-aisearch-spring-boot-starter => langchain4j-azure-ai-search-spring-boot-starter}/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports (100%) create mode 100644 langchain4j-azure-ai-search-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java delete mode 100644 langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java delete mode 100644 langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java delete mode 100644 langchain4j-azure-aisearch-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java rename {langchain4j-azure-openai-spring-boot-starter => langchain4j-azure-open-ai-spring-boot-starter}/pom.xml (92%) rename {langchain4j-azure-openai-spring-boot-starter => langchain4j-azure-open-ai-spring-boot-starter}/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java (100%) rename {langchain4j-azure-openai-spring-boot-starter => langchain4j-azure-open-ai-spring-boot-starter}/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java (100%) rename {langchain4j-azure-openai-spring-boot-starter => langchain4j-azure-open-ai-spring-boot-starter}/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java (100%) rename {langchain4j-azure-openai-spring-boot-starter => langchain4j-azure-open-ai-spring-boot-starter}/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java (100%) rename {langchain4j-azure-openai-spring-boot-starter => langchain4j-azure-open-ai-spring-boot-starter}/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java (100%) rename {langchain4j-azure-openai-spring-boot-starter => langchain4j-azure-open-ai-spring-boot-starter}/src/main/resources/META-INF/spring.factories (100%) rename {langchain4j-azure-openai-spring-boot-starter => langchain4j-azure-open-ai-spring-boot-starter}/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports (100%) rename {langchain4j-azure-openai-spring-boot-starter => langchain4j-azure-open-ai-spring-boot-starter}/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java (97%) diff --git a/langchain4j-azure-aisearch-spring-boot-starter/pom.xml b/langchain4j-azure-ai-search-spring-boot-starter/pom.xml similarity index 100% rename from langchain4j-azure-aisearch-spring-boot-starter/pom.xml rename to langchain4j-azure-ai-search-spring-boot-starter/pom.xml diff --git a/langchain4j-azure-ai-search-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java b/langchain4j-azure-ai-search-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java new file mode 100644 index 0000000..75b5ba2 --- /dev/null +++ b/langchain4j-azure-ai-search-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java @@ -0,0 +1,47 @@ +package dev.langchain4j.azure.aisearch.spring; + +import com.azure.search.documents.indexes.models.SearchIndex; +import dev.langchain4j.model.embedding.EmbeddingModel; +import dev.langchain4j.rag.content.retriever.azure.search.AzureAiSearchContentRetriever; +import dev.langchain4j.store.embedding.azure.search.AzureAiSearchEmbeddingStore; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.lang.Nullable; + +import static dev.langchain4j.azure.aisearch.spring.Properties.PREFIX; + +@AutoConfiguration +@EnableConfigurationProperties(Properties.class) +public class AutoConfig { + @Bean + @ConditionalOnProperty(PREFIX + ".content-retriver.api-key") + public AzureAiSearchContentRetriever azureAiSearchContentRetriever(Properties properties, @Nullable EmbeddingModel embeddingModel, @Nullable SearchIndex index) { + Properties.NestedProperties nestedProperties = properties.getContentRetriver(); + return AzureAiSearchContentRetriever.builder() + .endpoint(nestedProperties.getEndpoint()) + .apiKey(nestedProperties.getApiKey()) + .createOrUpdateIndex(nestedProperties.isCreateOrUpdateIndex()) + .embeddingModel(embeddingModel) + .dimensions(nestedProperties.getDimensions()) + .index(index) + .maxResults(nestedProperties.getMaxResults()) + .minScore(nestedProperties.getMinScore()) + .queryType(nestedProperties.getQueryType()) + .build(); + } + + @Bean + @ConditionalOnProperty(PREFIX + ".embedding-store.api-key") + public AzureAiSearchEmbeddingStore azureAiSearchEmbeddingStore(Properties properties, @Nullable EmbeddingModel embeddingModel, @Nullable SearchIndex index) { + Properties.NestedProperties nestedProperties = properties.getEmbeddingStore(); + return AzureAiSearchEmbeddingStore.builder() + .endpoint(nestedProperties.getEndpoint()) + .apiKey(nestedProperties.getApiKey()) + .createOrUpdateIndex(nestedProperties.isCreateOrUpdateIndex()) + .dimensions(nestedProperties.getDimensions()) + .index(index) + .build(); + } +} \ No newline at end of file diff --git a/langchain4j-azure-ai-search-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java b/langchain4j-azure-ai-search-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java new file mode 100644 index 0000000..0361b71 --- /dev/null +++ b/langchain4j-azure-ai-search-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java @@ -0,0 +1,33 @@ +package dev.langchain4j.azure.aisearch.spring; + +import dev.langchain4j.rag.content.retriever.azure.search.AzureAiSearchQueryType; +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.NestedConfigurationProperty; + +@Getter +@Setter +@ConfigurationProperties(prefix = Properties.PREFIX) +public class Properties { + + static final String PREFIX = "langchain4j.azure.ai-search"; + + @NestedConfigurationProperty + NestedProperties contentRetriver; + + @NestedConfigurationProperty + NestedProperties embeddingStore; + + @Getter + @Setter + public static class NestedProperties { + String endpoint; + String apiKey; + int dimensions; + boolean createOrUpdateIndex; + int maxResults = 3; + double minScore; + AzureAiSearchQueryType queryType; + } +} \ No newline at end of file diff --git a/langchain4j-azure-aisearch-spring-boot-starter/src/main/resources/META-INF/spring.factories b/langchain4j-azure-ai-search-spring-boot-starter/src/main/resources/META-INF/spring.factories similarity index 100% rename from langchain4j-azure-aisearch-spring-boot-starter/src/main/resources/META-INF/spring.factories rename to langchain4j-azure-ai-search-spring-boot-starter/src/main/resources/META-INF/spring.factories diff --git a/langchain4j-azure-aisearch-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/langchain4j-azure-ai-search-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports similarity index 100% rename from langchain4j-azure-aisearch-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports rename to langchain4j-azure-ai-search-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports diff --git a/langchain4j-azure-ai-search-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java b/langchain4j-azure-ai-search-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java new file mode 100644 index 0000000..00871f4 --- /dev/null +++ b/langchain4j-azure-ai-search-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java @@ -0,0 +1,79 @@ +package dev.langchain4j.azure.aisearch.spring; + +import dev.langchain4j.model.embedding.AllMiniLmL6V2EmbeddingModel; +import dev.langchain4j.model.embedding.EmbeddingModel; +import dev.langchain4j.rag.content.retriever.ContentRetriever; +import dev.langchain4j.rag.content.retriever.azure.search.AzureAiSearchContentRetriever; +import dev.langchain4j.store.embedding.EmbeddingStore; +import dev.langchain4j.store.embedding.azure.search.AzureAiSearchEmbeddingStore; +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +class AutoConfigIT { + + private static final String AZURE_AISEARCH_API_KEY = System.getenv("AZURE_AISEARCH_API_KEY"); + private static final String AZURE_AISEARCH_ENDPOINT = System.getenv("AZURE_AISEARCH_ENDPOINT"); + private static final String AZURE_AISEARCH_DIMENSIONS = System.getenv("AZURE_AISEARCH_DIMENSIONS"); + private static final String AZURE_AISEARCH_MAX_RESULTS = System.getenv("AZURE_AISEARCH_MAX_RESULTS"); + private static final String AZURE_AISEARCH_MIN_SCORE = System.getenv("AZURE_AISEARCH_MIN_SCORE"); + + ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(AutoConfig.class)); + + @Test + void should_provide_ai_search_retriver_only_search() { + contextRunner + .withPropertyValues( + Properties.PREFIX + ".content-retriver.api-key=" + AZURE_AISEARCH_API_KEY, + Properties.PREFIX + ".content-retriver.endpoint=" + AZURE_AISEARCH_ENDPOINT, + Properties.PREFIX + ".content-retriver.create-or-update-index=" + "false", + Properties.PREFIX + ".content-retriver.query-type=" + "FULL_TEXT" + ).run(context -> { + ContentRetriever contentRetriever = context.getBean(ContentRetriever.class); + assertThat(contentRetriever).isInstanceOf(AzureAiSearchContentRetriever.class); + + assertThat(context.getBean(AzureAiSearchContentRetriever.class)).isSameAs(contentRetriever); + }); + } + + @Test + void should_provide_ai_search_retrive_create_or_update_indexr() { + contextRunner + .withPropertyValues( + Properties.PREFIX + ".content-retriver.api-key=" + AZURE_AISEARCH_API_KEY, + Properties.PREFIX + ".content-retriver.endpoint=" + AZURE_AISEARCH_ENDPOINT, + Properties.PREFIX + ".content-retriver.dimensions=" + AZURE_AISEARCH_DIMENSIONS, + Properties.PREFIX + ".content-retriver.create-or-update-index=" + "true", + Properties.PREFIX + ".content-retriver.max-results=" + AZURE_AISEARCH_MAX_RESULTS, + Properties.PREFIX + ".content-retriver.min-score=" + AZURE_AISEARCH_MIN_SCORE, + Properties.PREFIX + ".content-retriver.query-type=" + "VECTOR" + ).withBean(EmbeddingModel.class, AllMiniLmL6V2EmbeddingModel::new) + .run(context -> { + ContentRetriever contentRetriever = context.getBean(ContentRetriever.class); + assertThat(contentRetriever).isInstanceOf(AzureAiSearchContentRetriever.class); + + assertThat(context.getBean(AzureAiSearchContentRetriever.class)).isSameAs(contentRetriever); + }); + } + + @Test + void should_provide_ai_search_embedding_store() { + contextRunner + .withPropertyValues( + Properties.PREFIX + ".embedding-store.api-key=" + AZURE_AISEARCH_API_KEY, + Properties.PREFIX + ".embedding-store.endpoint=" + AZURE_AISEARCH_ENDPOINT, + Properties.PREFIX + ".embedding-store.dimensions=" + AZURE_AISEARCH_DIMENSIONS, + Properties.PREFIX + ".embedding-store.create-or-update-index=" + "true" + ).withBean(EmbeddingModel.class, AllMiniLmL6V2EmbeddingModel::new) + .run(context -> { + EmbeddingStore embeddingStore = context.getBean(EmbeddingStore.class); + assertThat(embeddingStore).isInstanceOf(AzureAiSearchEmbeddingStore.class); + + assertThat(context.getBean(AzureAiSearchEmbeddingStore.class)).isSameAs(embeddingStore); + }); + } + +} \ No newline at end of file diff --git a/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java b/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java deleted file mode 100644 index 2a779b4..0000000 --- a/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java +++ /dev/null @@ -1,30 +0,0 @@ -package dev.langchain4j.azure.aisearch.spring; - -import dev.langchain4j.model.embedding.EmbeddingModel; -import dev.langchain4j.rag.content.retriever.azure.search.AzureAiSearchContentRetriever; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; - -import static dev.langchain4j.azure.aisearch.spring.Properties.PREFIX; - -@AutoConfiguration -@EnableConfigurationProperties(Properties.class) -public class AutoConfig { - - @Bean - @ConditionalOnProperty(PREFIX + ".api-key") - public AzureAiSearchContentRetriever azureAiSearchContentRetriever(Properties properties, EmbeddingModel embeddingModel) { - return AzureAiSearchContentRetriever.builder() - .endpoint(properties.getEndpoint()) - .apiKey(properties.getApiKey()) - .createOrUpdateIndex(properties.isCreateOrUpdateIndex()) - .embeddingModel(embeddingModel) - .dimensions(properties.getDimensions()) - .maxResults(properties.getMaxResults()) - .minScore(properties.getMinScore()) - .queryType(properties.getQueryType()) - .build(); - } -} \ No newline at end of file diff --git a/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java b/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java deleted file mode 100644 index e99464c..0000000 --- a/langchain4j-azure-aisearch-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java +++ /dev/null @@ -1,22 +0,0 @@ -package dev.langchain4j.azure.aisearch.spring; - -import dev.langchain4j.rag.content.retriever.azure.search.AzureAiSearchQueryType; -import lombok.Getter; -import lombok.Setter; -import org.springframework.boot.context.properties.ConfigurationProperties; - -@Getter -@Setter -@ConfigurationProperties(prefix = Properties.PREFIX) -public class Properties { - - static final String PREFIX = "langchain4j.azure.ai-search"; - - String endpoint; - String apiKey; - int dimensions; - boolean createOrUpdateIndex; - int maxResults = 3; - double minScore; - AzureAiSearchQueryType queryType; -} diff --git a/langchain4j-azure-aisearch-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java b/langchain4j-azure-aisearch-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java deleted file mode 100644 index 17726d9..0000000 --- a/langchain4j-azure-aisearch-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java +++ /dev/null @@ -1,65 +0,0 @@ -package dev.langchain4j.azure.aisearch.spring; - -import dev.langchain4j.model.embedding.AllMiniLmL6V2EmbeddingModel; -import dev.langchain4j.model.embedding.EmbeddingModel; -import dev.langchain4j.rag.content.retriever.ContentRetriever; -import dev.langchain4j.rag.content.retriever.azure.search.AzureAiSearchContentRetriever; -import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -class AutoConfigIT { - - private static final String AZURE_AISEARCH_API_KEY = System.getenv("AZURE_AISEARCH_API_KEY"); - private static final String AZURE_AISEARCH_ENDPOINT = System.getenv("AZURE_AISEARCH_ENDPOINT"); - private static final String AZURE_AISEARCH_DIMENSIONS = System.getenv("AZURE_AISEARCH_DIMENSIONS"); - private static final String AZURE_AISEARCH_SETUP_INDEX = System.getenv("AZURE_AISEARCH_SETUP_INDEX"); - private static final String AZURE_AISEARCH_MAX_RESULTS = System.getenv("AZURE_AISEARCH_MAX_RESULTS"); - private static final String AZURE_AISEARCH_MIN_SCORE = System.getenv("AZURE_AISEARCH_MIN_SCORE"); - private static final String AZURE_AISEARCH_QUERY_TYPE = System.getenv("AZURE_AISEARCH_QUERY_TYPE"); - - ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(AutoConfig.class)); - - @Test - void should_provide_ai_search_retriver_only_search() { - contextRunner - .withPropertyValues( - "langchain4j.azure.ai-search.api-key=" + AZURE_AISEARCH_API_KEY, - "langchain4j.azure.ai-search.endpoint=" + AZURE_AISEARCH_ENDPOINT, - "langchain4j.azure.ai-search.dimensions=" + "0", - "langchain4j.azure.ai-search.create-or-update-index=" + "false", - "langchain4j.azure.ai-search.max-results=" + AZURE_AISEARCH_MAX_RESULTS, - "langchain4j.azure.ai-search.query-type=" + "FULL_TEXT" - ).withBean(EmbeddingModel.class, AllMiniLmL6V2EmbeddingModel::new) - .run(context -> { - ContentRetriever contentRetriever = context.getBean(AzureAiSearchContentRetriever.class); - assertThat(contentRetriever).isInstanceOf(AzureAiSearchContentRetriever.class); - - assertThat(context.getBean(ContentRetriever.class)).isSameAs(contentRetriever); - }); - } - - @Test - void should_provide_ai_search_retrive_create_or_uodate_indexr() { - contextRunner - .withPropertyValues( - "langchain4j.azure.ai-search.api-key=" + AZURE_AISEARCH_API_KEY, - "langchain4j.azure.ai-search.endpoint=" + AZURE_AISEARCH_ENDPOINT, - "langchain4j.azure.ai-search.dimensions=" + AZURE_AISEARCH_DIMENSIONS, - "langchain4j.azure.ai-search.create-or-update-index=" + "true", - "langchain4j.azure.ai-search.max-results=" + AZURE_AISEARCH_MAX_RESULTS, - "langchain4j.azure.ai-search.min-score=" + AZURE_AISEARCH_MIN_SCORE, - "langchain4j.azure.ai-search.query-type=" + "VECTOR" - ).withBean(EmbeddingModel.class, AllMiniLmL6V2EmbeddingModel::new) - .run(context -> { - ContentRetriever contentRetriever = context.getBean(AzureAiSearchContentRetriever.class); - assertThat(contentRetriever).isInstanceOf(AzureAiSearchContentRetriever.class); - - assertThat(context.getBean(ContentRetriever.class)).isSameAs(contentRetriever); - }); - } - -} \ No newline at end of file diff --git a/langchain4j-azure-openai-spring-boot-starter/pom.xml b/langchain4j-azure-open-ai-spring-boot-starter/pom.xml similarity index 92% rename from langchain4j-azure-openai-spring-boot-starter/pom.xml rename to langchain4j-azure-open-ai-spring-boot-starter/pom.xml index edbebf6..3c7d83e 100644 --- a/langchain4j-azure-openai-spring-boot-starter/pom.xml +++ b/langchain4j-azure-open-ai-spring-boot-starter/pom.xml @@ -56,8 +56,10 @@ dev.langchain4j - langchain4j-open-ai - 0.29.0-SNAPSHOT + langchain4j-core + ${project.version} + tests + test-jar test diff --git a/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java similarity index 100% rename from langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java rename to langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java diff --git a/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java similarity index 100% rename from langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java rename to langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java diff --git a/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java similarity index 100% rename from langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java rename to langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java diff --git a/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java similarity index 100% rename from langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java rename to langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java diff --git a/langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java similarity index 100% rename from langchain4j-azure-openai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java rename to langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java diff --git a/langchain4j-azure-openai-spring-boot-starter/src/main/resources/META-INF/spring.factories b/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring.factories similarity index 100% rename from langchain4j-azure-openai-spring-boot-starter/src/main/resources/META-INF/spring.factories rename to langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring.factories diff --git a/langchain4j-azure-openai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports similarity index 100% rename from langchain4j-azure-openai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports rename to langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports diff --git a/langchain4j-azure-openai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java b/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java similarity index 97% rename from langchain4j-azure-openai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java rename to langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java index 628db6a..bd0daba 100644 --- a/langchain4j-azure-openai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java @@ -2,7 +2,9 @@ import dev.langchain4j.azure.openai.spring.AutoConfig; import dev.langchain4j.data.message.AiMessage; +import dev.langchain4j.model.ExampleTestTokenizer; import dev.langchain4j.model.StreamingResponseHandler; +import dev.langchain4j.model.Tokenizer; import dev.langchain4j.model.azure.AzureOpenAiChatModel; import dev.langchain4j.model.azure.AzureOpenAiEmbeddingModel; import dev.langchain4j.model.azure.AzureOpenAiImageModel; @@ -11,7 +13,6 @@ import dev.langchain4j.model.chat.StreamingChatLanguageModel; import dev.langchain4j.model.embedding.EmbeddingModel; import dev.langchain4j.model.image.ImageModel; -import dev.langchain4j.model.openai.OpenAiTokenizer; import dev.langchain4j.model.output.Response; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; @@ -116,7 +117,7 @@ void should_provide_embedding_model() { .withPropertyValues("langchain4j.azure.open-ai.embedding-model.api-key=" + AZURE_OPENAI_KEY, "langchain4j.azure.open-ai.embedding-model.endpoint=" + AZURE_OPENAI_ENDPOINT, "langchain4j.azure.open-ai.embedding-model.deployment-name=" + AZURE_EMBEDDING_DEPLOYMENT_NAME) - .withBean(OpenAiTokenizer.class, () -> new OpenAiTokenizer("gpt-3.5-turbo")) + .withBean(Tokenizer.class, ExampleTestTokenizer::new) .run(context -> { EmbeddingModel embeddingModel = context.getBean(EmbeddingModel.class); From f7873caa7dbfce805f8f92299710583b4620606d Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Mon, 15 Apr 2024 21:07:53 +0800 Subject: [PATCH 45/49] Add function test for retriever and store --- .../pom.xml | 1 + .../azure/aisearch/spring/AutoConfig.java | 12 +- .../azure/aisearch/spring/Properties.java | 11 +- .../azure/aisearch/spring/AutoConfigIT.java | 192 +++++++++++++++--- .../azure/openai/spring/AutoConfig.java | 38 ++-- .../openai/spring/ChatModelProperties.java | 2 +- .../spring/EmbeddingModelProperties.java | 1 + .../main/resources/META-INF/spring.factories | 2 +- ...ot.autoconfigure.AutoConfiguration.imports | 2 +- .../openai/{ => spring}/AutoConfigIT.java | 38 ++-- 10 files changed, 216 insertions(+), 83 deletions(-) rename langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/{ => spring}/AutoConfigIT.java (88%) diff --git a/langchain4j-azure-ai-search-spring-boot-starter/pom.xml b/langchain4j-azure-ai-search-spring-boot-starter/pom.xml index 41e6ee2..d0e04f5 100644 --- a/langchain4j-azure-ai-search-spring-boot-starter/pom.xml +++ b/langchain4j-azure-ai-search-spring-boot-starter/pom.xml @@ -53,6 +53,7 @@ spring-boot-starter-test test + dev.langchain4j langchain4j-embeddings-all-minilm-l6-v2 diff --git a/langchain4j-azure-ai-search-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java b/langchain4j-azure-ai-search-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java index 75b5ba2..e801374 100644 --- a/langchain4j-azure-ai-search-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java +++ b/langchain4j-azure-ai-search-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/AutoConfig.java @@ -16,18 +16,18 @@ @EnableConfigurationProperties(Properties.class) public class AutoConfig { @Bean - @ConditionalOnProperty(PREFIX + ".content-retriver.api-key") + @ConditionalOnProperty(PREFIX + ".content-retriever.api-key") public AzureAiSearchContentRetriever azureAiSearchContentRetriever(Properties properties, @Nullable EmbeddingModel embeddingModel, @Nullable SearchIndex index) { - Properties.NestedProperties nestedProperties = properties.getContentRetriver(); + Properties.NestedProperties nestedProperties = properties.getContentRetriever(); return AzureAiSearchContentRetriever.builder() .endpoint(nestedProperties.getEndpoint()) .apiKey(nestedProperties.getApiKey()) - .createOrUpdateIndex(nestedProperties.isCreateOrUpdateIndex()) + .createOrUpdateIndex(nestedProperties.getCreateOrUpdateIndex()) .embeddingModel(embeddingModel) - .dimensions(nestedProperties.getDimensions()) + .dimensions(nestedProperties.getDimensions() == null ? 0 : nestedProperties.getDimensions()) .index(index) .maxResults(nestedProperties.getMaxResults()) - .minScore(nestedProperties.getMinScore()) + .minScore(nestedProperties.getMinScore() == null ? 0.0 : nestedProperties.getMinScore()) .queryType(nestedProperties.getQueryType()) .build(); } @@ -39,7 +39,7 @@ public AzureAiSearchEmbeddingStore azureAiSearchEmbeddingStore(Properties proper return AzureAiSearchEmbeddingStore.builder() .endpoint(nestedProperties.getEndpoint()) .apiKey(nestedProperties.getApiKey()) - .createOrUpdateIndex(nestedProperties.isCreateOrUpdateIndex()) + .createOrUpdateIndex(nestedProperties.getCreateOrUpdateIndex()) .dimensions(nestedProperties.getDimensions()) .index(index) .build(); diff --git a/langchain4j-azure-ai-search-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java b/langchain4j-azure-ai-search-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java index 0361b71..1931d7c 100644 --- a/langchain4j-azure-ai-search-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java +++ b/langchain4j-azure-ai-search-spring-boot-starter/src/main/java/dev/langchain4j/azure/aisearch/spring/Properties.java @@ -14,7 +14,7 @@ public class Properties { static final String PREFIX = "langchain4j.azure.ai-search"; @NestedConfigurationProperty - NestedProperties contentRetriver; + NestedProperties contentRetriever; @NestedConfigurationProperty NestedProperties embeddingStore; @@ -24,10 +24,11 @@ public class Properties { public static class NestedProperties { String endpoint; String apiKey; - int dimensions; - boolean createOrUpdateIndex; - int maxResults = 3; - double minScore; + Integer dimensions; + Boolean createOrUpdateIndex; + String indexName; + Integer maxResults = 3; + Double minScore; AzureAiSearchQueryType queryType; } } \ No newline at end of file diff --git a/langchain4j-azure-ai-search-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java b/langchain4j-azure-ai-search-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java index 00871f4..7bb2b7c 100644 --- a/langchain4j-azure-ai-search-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java +++ b/langchain4j-azure-ai-search-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java @@ -1,78 +1,210 @@ package dev.langchain4j.azure.aisearch.spring; +import com.azure.core.credential.AzureKeyCredential; +import com.azure.search.documents.indexes.SearchIndexClient; +import com.azure.search.documents.indexes.SearchIndexClientBuilder; +import com.azure.search.documents.indexes.models.SearchIndex; +import dev.langchain4j.data.embedding.Embedding; +import dev.langchain4j.data.segment.TextSegment; import dev.langchain4j.model.embedding.AllMiniLmL6V2EmbeddingModel; import dev.langchain4j.model.embedding.EmbeddingModel; +import dev.langchain4j.rag.content.Content; import dev.langchain4j.rag.content.retriever.ContentRetriever; import dev.langchain4j.rag.content.retriever.azure.search.AzureAiSearchContentRetriever; +import dev.langchain4j.rag.content.retriever.azure.search.AzureAiSearchQueryType; +import dev.langchain4j.rag.query.Query; +import dev.langchain4j.store.embedding.EmbeddingMatch; import dev.langchain4j.store.embedding.EmbeddingStore; import dev.langchain4j.store.embedding.azure.search.AzureAiSearchEmbeddingStore; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import java.util.List; + +import static dev.langchain4j.store.embedding.azure.search.AbstractAzureAiSearchEmbeddingStore.INDEX_NAME; +import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; class AutoConfigIT { - private static final String AZURE_AISEARCH_API_KEY = System.getenv("AZURE_AISEARCH_API_KEY"); - private static final String AZURE_AISEARCH_ENDPOINT = System.getenv("AZURE_AISEARCH_ENDPOINT"); - private static final String AZURE_AISEARCH_DIMENSIONS = System.getenv("AZURE_AISEARCH_DIMENSIONS"); - private static final String AZURE_AISEARCH_MAX_RESULTS = System.getenv("AZURE_AISEARCH_MAX_RESULTS"); - private static final String AZURE_AISEARCH_MIN_SCORE = System.getenv("AZURE_AISEARCH_MIN_SCORE"); - + private static final String AZURE_SEARCH_KEY = System.getenv("AZURE_SEARCH_KEY"); + private static final String AZURE_SEARCH_ENDPOINT = System.getenv("AZURE_SEARCH_ENDPOINT"); ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(AutoConfig.class)); + private static final Logger log = LoggerFactory.getLogger(AutoConfigIT.class); + + private final EmbeddingModel embeddingModel = new AllMiniLmL6V2EmbeddingModel(); + private final int dimensions = embeddingModel.embed("test").content().vector().length; + + private final SearchIndexClient searchIndexClient = new SearchIndexClientBuilder() + .endpoint(System.getenv("AZURE_SEARCH_ENDPOINT")) + .credential(new AzureKeyCredential(System.getenv("AZURE_SEARCH_KEY"))) + .buildClient(); + + private SearchIndex index = new SearchIndex(INDEX_NAME); + @Test - void should_provide_ai_search_retriver_only_search() { + void should_provide_ai_search_retriever() { + + searchIndexClient.deleteIndex(INDEX_NAME); + contextRunner .withPropertyValues( - Properties.PREFIX + ".content-retriver.api-key=" + AZURE_AISEARCH_API_KEY, - Properties.PREFIX + ".content-retriver.endpoint=" + AZURE_AISEARCH_ENDPOINT, - Properties.PREFIX + ".content-retriver.create-or-update-index=" + "false", - Properties.PREFIX + ".content-retriver.query-type=" + "FULL_TEXT" - ).run(context -> { + Properties.PREFIX + ".content-retriever.api-key=" + AZURE_SEARCH_KEY, + Properties.PREFIX + ".content-retriever.endpoint=" + AZURE_SEARCH_ENDPOINT, + Properties.PREFIX + ".content-retriever.dimensions=" + dimensions, + Properties.PREFIX + ".content-retriever.create-or-update-index=" + "true", + Properties.PREFIX + ".content-retriever.query-type=" + "VECTOR" + ).withBean(EmbeddingModel.class, () -> embeddingModel) + .run(context -> { ContentRetriever contentRetriever = context.getBean(ContentRetriever.class); assertThat(contentRetriever).isInstanceOf(AzureAiSearchContentRetriever.class); + AzureAiSearchContentRetriever azureAiSearchContentRetriever = (AzureAiSearchContentRetriever) contentRetriever; + + String content1 = "This book is about politics"; + String content2 = "Cats sleeps a lot."; + String content3 = "Sandwiches taste good."; + String content4 = "The house is open"; + List contents = asList(content1, content2, content3, content4); + + for (String content : contents) { + TextSegment textSegment = TextSegment.from(content); + Embedding embedding = embeddingModel.embed(content).content(); + azureAiSearchContentRetriever.add(embedding, textSegment); + } - assertThat(context.getBean(AzureAiSearchContentRetriever.class)).isSameAs(contentRetriever); + awaitUntilPersisted(); }); - } - @Test - void should_provide_ai_search_retrive_create_or_update_indexr() { + String content = "house"; + Query query = Query.from(content); + contextRunner .withPropertyValues( - Properties.PREFIX + ".content-retriver.api-key=" + AZURE_AISEARCH_API_KEY, - Properties.PREFIX + ".content-retriver.endpoint=" + AZURE_AISEARCH_ENDPOINT, - Properties.PREFIX + ".content-retriver.dimensions=" + AZURE_AISEARCH_DIMENSIONS, - Properties.PREFIX + ".content-retriver.create-or-update-index=" + "true", - Properties.PREFIX + ".content-retriver.max-results=" + AZURE_AISEARCH_MAX_RESULTS, - Properties.PREFIX + ".content-retriver.min-score=" + AZURE_AISEARCH_MIN_SCORE, - Properties.PREFIX + ".content-retriver.query-type=" + "VECTOR" - ).withBean(EmbeddingModel.class, AllMiniLmL6V2EmbeddingModel::new) + Properties.PREFIX + ".content-retriever.api-key=" + AZURE_SEARCH_KEY, + Properties.PREFIX + ".content-retriever.endpoint=" + AZURE_SEARCH_ENDPOINT, + Properties.PREFIX + ".content-retriever.create-or-update-index=" + "false", + Properties.PREFIX + ".content-retriever.query-type=" + AzureAiSearchQueryType.VECTOR + ).withBean(SearchIndex.class, () -> index) + .withBean(EmbeddingModel.class, () -> embeddingModel) .run(context -> { ContentRetriever contentRetriever = context.getBean(ContentRetriever.class); assertThat(contentRetriever).isInstanceOf(AzureAiSearchContentRetriever.class); + AzureAiSearchContentRetriever contentRetrieverWithVector = (AzureAiSearchContentRetriever) contentRetriever; + log.info("Testing Vector Search"); + List relevant = contentRetrieverWithVector.retrieve(query); + assertThat(relevant).hasSizeGreaterThan(0); + assertThat(relevant.get(0).textSegment().text()).isEqualTo("The house is open"); + log.info("#1 relevant item: {}", relevant.get(0).textSegment().text()); + }); - assertThat(context.getBean(AzureAiSearchContentRetriever.class)).isSameAs(contentRetriever); + contextRunner + .withPropertyValues( + Properties.PREFIX + ".content-retriever.api-key=" + AZURE_SEARCH_KEY, + Properties.PREFIX + ".content-retriever.endpoint=" + AZURE_SEARCH_ENDPOINT, + Properties.PREFIX + ".content-retriever.create-or-update-index=" + "false", + Properties.PREFIX + ".content-retriever.query-type=" + AzureAiSearchQueryType.FULL_TEXT + ) + .run(context -> { + ContentRetriever contentRetriever = context.getBean(ContentRetriever.class); + assertThat(contentRetriever).isInstanceOf(AzureAiSearchContentRetriever.class); + AzureAiSearchContentRetriever contentRetrieverWithFullText = (AzureAiSearchContentRetriever) contentRetriever; + log.info("Testing Full Text Search"); + // This uses the same storage as the vector search, so we don't need to add the content again + List relevant2 = contentRetrieverWithFullText.retrieve(query); + assertThat(relevant2).hasSizeGreaterThan(0); + assertThat(relevant2.get(0).textSegment().text()).isEqualTo("The house is open"); + log.info("#1 relevant item: {}", relevant2.get(0).textSegment().text()); }); + + contextRunner + .withPropertyValues( + Properties.PREFIX + ".content-retriever.api-key=" + AZURE_SEARCH_KEY, + Properties.PREFIX + ".content-retriever.endpoint=" + AZURE_SEARCH_ENDPOINT, + Properties.PREFIX + ".content-retriever.create-or-update-index=" + "false", + Properties.PREFIX + ".content-retriever.query-type=" + AzureAiSearchQueryType.HYBRID + ).withBean(SearchIndex.class, () -> index) + .withBean(EmbeddingModel.class, () -> embeddingModel) + .run(context -> { + ContentRetriever contentRetriever = context.getBean(ContentRetriever.class); + assertThat(contentRetriever).isInstanceOf(AzureAiSearchContentRetriever.class); + AzureAiSearchContentRetriever contentRetrieverWithHybrid = (AzureAiSearchContentRetriever) contentRetriever; + log.info("Testing Hybrid Search"); + List relevant3 = contentRetrieverWithHybrid.retrieve(query); + assertThat(relevant3).hasSizeGreaterThan(0); + assertThat(relevant3.get(0).textSegment().text()).isEqualTo("The house is open"); + log.info("#1 relevant item: {}", relevant3.get(0).textSegment().text()); + }); + + contextRunner + .withPropertyValues( + Properties.PREFIX + ".content-retriever.api-key=" + AZURE_SEARCH_KEY, + Properties.PREFIX + ".content-retriever.endpoint=" + AZURE_SEARCH_ENDPOINT, + Properties.PREFIX + ".content-retriever.create-or-update-index=" + "false", + Properties.PREFIX + ".content-retriever.query-type=" + AzureAiSearchQueryType.HYBRID_WITH_RERANKING + ).withBean(SearchIndex.class, () -> index) + .withBean(EmbeddingModel.class, () -> embeddingModel) + .run(context -> { + ContentRetriever contentRetriever = context.getBean(ContentRetriever.class); + assertThat(contentRetriever).isInstanceOf(AzureAiSearchContentRetriever.class); + AzureAiSearchContentRetriever contentRetrieverWithHybridAndReranking = (AzureAiSearchContentRetriever) contentRetriever; + log.info("Testing Hybrid Search with Reranking"); + List relevant4 = contentRetrieverWithHybridAndReranking.retrieve(query); + assertThat(relevant4).hasSizeGreaterThan(0); + assertThat(relevant4.get(0).textSegment().text()).isEqualTo("The house is open"); + log.info("#1 relevant item: {}", relevant4.get(0).textSegment().text()); + }); + } + + protected void awaitUntilPersisted() { + try { + Thread.sleep(1_000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } + @Test void should_provide_ai_search_embedding_store() { + + searchIndexClient.deleteIndex(INDEX_NAME); + contextRunner .withPropertyValues( - Properties.PREFIX + ".embedding-store.api-key=" + AZURE_AISEARCH_API_KEY, - Properties.PREFIX + ".embedding-store.endpoint=" + AZURE_AISEARCH_ENDPOINT, - Properties.PREFIX + ".embedding-store.dimensions=" + AZURE_AISEARCH_DIMENSIONS, + Properties.PREFIX + ".embedding-store.api-key=" + AZURE_SEARCH_KEY, + Properties.PREFIX + ".embedding-store.endpoint=" + AZURE_SEARCH_ENDPOINT, + Properties.PREFIX + ".embedding-store.dimensions=" + 384, Properties.PREFIX + ".embedding-store.create-or-update-index=" + "true" - ).withBean(EmbeddingModel.class, AllMiniLmL6V2EmbeddingModel::new) + ).withBean(EmbeddingModel.class, () -> embeddingModel) .run(context -> { EmbeddingStore embeddingStore = context.getBean(EmbeddingStore.class); assertThat(embeddingStore).isInstanceOf(AzureAiSearchEmbeddingStore.class); - assertThat(context.getBean(AzureAiSearchEmbeddingStore.class)).isSameAs(embeddingStore); + + + String content1 = "banana"; + String content2 = "computer"; + String content3 = "apple"; + String content4 = "pizza"; + String content5 = "strawberry"; + String content6 = "chess"; + List contents = asList(content1, content2, content3, content4, content5, content6); + + for (String content : contents) { + TextSegment textSegment = TextSegment.from(content); + Embedding embedding = embeddingModel.embed(content).content(); + embeddingStore.add(embedding, textSegment); + } + Embedding relevantEmbedding = embeddingModel.embed("fruit").content(); + List> relevant = embeddingStore.findRelevant(relevantEmbedding, 3); + assertThat(relevant).hasSize(3); + assertThat(relevant.get(0).embedding()).isNotNull(); + assertThat(relevant.get(0).embedded().text()).isIn(content1, content3, content5); }); } diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java index 03f6f97..78592e6 100644 --- a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java @@ -8,32 +8,26 @@ import dev.langchain4j.model.azure.AzureOpenAiImageModel; import dev.langchain4j.model.azure.AzureOpenAiStreamingChatModel; import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; +import org.springframework.lang.Nullable; import java.time.Duration; -import static dev.langchain4j.azure.openai.spring.Properties.PREFIX; - @AutoConfiguration @EnableConfigurationProperties(Properties.class) public class AutoConfig { @Bean - @ConditionalOnProperty(PREFIX + ".chat-model.api-key") - @ConfigurationProperties + @ConditionalOnProperty(Properties.PREFIX + ".chat-model.api-key") AzureOpenAiChatModel openAiChatModelByAPIKey(Properties properties) { return openAiChatModel(properties); } @Bean - @ConditionalOnProperty(PREFIX + ".chat-model.non-azure-api-key") - @ConditionalOnMissingBean(AzureOpenAiChatModel.class) + @ConditionalOnProperty(Properties.PREFIX + ".chat-model.non-azure-api-key") AzureOpenAiChatModel openAiChatModelByNonAzureApiKey(Properties properties) { return openAiChatModel(properties); } @@ -49,7 +43,7 @@ AzureOpenAiChatModel openAiChatModel(Properties properties) { .maxTokens(chatModelProperties.getMaxTokens()) .presencePenalty(chatModelProperties.getPresencePenalty()) .frequencyPenalty(chatModelProperties.getFrequencyPenalty()) - .timeout(Duration.ofSeconds(chatModelProperties.getTimeout())) + .timeout(Duration.ofSeconds(chatModelProperties.getTimeout() == null ? 0 : chatModelProperties.getTimeout())) .maxRetries(chatModelProperties.getMaxRetries()) .proxyOptions(ProxyOptions.fromConfiguration(Configuration.getGlobalConfiguration())) .logRequestsAndResponses(chatModelProperties.getLogRequestsAndResponses() != null && chatModelProperties.getLogRequestsAndResponses()); @@ -60,14 +54,13 @@ AzureOpenAiChatModel openAiChatModel(Properties properties) { } @Bean - @ConditionalOnProperty(PREFIX + ".streaming-chat-model.api-key") + @ConditionalOnProperty(Properties.PREFIX + ".streaming-chat-model.api-key") AzureOpenAiStreamingChatModel openAiStreamingChatModelByApiKey(Properties properties) { return openAiStreamingChatModel(properties); } @Bean - @ConditionalOnProperty(PREFIX + ".streaming-chat-model.non-azure-api-key") - @ConditionalOnMissingBean(AzureOpenAiStreamingChatModel.class) + @ConditionalOnProperty(Properties.PREFIX + ".streaming-chat-model.non-azure-api-key") AzureOpenAiStreamingChatModel openAiStreamingChatModelByNonAzureApiKey(Properties properties) { return openAiStreamingChatModel(properties); } @@ -85,7 +78,7 @@ AzureOpenAiStreamingChatModel openAiStreamingChatModel(Properties properties) { .maxTokens(chatModelProperties.getMaxTokens()) .presencePenalty(chatModelProperties.getPresencePenalty()) .frequencyPenalty(chatModelProperties.getFrequencyPenalty()) - .timeout(Duration.ofSeconds(chatModelProperties.getTimeout())) + .timeout(Duration.ofSeconds(chatModelProperties.getTimeout() == null ? 0 : chatModelProperties.getTimeout())) .proxyOptions(ProxyOptions.fromConfiguration(Configuration.getGlobalConfiguration())) .logRequestsAndResponses(chatModelProperties.getLogRequestsAndResponses() != null && chatModelProperties.getLogRequestsAndResponses()); if (chatModelProperties.getNonAzureApiKey() != null) { @@ -95,17 +88,14 @@ AzureOpenAiStreamingChatModel openAiStreamingChatModel(Properties properties) { } @Bean - @ConditionalOnProperty({PREFIX + ".embedding-model.api-key"}) - @ConditionalOnBean(Tokenizer.class) - AzureOpenAiEmbeddingModel openAiEmbeddingModelByApiKey(Properties properties, Tokenizer tokenizer){ + @ConditionalOnProperty({Properties.PREFIX + ".embedding-model.api-key"}) + AzureOpenAiEmbeddingModel openAiEmbeddingModelByApiKey(Properties properties, @Nullable Tokenizer tokenizer) { return openAiEmbeddingModel(properties, tokenizer); } @Bean - @ConditionalOnProperty({PREFIX + ".embedding-model.non-azure-api-key"}) - @ConditionalOnBean(Tokenizer.class) - @ConditionalOnMissingBean(AzureOpenAiEmbeddingModel.class) - AzureOpenAiEmbeddingModel openAiEmbeddingModelByNonAzureApiKey(Properties properties, Tokenizer tokenizer){ + @ConditionalOnProperty({Properties.PREFIX + ".embedding-model.non-azure-api-key"}) + AzureOpenAiEmbeddingModel openAiEmbeddingModelByNonAzureApiKey(Properties properties, @Nullable Tokenizer tokenizer) { return openAiEmbeddingModel(properties, tokenizer); } @@ -117,6 +107,7 @@ AzureOpenAiEmbeddingModel openAiEmbeddingModel(Properties properties, Tokenizer .deploymentName(embeddingModelProperties.getDeploymentName()) .maxRetries(embeddingModelProperties.getMaxRetries()) .tokenizer(tokenizer) + .timeout(Duration.ofSeconds(embeddingModelProperties.getTimeout() == null ? 0 : embeddingModelProperties.getTimeout())) .proxyOptions(ProxyOptions.fromConfiguration(Configuration.getGlobalConfiguration())) .logRequestsAndResponses(embeddingModelProperties.getLogRequestsAndResponses() != null && embeddingModelProperties.getLogRequestsAndResponses()); @@ -127,14 +118,13 @@ AzureOpenAiEmbeddingModel openAiEmbeddingModel(Properties properties, Tokenizer } @Bean - @ConditionalOnProperty(PREFIX + ".image-model.api-key") + @ConditionalOnProperty(Properties.PREFIX + ".image-model.api-key") AzureOpenAiImageModel openAiImageModelByApiKey(Properties properties){ return openAiImageModel(properties); } @Bean - @ConditionalOnProperty(PREFIX + ".image-model.non-azure-api-key") - @ConditionalOnMissingBean(AzureOpenAiImageModel.class) + @ConditionalOnProperty(Properties.PREFIX + ".image-model.non-azure-api-key") AzureOpenAiImageModel openAiImageModelByNonAzureApiKey(Properties properties){ return openAiImageModel(properties); } diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java index cd41523..2058afd 100644 --- a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ChatModelProperties.java @@ -22,7 +22,7 @@ class ChatModelProperties { String responseFormat; Integer seed; List stop; - int timeout; + Integer timeout; Integer maxRetries; Boolean logRequestsAndResponses; } \ No newline at end of file diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java index 8a69e31..c65cccc 100644 --- a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/EmbeddingModelProperties.java @@ -12,6 +12,7 @@ class EmbeddingModelProperties { String nonAzureApiKey; String deploymentName; Integer dimensions; + Integer timeout; Integer maxRetries; Boolean logRequestsAndResponses; } \ No newline at end of file diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring.factories b/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring.factories index 4db50a7..1b6bde2 100644 --- a/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring.factories +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring.factories @@ -1,2 +1,2 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -dev.langchain4j.azure.openai.spring.AutoConfig \ No newline at end of file +spring.dev.langchain4j.azure.openai.spring.AutoConfig \ No newline at end of file diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 4ab7c73..0dbadec 100644 --- a/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1 +1 @@ -dev.langchain4j.azure.openai.spring.AutoConfig \ No newline at end of file +spring.dev.langchain4j.azure.openai.spring.AutoConfig \ No newline at end of file diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java b/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/spring/AutoConfigIT.java similarity index 88% rename from langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java rename to langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/spring/AutoConfigIT.java index bd0daba..6fca94a 100644 --- a/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/AutoConfigIT.java +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/spring/AutoConfigIT.java @@ -1,10 +1,7 @@ -package dev.langchain4j.azure.openai; +package dev.langchain4j.azure.openai.spring; -import dev.langchain4j.azure.openai.spring.AutoConfig; import dev.langchain4j.data.message.AiMessage; -import dev.langchain4j.model.ExampleTestTokenizer; import dev.langchain4j.model.StreamingResponseHandler; -import dev.langchain4j.model.Tokenizer; import dev.langchain4j.model.azure.AzureOpenAiChatModel; import dev.langchain4j.model.azure.AzureOpenAiEmbeddingModel; import dev.langchain4j.model.azure.AzureOpenAiImageModel; @@ -15,6 +12,8 @@ import dev.langchain4j.model.image.ImageModel; import dev.langchain4j.model.output.Response; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -27,7 +26,6 @@ class AutoConfigIT { private static final String AZURE_OPENAI_KEY = System.getenv("AZURE_OPENAI_KEY"); private static final String AZURE_OPENAI_ENDPOINT = System.getenv("AZURE_OPENAI_ENDPOINT"); - private static final String AZURE_OPENAI_DEPLOYMENT_NAME = System.getenv("AZURE_OPENAI_DEPLOYMENT_NAME"); private static final String AZURE_DALLE3_DEPLOYMENT_NAME = System.getenv("AZURE_DALLE3_DEPLOYMENT_NAME"); private static final String AZURE_EMBEDDING_DEPLOYMENT_NAME = System.getenv("AZURE_EMBEDDING_DEPLOYMENT_NAME"); @@ -36,13 +34,17 @@ class AutoConfigIT { ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(AutoConfig.class)); - @Test - void should_provide_chat_model() { + @ParameterizedTest(name = "Deployment name: {0}") + @CsvSource({ + "gpt-35-turbo", + "gpt-4" + }) + void should_provide_chat_model(String deploymentName) { contextRunner .withPropertyValues( "langchain4j.azure.open-ai.chat-model.api-key=" + AZURE_OPENAI_KEY, "langchain4j.azure.open-ai.chat-model.endpoint=" + AZURE_OPENAI_ENDPOINT, - "langchain4j.azure.open-ai.chat-model.deployment-name=" + AZURE_OPENAI_DEPLOYMENT_NAME, + "langchain4j.azure.open-ai.chat-model.deployment-name=" + deploymentName, "langchain4j.azure.open-ai.chat-model.max-tokens=20" ) .run(context -> { @@ -50,16 +52,19 @@ void should_provide_chat_model() { ChatLanguageModel chatLanguageModel = context.getBean(ChatLanguageModel.class); assertThat(chatLanguageModel).isInstanceOf(AzureOpenAiChatModel.class); assertThat(chatLanguageModel.generate("What is the capital of Germany?")).contains("Berlin"); - assertThat(context.getBean(AzureOpenAiChatModel.class)).isSameAs(chatLanguageModel); }); } - @Test - void should_provide_chat_model_no_azure() { + @ParameterizedTest(name = "Deployment name: {0}") + @CsvSource({ + "gpt-3.5-turbo" + }) + void should_provide_chat_model_no_azure(String deploymentName) { contextRunner .withPropertyValues( "langchain4j.azure.open-ai.chat-model.non-azure-api-key=" + NO_AZURE_OPENAI_KEY, + "langchain4j.azure.open-ai.chat-model.deployment-name=" + deploymentName, "langchain4j.azure.open-ai.chat-model.max-tokens=20", "langchain4j.azure.open-ai.chat-model.timeout=60" ) @@ -73,13 +78,17 @@ void should_provide_chat_model_no_azure() { }); } - @Test - void should_provide_streaming_chat_model() { + @ParameterizedTest(name = "Deployment name: {0}") + @CsvSource({ + "gpt-35-turbo", + "gpt-4" + }) + void should_provide_streaming_chat_model(String deploymentName) { contextRunner .withPropertyValues( "langchain4j.azure.open-ai.streaming-chat-model.api-key=" + AZURE_OPENAI_KEY, "langchain4j.azure.open-ai.streaming-chat-model.endpoint=" + AZURE_OPENAI_ENDPOINT, - "langchain4j.azure.open-ai.streaming-chat-model.deployment-name=" + AZURE_OPENAI_DEPLOYMENT_NAME, + "langchain4j.azure.open-ai.streaming-chat-model.deployment-name=" + deploymentName, "langchain4j.azure.open-ai.streaming-chat-model.max-tokens=20", "langchain4j.azure.open-ai.streaming-chat-model.timeout=60" ) @@ -117,7 +126,6 @@ void should_provide_embedding_model() { .withPropertyValues("langchain4j.azure.open-ai.embedding-model.api-key=" + AZURE_OPENAI_KEY, "langchain4j.azure.open-ai.embedding-model.endpoint=" + AZURE_OPENAI_ENDPOINT, "langchain4j.azure.open-ai.embedding-model.deployment-name=" + AZURE_EMBEDDING_DEPLOYMENT_NAME) - .withBean(Tokenizer.class, ExampleTestTokenizer::new) .run(context -> { EmbeddingModel embeddingModel = context.getBean(EmbeddingModel.class); From 13ab9bb5e94215e4d8fdef8b6be802e920febeba Mon Sep 17 00:00:00 2001 From: Zhiyong Li Date: Tue, 16 Apr 2024 20:36:16 +0800 Subject: [PATCH 46/49] Update the test case --- .../dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/langchain4j-azure-ai-search-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java b/langchain4j-azure-ai-search-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java index 7bb2b7c..fbd183a 100644 --- a/langchain4j-azure-ai-search-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java +++ b/langchain4j-azure-ai-search-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java @@ -88,6 +88,8 @@ void should_provide_ai_search_retriever() { Properties.PREFIX + ".content-retriever.api-key=" + AZURE_SEARCH_KEY, Properties.PREFIX + ".content-retriever.endpoint=" + AZURE_SEARCH_ENDPOINT, Properties.PREFIX + ".content-retriever.create-or-update-index=" + "false", + Properties.PREFIX + ".content-retriever.max-results=" + "3", + Properties.PREFIX + ".content-retriever.min-score=" + "0.6", Properties.PREFIX + ".content-retriever.query-type=" + AzureAiSearchQueryType.VECTOR ).withBean(SearchIndex.class, () -> index) .withBean(EmbeddingModel.class, () -> embeddingModel) @@ -145,6 +147,8 @@ void should_provide_ai_search_retriever() { Properties.PREFIX + ".content-retriever.api-key=" + AZURE_SEARCH_KEY, Properties.PREFIX + ".content-retriever.endpoint=" + AZURE_SEARCH_ENDPOINT, Properties.PREFIX + ".content-retriever.create-or-update-index=" + "false", + Properties.PREFIX + ".content-retriever.max-results=" + "3", + Properties.PREFIX + ".content-retriever.min-score=" + "0.4", Properties.PREFIX + ".content-retriever.query-type=" + AzureAiSearchQueryType.HYBRID_WITH_RERANKING ).withBean(SearchIndex.class, () -> index) .withBean(EmbeddingModel.class, () -> embeddingModel) From cb110133f86ef96ed6e011dfe4bd145c36f76192 Mon Sep 17 00:00:00 2001 From: LangChain4j Date: Thu, 2 May 2024 18:32:31 +0200 Subject: [PATCH 47/49] cosmetics --- .../azure/aisearch/spring/AutoConfigIT.java | 31 ++++++------- .../azure/openai/spring/AutoConfig.java | 11 ++--- .../azure/openai/spring/Properties.java | 2 +- .../azure/openai/spring/AutoConfigIT.java | 46 +++++++++---------- 4 files changed, 41 insertions(+), 49 deletions(-) diff --git a/langchain4j-azure-ai-search-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java b/langchain4j-azure-ai-search-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java index fbd183a..19cf514 100644 --- a/langchain4j-azure-ai-search-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java +++ b/langchain4j-azure-ai-search-spring-boot-starter/src/test/java/dev/langchain4j/azure/aisearch/spring/AutoConfigIT.java @@ -30,22 +30,22 @@ class AutoConfigIT { + private static final Logger log = LoggerFactory.getLogger(AutoConfigIT.class); + private static final String AZURE_SEARCH_KEY = System.getenv("AZURE_SEARCH_KEY"); private static final String AZURE_SEARCH_ENDPOINT = System.getenv("AZURE_SEARCH_ENDPOINT"); - ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(AutoConfig.class)); - - private static final Logger log = LoggerFactory.getLogger(AutoConfigIT.class); private final EmbeddingModel embeddingModel = new AllMiniLmL6V2EmbeddingModel(); - private final int dimensions = embeddingModel.embed("test").content().vector().length; + private final int dimensions = embeddingModel.embed("test").content().dimension(); private final SearchIndexClient searchIndexClient = new SearchIndexClientBuilder() .endpoint(System.getenv("AZURE_SEARCH_ENDPOINT")) .credential(new AzureKeyCredential(System.getenv("AZURE_SEARCH_KEY"))) .buildClient(); + private final SearchIndex index = new SearchIndex(INDEX_NAME); - private SearchIndex index = new SearchIndex(INDEX_NAME); + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(AutoConfig.class)); @Test void should_provide_ai_search_retriever() { @@ -164,15 +164,6 @@ void should_provide_ai_search_retriever() { }); } - protected void awaitUntilPersisted() { - try { - Thread.sleep(1_000); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - - @Test void should_provide_ai_search_embedding_store() { @@ -186,11 +177,10 @@ void should_provide_ai_search_embedding_store() { Properties.PREFIX + ".embedding-store.create-or-update-index=" + "true" ).withBean(EmbeddingModel.class, () -> embeddingModel) .run(context -> { - EmbeddingStore embeddingStore = context.getBean(EmbeddingStore.class); + EmbeddingStore embeddingStore = context.getBean(EmbeddingStore.class); assertThat(embeddingStore).isInstanceOf(AzureAiSearchEmbeddingStore.class); assertThat(context.getBean(AzureAiSearchEmbeddingStore.class)).isSameAs(embeddingStore); - String content1 = "banana"; String content2 = "computer"; String content3 = "apple"; @@ -212,4 +202,11 @@ void should_provide_ai_search_embedding_store() { }); } + protected void awaitUntilPersisted() { + try { + Thread.sleep(1_000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } } \ No newline at end of file diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java index 78592e6..a1f3329 100644 --- a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java @@ -19,7 +19,6 @@ @EnableConfigurationProperties(Properties.class) public class AutoConfig { - @Bean @ConditionalOnProperty(Properties.PREFIX + ".chat-model.api-key") AzureOpenAiChatModel openAiChatModelByAPIKey(Properties properties) { @@ -68,7 +67,7 @@ AzureOpenAiStreamingChatModel openAiStreamingChatModelByNonAzureApiKey(Propertie AzureOpenAiStreamingChatModel openAiStreamingChatModel(Properties properties) { ChatModelProperties chatModelProperties = properties.getStreamingChatModel(); - AzureOpenAiStreamingChatModel.Builder builder= AzureOpenAiStreamingChatModel.builder() + AzureOpenAiStreamingChatModel.Builder builder = AzureOpenAiStreamingChatModel.builder() .endpoint(chatModelProperties.getEndpoint()) .apiKey(chatModelProperties.getApiKey()) .deploymentName(chatModelProperties.getDeploymentName()) @@ -101,7 +100,7 @@ AzureOpenAiEmbeddingModel openAiEmbeddingModelByNonAzureApiKey(Properties proper AzureOpenAiEmbeddingModel openAiEmbeddingModel(Properties properties, Tokenizer tokenizer) { EmbeddingModelProperties embeddingModelProperties = properties.getEmbeddingModel(); - AzureOpenAiEmbeddingModel.Builder builder= AzureOpenAiEmbeddingModel.builder() + AzureOpenAiEmbeddingModel.Builder builder = AzureOpenAiEmbeddingModel.builder() .endpoint(embeddingModelProperties.getEndpoint()) .apiKey(embeddingModelProperties.getApiKey()) .deploymentName(embeddingModelProperties.getDeploymentName()) @@ -119,19 +118,19 @@ AzureOpenAiEmbeddingModel openAiEmbeddingModel(Properties properties, Tokenizer @Bean @ConditionalOnProperty(Properties.PREFIX + ".image-model.api-key") - AzureOpenAiImageModel openAiImageModelByApiKey(Properties properties){ + AzureOpenAiImageModel openAiImageModelByApiKey(Properties properties) { return openAiImageModel(properties); } @Bean @ConditionalOnProperty(Properties.PREFIX + ".image-model.non-azure-api-key") - AzureOpenAiImageModel openAiImageModelByNonAzureApiKey(Properties properties){ + AzureOpenAiImageModel openAiImageModelByNonAzureApiKey(Properties properties) { return openAiImageModel(properties); } AzureOpenAiImageModel openAiImageModel(Properties properties) { ImageModelProperties imageModelProperties = properties.getImageModel(); - AzureOpenAiImageModel.Builder builder= AzureOpenAiImageModel.builder() + AzureOpenAiImageModel.Builder builder = AzureOpenAiImageModel.builder() .endpoint(imageModelProperties.getEndpoint()) .apiKey(imageModelProperties.getApiKey()) .deploymentName(imageModelProperties.getDeploymentName()) diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java index e2e6995..da11552 100644 --- a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/Properties.java @@ -10,7 +10,7 @@ @ConfigurationProperties(prefix = Properties.PREFIX) public class Properties { - static final String PREFIX = "langchain4j.azure.open-ai"; + static final String PREFIX = "langchain4j.azure-open-ai"; @NestedConfigurationProperty ChatModelProperties chatModel; diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/spring/AutoConfigIT.java b/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/spring/AutoConfigIT.java index 6fca94a..89eb071 100644 --- a/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/spring/AutoConfigIT.java +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/azure/openai/spring/AutoConfigIT.java @@ -26,12 +26,9 @@ class AutoConfigIT { private static final String AZURE_OPENAI_KEY = System.getenv("AZURE_OPENAI_KEY"); private static final String AZURE_OPENAI_ENDPOINT = System.getenv("AZURE_OPENAI_ENDPOINT"); - private static final String AZURE_DALLE3_DEPLOYMENT_NAME = System.getenv("AZURE_DALLE3_DEPLOYMENT_NAME"); - private static final String AZURE_EMBEDDING_DEPLOYMENT_NAME = System.getenv("AZURE_EMBEDDING_DEPLOYMENT_NAME"); + private static final String NO_AZURE_OPENAI_KEY = System.getenv("OPENAI_API_KEY"); - private static final String NO_AZURE_OPENAI_KEY = System.getenv("NO_AZURE_OPENAI_KEY"); - - ApplicationContextRunner contextRunner = new ApplicationContextRunner() + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(AutoConfig.class)); @ParameterizedTest(name = "Deployment name: {0}") @@ -42,10 +39,10 @@ class AutoConfigIT { void should_provide_chat_model(String deploymentName) { contextRunner .withPropertyValues( - "langchain4j.azure.open-ai.chat-model.api-key=" + AZURE_OPENAI_KEY, - "langchain4j.azure.open-ai.chat-model.endpoint=" + AZURE_OPENAI_ENDPOINT, - "langchain4j.azure.open-ai.chat-model.deployment-name=" + deploymentName, - "langchain4j.azure.open-ai.chat-model.max-tokens=20" + "langchain4j.azure-open-ai.chat-model.api-key=" + AZURE_OPENAI_KEY, + "langchain4j.azure-open-ai.chat-model.endpoint=" + AZURE_OPENAI_ENDPOINT, + "langchain4j.azure-open-ai.chat-model.deployment-name=" + deploymentName, + "langchain4j.azure-open-ai.chat-model.max-tokens=20" ) .run(context -> { @@ -63,10 +60,10 @@ void should_provide_chat_model(String deploymentName) { void should_provide_chat_model_no_azure(String deploymentName) { contextRunner .withPropertyValues( - "langchain4j.azure.open-ai.chat-model.non-azure-api-key=" + NO_AZURE_OPENAI_KEY, - "langchain4j.azure.open-ai.chat-model.deployment-name=" + deploymentName, - "langchain4j.azure.open-ai.chat-model.max-tokens=20", - "langchain4j.azure.open-ai.chat-model.timeout=60" + "langchain4j.azure-open-ai.chat-model.non-azure-api-key=" + NO_AZURE_OPENAI_KEY, + "langchain4j.azure-open-ai.chat-model.deployment-name=" + deploymentName, + "langchain4j.azure-open-ai.chat-model.max-tokens=20", + "langchain4j.azure-open-ai.chat-model.timeout=60" ) .run(context -> { @@ -86,11 +83,11 @@ void should_provide_chat_model_no_azure(String deploymentName) { void should_provide_streaming_chat_model(String deploymentName) { contextRunner .withPropertyValues( - "langchain4j.azure.open-ai.streaming-chat-model.api-key=" + AZURE_OPENAI_KEY, - "langchain4j.azure.open-ai.streaming-chat-model.endpoint=" + AZURE_OPENAI_ENDPOINT, - "langchain4j.azure.open-ai.streaming-chat-model.deployment-name=" + deploymentName, - "langchain4j.azure.open-ai.streaming-chat-model.max-tokens=20", - "langchain4j.azure.open-ai.streaming-chat-model.timeout=60" + "langchain4j.azure-open-ai.streaming-chat-model.api-key=" + AZURE_OPENAI_KEY, + "langchain4j.azure-open-ai.streaming-chat-model.endpoint=" + AZURE_OPENAI_ENDPOINT, + "langchain4j.azure-open-ai.streaming-chat-model.deployment-name=" + deploymentName, + "langchain4j.azure-open-ai.streaming-chat-model.max-tokens=20", + "langchain4j.azure-open-ai.streaming-chat-model.timeout=60" ) .run(context -> { @@ -119,13 +116,12 @@ public void onError(Throwable error) { }); } - @Test void should_provide_embedding_model() { contextRunner - .withPropertyValues("langchain4j.azure.open-ai.embedding-model.api-key=" + AZURE_OPENAI_KEY, - "langchain4j.azure.open-ai.embedding-model.endpoint=" + AZURE_OPENAI_ENDPOINT, - "langchain4j.azure.open-ai.embedding-model.deployment-name=" + AZURE_EMBEDDING_DEPLOYMENT_NAME) + .withPropertyValues("langchain4j.azure-open-ai.embedding-model.api-key=" + AZURE_OPENAI_KEY, + "langchain4j.azure-open-ai.embedding-model.endpoint=" + AZURE_OPENAI_ENDPOINT, + "langchain4j.azure-open-ai.embedding-model.deployment-name=" + "text-embedding-ada-002") .run(context -> { EmbeddingModel embeddingModel = context.getBean(EmbeddingModel.class); @@ -140,9 +136,9 @@ void should_provide_embedding_model() { void should_provide_image_model() { contextRunner .withPropertyValues( - "langchain4j.azure.open-ai.image-model.api-key=" + AZURE_OPENAI_KEY, - "langchain4j.azure.open-ai.image-model.endpoint=" + AZURE_OPENAI_ENDPOINT, - "langchain4j.azure.open-ai.image-model.deployment-name=" + AZURE_DALLE3_DEPLOYMENT_NAME + "langchain4j.azure-open-ai.image-model.api-key=" + AZURE_OPENAI_KEY, + "langchain4j.azure-open-ai.image-model.endpoint=" + AZURE_OPENAI_ENDPOINT, + "langchain4j.azure-open-ai.image-model.deployment-name=" + "dall-e-3" ) .run(context -> { From 79f38bed822cabc4f8f302c0a73bc71717a17af1 Mon Sep 17 00:00:00 2001 From: LangChain4j Date: Thu, 2 May 2024 18:32:58 +0200 Subject: [PATCH 48/49] fixed "Duration.ofSeconds(0) by default" --- .../java/dev/langchain4j/azure/openai/spring/AutoConfig.java | 2 +- .../langchain4j/azure/openai/spring/ImageModelProperties.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java index a1f3329..ac0c7f0 100644 --- a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/AutoConfig.java @@ -139,7 +139,7 @@ AzureOpenAiImageModel openAiImageModel(Properties properties) { .style(imageModelProperties.getStyle()) .user(imageModelProperties.getUser()) .responseFormat(imageModelProperties.getResponseFormat()) - .timeout(Duration.ofSeconds(imageModelProperties.getTimeout())) + .timeout(imageModelProperties.getTimeout() == null ? null : Duration.ofSeconds(imageModelProperties.getTimeout())) .maxRetries(imageModelProperties.getMaxRetries()) .proxyOptions(ProxyOptions.fromConfiguration(Configuration.getGlobalConfiguration())) .logRequestsAndResponses(imageModelProperties.getLogRequestsAndResponses() != null && imageModelProperties.getLogRequestsAndResponses()); diff --git a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java index 5613080..215cd64 100644 --- a/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java +++ b/langchain4j-azure-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/azure/openai/spring/ImageModelProperties.java @@ -16,7 +16,7 @@ class ImageModelProperties { String style; String responseFormat; String user; - int timeout; + Integer timeout; Integer maxRetries; Boolean logRequestsAndResponses; } \ No newline at end of file From 489aa419f0dedfabec5360ec3b48834523761b25 Mon Sep 17 00:00:00 2001 From: LangChain4j Date: Thu, 2 May 2024 18:38:01 +0200 Subject: [PATCH 49/49] fixed versions --- langchain4j-azure-ai-search-spring-boot-starter/pom.xml | 4 ++-- langchain4j-azure-open-ai-spring-boot-starter/pom.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/langchain4j-azure-ai-search-spring-boot-starter/pom.xml b/langchain4j-azure-ai-search-spring-boot-starter/pom.xml index d0e04f5..4349a86 100644 --- a/langchain4j-azure-ai-search-spring-boot-starter/pom.xml +++ b/langchain4j-azure-ai-search-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ dev.langchain4j langchain4j-spring - 0.29.0 + 0.31.0-SNAPSHOT ../pom.xml @@ -57,7 +57,7 @@ dev.langchain4j langchain4j-embeddings-all-minilm-l6-v2 - 0.29.0 + ${project.version} test diff --git a/langchain4j-azure-open-ai-spring-boot-starter/pom.xml b/langchain4j-azure-open-ai-spring-boot-starter/pom.xml index 3c7d83e..72bb78e 100644 --- a/langchain4j-azure-open-ai-spring-boot-starter/pom.xml +++ b/langchain4j-azure-open-ai-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ dev.langchain4j langchain4j-spring - 0.29.0-SNAPSHOT + 0.31.0-SNAPSHOT ../pom.xml