Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Azure OpenAI and AI Search #8

Merged
merged 53 commits into from
May 2, 2024
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
d5d21bf
Support Azure OpenAI
Feb 18, 2024
1d04edb
Merge branch 'langchain4j:main' into main
showpune Feb 20, 2024
bba8850
Update langchain4j-azure-open-ai-spring-boot-starter/pom.xml
showpune Mar 15, 2024
2b81671
Update langchain4j-azure-open-ai-spring-boot-starter/src/test/java/de…
showpune Mar 15, 2024
9d01db0
Update langchain4j-azure-open-ai-spring-boot-starter/src/test/java/de…
showpune Mar 15, 2024
2f0053a
Update langchain4j-azure-open-ai-spring-boot-starter/src/test/java/de…
showpune Mar 15, 2024
e0de25c
remove the azure core lib
Mar 15, 2024
a423557
Add Azure AI Search support
Mar 15, 2024
436f505
Format the code
Mar 15, 2024
546b0f1
use latest ai search
Mar 20, 2024
8e3be8c
decouple as different resource
Mar 22, 2024
48dcf22
decouple as different resource
Mar 26, 2024
5e5fa49
Merge branch 'langchain4j:main' into main
showpune Mar 26, 2024
26da799
Merge remote-tracking branch 'origin/azure-resource'
Mar 26, 2024
ed5be1b
Revert "bumped to 0.29.0-SNAPSHOT"
Mar 26, 2024
165d27e
rollback the distributionManagement
Mar 26, 2024
bbe199d
Reapply "bumped to 0.29.0-SNAPSHOT"
Mar 26, 2024
f8c6eae
Add Default value support
Mar 26, 2024
99581d0
Rollback the other components
Mar 26, 2024
8552bb7
Support Azure OpenAI
Feb 18, 2024
7f288ea
Update langchain4j-azure-open-ai-spring-boot-starter/pom.xml
showpune Mar 15, 2024
501aadf
Update langchain4j-azure-open-ai-spring-boot-starter/src/test/java/de…
showpune Mar 15, 2024
141634e
Update langchain4j-azure-open-ai-spring-boot-starter/src/test/java/de…
showpune Mar 15, 2024
46d64e8
Update langchain4j-azure-open-ai-spring-boot-starter/src/test/java/de…
showpune Mar 15, 2024
877cf22
remove the azure core lib
Mar 15, 2024
615f561
Add Azure AI Search support
Mar 15, 2024
3177711
Format the code
Mar 15, 2024
f8dc867
use latest ai search
Mar 20, 2024
615a2f9
decouple as different resource
Mar 22, 2024
4078e31
decouple as different resource
Mar 26, 2024
16864e1
Revert "bumped to 0.29.0-SNAPSHOT"
Mar 26, 2024
6296d25
rollback the distributionManagement
Mar 26, 2024
ec6edbc
Reapply "bumped to 0.29.0-SNAPSHOT"
Mar 26, 2024
bf227f2
Add Default value support
Mar 26, 2024
9c475aa
Rollback the other components
Mar 26, 2024
6ce6b67
Merge remote-tracking branch 'origin/main'
Mar 26, 2024
7b9364e
Rollback the other components
Mar 26, 2024
de2978c
Rollback the other components
Mar 26, 2024
118a429
Add Non Azure Support
Mar 27, 2024
43fc526
NonAzureKey not depends on deployment
Mar 28, 2024
f0c5dea
Update langchain4j-azure-aisearch-spring-boot-starter/src/main/java/d…
showpune Mar 29, 2024
0ad06f0
Update langchain4j-azure-openai-spring-boot-starter/pom.xml
showpune Mar 29, 2024
a62be40
Update pom.xml
showpune Mar 29, 2024
08cb971
Update pom.xml
showpune Mar 29, 2024
0e2b24d
Update langchain4j-azure-aisearch-spring-boot-starter/pom.xml
showpune Mar 29, 2024
7dc5bfd
Update langchain4j-azure-aisearch-spring-boot-starter/pom.xml
showpune Mar 29, 2024
019b56d
Update langchain4j-azure-aisearch-spring-boot-starter/pom.xml
showpune Mar 29, 2024
a72d00a
Fix the review problems
Mar 29, 2024
f7873ca
Add function test for retriever and store
Apr 15, 2024
13ab9bb
Update the test case
Apr 16, 2024
cb11013
cosmetics
langchain4j May 2, 2024
79f38be
fixed "Duration.ofSeconds(0) by default"
langchain4j May 2, 2024
489aa41
fixed versions
langchain4j May 2, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions langchain4j-azure-spring-boot-starter/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-spring</artifactId>
<version>0.29.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

<artifactId>langchain4j-azure-spring-boot-starter</artifactId>
<name>LangChain4j Spring Boot starter for Azure</name>
<packaging>jar</packaging>

<dependencies>

<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-azure-open-ai</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-azure-ai-search</artifactId>
showpune marked this conversation as resolved.
Show resolved Hide resolved
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure-processor</artifactId>
<optional>true</optional>
</dependency>

<!-- should be listed before spring-boot-configuration-processor -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>

<!-- needed to generate automatic metadata about available config properties -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

</dependencies>

<licenses>
<license>
<name>Apache-2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
<comments>A business-friendly OSS license</comments>
</license>
</licenses>

</project>
Original file line number Diff line number Diff line change
@@ -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();
}
}
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package dev.langchain4j.azure.openai.spring;

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;
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();
}
}
Original file line number Diff line number Diff line change
@@ -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<String> stop;
Integer maxTokens;
Double presencePenalty;
Double frequencyPenalty;
Map<String, Integer> logitBias;
String responseFormat;
Integer seed;
String user;
Duration timeout;
Integer maxRetries;
Boolean logRequestsAndResponses;
}
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
dev.langchain4j.azure.openai.spring.AutoConfig,\
dev.langchain4j.azure.aisearch.spring.AutoConfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dev.langchain4j.azure.openai.spring.AutoConfig
dev.langchain4j.azure.aisearch.spring.AutoConfig
Original file line number Diff line number Diff line change
@@ -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<TextSegment> azureAiSearchEmbeddingStore = context.getBean(AzureAiSearchEmbeddingStore.class);
assertThat(azureAiSearchEmbeddingStore).isInstanceOf(AzureAiSearchEmbeddingStore.class);

assertThat(context.getBean(AzureAiSearchEmbeddingStore.class)).isSameAs(azureAiSearchEmbeddingStore);
});
}

}
Loading