From fdb30dc25f3d5bccf7f4bf5087760baf80ee3edd Mon Sep 17 00:00:00 2001 From: ymqu823 Date: Sun, 1 Dec 2024 13:09:03 +0000 Subject: [PATCH] Add Chroma Spring Boot Starter --- .../pom.xml | 100 ++++++++++++++++++ ...ChromaEmbeddingStoreAutoConfiguration.java | 29 +++++ .../ChromaEmbeddingStoreProperties.java | 24 +++++ ...ot.autoconfigure.AutoConfiguration.imports | 1 + ...romaEmbeddingStoreAutoConfigurationIT.java | 55 ++++++++++ 5 files changed, 209 insertions(+) create mode 100644 langchain4j-chroma-spring-boot-starter/pom.xml create mode 100644 langchain4j-chroma-spring-boot-starter/src/main/java/dev/langchain4j/store/embedding/chroma/spring/ChromaEmbeddingStoreAutoConfiguration.java create mode 100644 langchain4j-chroma-spring-boot-starter/src/main/java/dev/langchain4j/store/embedding/chroma/spring/ChromaEmbeddingStoreProperties.java create mode 100644 langchain4j-chroma-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 langchain4j-chroma-spring-boot-starter/src/test/java/ChromaEmbeddingStoreAutoConfigurationIT.java diff --git a/langchain4j-chroma-spring-boot-starter/pom.xml b/langchain4j-chroma-spring-boot-starter/pom.xml new file mode 100644 index 00000000..dce95073 --- /dev/null +++ b/langchain4j-chroma-spring-boot-starter/pom.xml @@ -0,0 +1,100 @@ + + + + central + Maven Central Repository + https://repo.maven.apache.org/maven2 + + true + + + false + + + + 4.0.0 + + dev.langchain4j + langchain4j-spring + 0.37.0-SNAPSHOT + ../pom.xml + + langchain4j-chroma-spring-boot-starter + LangChain4j Spring Boot starter for Chroma + jar + + + + + dev.langchain4j + langchain4j-chroma + + + + 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 + + + + dev.langchain4j + langchain4j-embeddings-all-minilm-l6-v2-q + test + + + + dev.langchain4j + langchain4j-spring-boot-tests + ${project.version} + tests + test-jar + test + + + + org.testcontainers + testcontainers + 1.18.3 + test + + + + org.tinylog + tinylog-impl + test + + + + org.tinylog + slf4j-tinylog + test + + + \ No newline at end of file diff --git a/langchain4j-chroma-spring-boot-starter/src/main/java/dev/langchain4j/store/embedding/chroma/spring/ChromaEmbeddingStoreAutoConfiguration.java b/langchain4j-chroma-spring-boot-starter/src/main/java/dev/langchain4j/store/embedding/chroma/spring/ChromaEmbeddingStoreAutoConfiguration.java new file mode 100644 index 00000000..08fe9862 --- /dev/null +++ b/langchain4j-chroma-spring-boot-starter/src/main/java/dev/langchain4j/store/embedding/chroma/spring/ChromaEmbeddingStoreAutoConfiguration.java @@ -0,0 +1,29 @@ +package dev.langchain4j.store.embedding.chroma.spring; + +import dev.langchain4j.store.embedding.chroma.ChromaEmbeddingStore; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import java.util.Optional; +import java.time.Duration; +import static dev.langchain4j.store.embedding.chroma.spring.ChromaEmbeddingStoreProperties.*; + +@AutoConfiguration +@ConditionalOnProperty(prefix = "langchain4j.chroma", name = "enabled", havingValue = "true", matchIfMissing = true) +public class ChromaEmbeddingStoreAutoConfiguration { + + public ChromaEmbeddingStore chromaEmbeddingStore(ChromaEmbeddingStoreProperties properties) { + String baseUrl = Optional.ofNullable(properties.getBaseUrl()).orElse(DEFAULT_BASE_URL); + String collectionName = Optional.ofNullable(properties.getCollectionName()).orElse(DEFAULT_COLLECTION_NAME); + Duration timeout = Optional.ofNullable(properties.getTimeout()).orElse(DEFAULT_TIMEOUT); + + return ChromaEmbeddingStore.builder() + .baseUrl(baseUrl) + .collectionName(collectionName) + .timeout(timeout) + .logRequests(properties.getLogRequests()) + .logResponses(properties.getLogResponses()) + .build(); + } +} \ No newline at end of file diff --git a/langchain4j-chroma-spring-boot-starter/src/main/java/dev/langchain4j/store/embedding/chroma/spring/ChromaEmbeddingStoreProperties.java b/langchain4j-chroma-spring-boot-starter/src/main/java/dev/langchain4j/store/embedding/chroma/spring/ChromaEmbeddingStoreProperties.java new file mode 100644 index 00000000..332d20d7 --- /dev/null +++ b/langchain4j-chroma-spring-boot-starter/src/main/java/dev/langchain4j/store/embedding/chroma/spring/ChromaEmbeddingStoreProperties.java @@ -0,0 +1,24 @@ +package dev.langchain4j.store.embedding.chroma.spring; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; + +import java.time.Duration; + +@Getter +@Setter +@ConfigurationProperties(prefix = ChromaEmbeddingStoreProperties.PREFIX) +public class ChromaEmbeddingStoreProperties { + + static final String PREFIX = "langchain4j.chroma"; + static final String DEFAULT_BASE_URL = "http://localhost:8000"; + static final String DEFAULT_COLLECTION_NAME = "default"; + static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(5); + + private String baseUrl; + private String collectionName; + private Duration timeout; + private Boolean logRequests; + private Boolean logResponses; +} \ No newline at end of file diff --git a/langchain4j-chroma-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/langchain4j-chroma-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..78e5271f --- /dev/null +++ b/langchain4j-chroma-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +dev.langchain4j.store.embedding.chroma.spring.ChromaEmbeddingStoreAutoConfiguration \ No newline at end of file diff --git a/langchain4j-chroma-spring-boot-starter/src/test/java/ChromaEmbeddingStoreAutoConfigurationIT.java b/langchain4j-chroma-spring-boot-starter/src/test/java/ChromaEmbeddingStoreAutoConfigurationIT.java new file mode 100644 index 00000000..b36f657f --- /dev/null +++ b/langchain4j-chroma-spring-boot-starter/src/test/java/ChromaEmbeddingStoreAutoConfigurationIT.java @@ -0,0 +1,55 @@ +package dev.langchain4j.store.embedding.chroma.spring; + +import dev.langchain4j.data.segment.TextSegment; +import dev.langchain4j.store.embedding.EmbeddingStore; +import dev.langchain4j.store.embedding.chroma.ChromaEmbeddingStore; +import dev.langchain4j.store.embedding.spring.EmbeddingStoreAutoConfigurationIT; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; + +class ChromaEmbeddingStoreAutoConfigurationIT extends EmbeddingStoreAutoConfigurationIT { + + // Define a Testcontainers instance for Chroma + static GenericContainer chromaContainer = new GenericContainer<>("chroma-core:latest") + .withExposedPorts(8000) // Chroma typically runs on port 8000 + .waitingFor(Wait.forHttp("/").forStatusCode(200)); // Wait until Chroma service is ready + + @BeforeAll + static void beforeAll() { + chromaContainer.start(); + } + + @AfterAll + static void afterAll() { + chromaContainer.stop(); + } + + @Override + protected Class autoConfigurationClass() { + return ChromaEmbeddingStoreAutoConfiguration.class; + } + + @Override + protected Class> embeddingStoreClass() { + return ChromaEmbeddingStore.class; + } + + @Override + protected String[] properties() { + return new String[]{ + "langchain4j.chroma.base-url=http://" + chromaContainer.getHost() + ":" + chromaContainer.getMappedPort(8000), + "langchain4j.chroma.collection-name=test-collection", + "langchain4j.chroma.timeout=5s", + "langchain4j.chroma.log-requests=true", + "langchain4j.chroma.log-responses=false" + }; + } + + @Override + protected String dimensionPropertyKey() { + // Chroma doesn't require a dimension property; return null or a placeholder key if needed + return "langchain4j.chroma.dimension"; + } +} \ No newline at end of file