diff --git a/astradb-examples/pom.xml b/astradb-examples/pom.xml
new file mode 100644
index 00000000..aeec3383
--- /dev/null
+++ b/astradb-examples/pom.xml
@@ -0,0 +1,63 @@
+
+ 4.0.0
+
+ dev.langchain4j
+ langchain4j-examples
+ 0.30.0
+
+
+ astradb-examples
+ jar
+ astradb-examples
+
+
+ 11
+ 11
+ UTF-8
+ 0.29.1
+
+
+
+
+
+ dev.langchain4j
+ langchain4j
+ ${langchain.version}
+ test
+
+
+ dev.langchain4j
+ langchain4j-core
+ ${langchain.version}
+ test
+
+
+ dev.langchain4j
+ langchain4j-astradb
+ ${langchain.version}
+ test
+
+
+
+ ch.qos.logback
+ logback-classic
+ 1.5.3
+ test
+
+
+
+ dev.langchain4j
+ langchain4j-open-ai
+ ${langchain.version}
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ 5.10.2
+ test
+
+
+
+
diff --git a/astradb-examples/src/test/java/AstraDbAssistant.java b/astradb-examples/src/test/java/AstraDbAssistant.java
new file mode 100644
index 00000000..345c330a
--- /dev/null
+++ b/astradb-examples/src/test/java/AstraDbAssistant.java
@@ -0,0 +1,3 @@
+interface AstraDbAssistant {
+ String answer(String query);
+}
diff --git a/astradb-examples/src/test/java/AstraDbNaiveRagTestIT.java b/astradb-examples/src/test/java/AstraDbNaiveRagTestIT.java
new file mode 100644
index 00000000..d34a3f82
--- /dev/null
+++ b/astradb-examples/src/test/java/AstraDbNaiveRagTestIT.java
@@ -0,0 +1,113 @@
+import com.datastax.astra.client.DataAPIClient;
+import dev.langchain4j.data.document.parser.TextDocumentParser;
+import dev.langchain4j.data.segment.TextSegment;
+import dev.langchain4j.memory.chat.MessageWindowChatMemory;
+import dev.langchain4j.model.chat.ChatLanguageModel;
+import dev.langchain4j.model.embedding.EmbeddingModel;
+import dev.langchain4j.model.openai.OpenAiChatModel;
+import dev.langchain4j.model.openai.OpenAiEmbeddingModel;
+import dev.langchain4j.model.openai.OpenAiTokenizer;
+import dev.langchain4j.rag.content.retriever.ContentRetriever;
+import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever;
+import dev.langchain4j.service.AiServices;
+import dev.langchain4j.store.embedding.EmbeddingStore;
+import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
+import dev.langchain4j.store.embedding.astradb.AstraDbEmbeddingStore;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.util.Objects;
+
+import static com.datastax.astra.client.model.SimilarityMetric.COSINE;
+import static com.dtsx.astra.sdk.utils.TestUtils.getAstraToken;
+import static dev.langchain4j.data.document.loader.FileSystemDocumentLoader.loadDocument;
+import static dev.langchain4j.data.document.splitter.DocumentSplitters.recursive;
+import static dev.langchain4j.model.openai.OpenAiChatModelName.GPT_3_5_TURBO;
+import static dev.langchain4j.model.openai.OpenAiEmbeddingModelName.TEXT_EMBEDDING_ADA_002;
+import static java.time.Duration.ofSeconds;
+
+@Disabled("AstraDB is not available in the CI")
+class AstraDbNaiveRagTestIT {
+
+ static final String VAR_OPENAI_API_KEY = "OPENAI_API_KEY";
+ static final String VAR_ASTRA_TOKEN = "ASTRA_DB_APPLICATION_TOKEN";
+
+ @Test
+ @EnabledIfEnvironmentVariable(named = VAR_ASTRA_TOKEN, matches = "Astra.*")
+ @EnabledIfEnvironmentVariable(named = VAR_OPENAI_API_KEY, matches = "sk.*")
+ void shouldNaiveRagWithOpenAiAndAstraDbTest() {
+
+ // Parsing input file
+ Path textFile = new File(Objects.requireNonNull(getClass()
+ .getResource("/story-about-happy-carrot.txt"))
+ .getFile())
+ .toPath();
+
+ // === INGESTION ===
+
+ EmbeddingModel embeddingModel = initEmbeddingModelOpenAi();
+ EmbeddingStore embeddingStore = initEmbeddingStoreAstraDb();
+ EmbeddingStoreIngestor.builder()
+ .documentSplitter(recursive(100, 10, new OpenAiTokenizer(GPT_3_5_TURBO)))
+ .embeddingModel(embeddingModel)
+ .embeddingStore(embeddingStore)
+ .build()
+ .ingest(loadDocument(textFile, new TextDocumentParser()));
+
+ // === NAIVE RETRIEVER ===
+
+ ContentRetriever contentRetriever = EmbeddingStoreContentRetriever.builder()
+ .embeddingStore(embeddingStore)
+ .embeddingModel(embeddingModel)
+ .maxResults(2)
+ .minScore(0.5)
+ .build();
+
+ AstraDbAssistant ai = AiServices.builder(AstraDbAssistant.class)
+ .contentRetriever(contentRetriever)
+ .chatLanguageModel(initChatLanguageModelOpenAi())
+ .chatMemory(MessageWindowChatMemory.withMaxMessages(10))
+ .build();
+
+ String response = ai.answer("What vegetable is Happy?");
+ Assertions.assertNotNull(response);
+ }
+
+ private ChatLanguageModel initChatLanguageModelOpenAi() {
+ return OpenAiChatModel.builder()
+ .apiKey(System.getenv(VAR_OPENAI_API_KEY))
+ .modelName(GPT_3_5_TURBO)
+ .temperature(0.7)
+ .timeout(ofSeconds(15))
+ .maxRetries(3)
+ .logResponses(true)
+ .logRequests(true)
+ .build();
+ }
+
+ private EmbeddingModel initEmbeddingModelOpenAi() {
+ return OpenAiEmbeddingModel.builder()
+ .apiKey(System.getenv(VAR_OPENAI_API_KEY))
+ .modelName(TEXT_EMBEDDING_ADA_002)
+ .build();
+ }
+
+ private EmbeddingStore initEmbeddingStoreAstraDb() {
+ return new AstraDbEmbeddingStore(
+ // Astra Db Client
+ new DataAPIClient(getAstraToken())
+ // Access the 'admin' part
+ .getAdmin()
+ // To create a database if it does not exist
+ .createDatabase("test_langchain4j")
+ // Select the created db
+ .getDatabase()
+ // And create a collection if it does not exist
+ .createCollection("story_collection", 1536, COSINE));
+ }
+
+}
\ No newline at end of file
diff --git a/astradb-examples/src/test/resources/logback-test.xml b/astradb-examples/src/test/resources/logback-test.xml
new file mode 100644
index 00000000..b176835f
--- /dev/null
+++ b/astradb-examples/src/test/resources/logback-test.xml
@@ -0,0 +1,17 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} %magenta(%-5level) %cyan(%-20logger) : %msg%n
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/astradb-examples/src/test/resources/story-about-happy-carrot.txt b/astradb-examples/src/test/resources/story-about-happy-carrot.txt
new file mode 100644
index 00000000..66ae976d
--- /dev/null
+++ b/astradb-examples/src/test/resources/story-about-happy-carrot.txt
@@ -0,0 +1,28 @@
+Once upon a time in the town of VeggieVille, there lived a cheerful carrot named Charlie.
+Charlie was a radiant carrot, always beaming with joy and positivity.
+His vibrant orange skin and lush green top were a sight to behold, but it was his infectious laughter and warm personality that really set him apart.
+
+Charlie had a diverse group of friends, each a vegetable with their own unique characteristics.
+There was Bella the blushing beetroot, always ready with a riddle or two; Timmy the timid tomato, a gentle soul with a heart of gold; and Percy the prankster potato, whose jokes always brought a smile to everyone's faces.
+Despite their differences, they shared a close bond, their friendship as robust as their natural goodness.
+
+Their lives were filled with delightful adventures, from playing hide-and-seek amidst the leafy lettuce to swimming in the dewy droplets that pooled on the cabbage leaves.
+Their favorite place, though, was the sunlit corner of the vegetable patch, where they would bask in the warmth of the sun, share stories, and have hearty laughs.
+
+One day, a bunch of pesky caterpillars invaded VeggieVille.
+The vegetables were terrified, fearing they would be nibbled to nothingness.
+But Charlie, with his usual sunny disposition, had an idea.
+He proposed they host a grand feast for the caterpillars, with the juiciest leaves from the outskirts of the town.
+Charlie's optimism was contagious, and his friends eagerly joined in to prepare the feast.
+
+When the caterpillars arrived, they were pleasantly surprised.
+They enjoyed the feast and were so impressed with the vegetables' hospitality that they promised not to trouble VeggieVille again.
+In return, they agreed to help pollinate the flowers, contributing to a more lush and vibrant VeggieVille.
+
+Charlie's idea had saved the day, but he humbly attributed the success to their teamwork and friendship.
+They celebrated their victory with a grand party, filled with laughter, dance, and merry games.
+That night, under the twinkling stars, they made a pact to always stand by each other, come what may.
+
+From then on, the story of the happy carrot and his friends spread far and wide, a tale of friendship, unity, and positivity.
+Charlie, Bella, Timmy, and Percy continued to live their joyful lives, their laughter echoing through VeggieVille.
+And so, the tale of the happy carrot and his friends serves as a reminder that no matter the challenge, with optimism, teamwork, and a bit of creativity, anything is possible.
\ No newline at end of file
diff --git a/cassandra-examples/pom.xml b/cassandra-examples/pom.xml
new file mode 100644
index 00000000..b2573265
--- /dev/null
+++ b/cassandra-examples/pom.xml
@@ -0,0 +1,80 @@
+
+
+ 4.0.0
+ cassandra-example
+
+
+ dev.langchain4j
+ langchain4j-examples
+ 0.30.0
+
+
+
+
+ 11
+ 11
+ UTF-8
+ 0.29.1
+ 1.19.7
+
+
+
+
+
+ dev.langchain4j
+ langchain4j-cassandra
+ ${langchain.version}
+
+
+
+ dev.langchain4j
+ langchain4j
+ ${langchain.version}
+ test
+
+
+
+ dev.langchain4j
+ langchain4j-core
+ ${langchain.version}
+ test
+
+
+
+ ch.qos.logback
+ logback-classic
+ 1.5.3
+ test
+
+
+
+ dev.langchain4j
+ langchain4j-open-ai
+ ${langchain.version}
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ 5.10.2
+ test
+
+
+
+ org.testcontainers
+ cassandra
+ ${testcontainers.version}
+ test
+
+
+ org.testcontainers
+ junit-jupiter
+ ${testcontainers.version}
+ test
+
+
+
+
+
\ No newline at end of file
diff --git a/cassandra-examples/src/test/java/CassandraAssistant.java b/cassandra-examples/src/test/java/CassandraAssistant.java
new file mode 100644
index 00000000..b6a7185a
--- /dev/null
+++ b/cassandra-examples/src/test/java/CassandraAssistant.java
@@ -0,0 +1,3 @@
+interface CassandraAssistant {
+ String answer(String query);
+}
diff --git a/cassandra-examples/src/test/java/CassandraNaiveRagTestIT.java b/cassandra-examples/src/test/java/CassandraNaiveRagTestIT.java
new file mode 100644
index 00000000..280318a8
--- /dev/null
+++ b/cassandra-examples/src/test/java/CassandraNaiveRagTestIT.java
@@ -0,0 +1,154 @@
+
+import com.datastax.oss.driver.api.core.CqlSession;
+import dev.langchain4j.data.document.parser.TextDocumentParser;
+import dev.langchain4j.data.segment.TextSegment;
+import dev.langchain4j.memory.chat.MessageWindowChatMemory;
+import dev.langchain4j.model.chat.ChatLanguageModel;
+import dev.langchain4j.model.embedding.EmbeddingModel;
+import dev.langchain4j.model.openai.OpenAiChatModel;
+import dev.langchain4j.model.openai.OpenAiEmbeddingModel;
+import dev.langchain4j.model.openai.OpenAiTokenizer;
+import dev.langchain4j.rag.content.retriever.ContentRetriever;
+import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever;
+import dev.langchain4j.service.AiServices;
+import dev.langchain4j.store.cassio.SimilarityMetric;
+import dev.langchain4j.store.embedding.EmbeddingStore;
+import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
+import dev.langchain4j.store.embedding.cassandra.CassandraCassioEmbeddingStore;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
+import org.testcontainers.DockerClientFactory;
+import org.testcontainers.containers.CassandraContainer;
+import org.testcontainers.junit.jupiter.Testcontainers;
+import org.testcontainers.utility.DockerImageName;
+
+import java.io.File;
+import java.net.InetSocketAddress;
+import java.nio.file.Path;
+import java.util.Collections;
+import java.util.Objects;
+
+import static dev.langchain4j.data.document.loader.FileSystemDocumentLoader.loadDocument;
+import static dev.langchain4j.data.document.splitter.DocumentSplitters.recursive;
+import static dev.langchain4j.model.openai.OpenAiChatModelName.GPT_3_5_TURBO;
+import static dev.langchain4j.model.openai.OpenAiEmbeddingModelName.TEXT_EMBEDDING_ADA_002;
+import static java.time.Duration.ofSeconds;
+
+@Testcontainers
+class CassandraNaiveRagTestIT {
+
+ static final String VAR_OPENAI_API_KEY = "OPENAI_API_KEY";
+
+ static final String CASSANDRA_IMAGE = "cassandra:5.0";
+ static final String DATACENTER = "datacenter1";
+ static final String CLUSTER = "langchain4j";
+ static final String VECTOR_STORE = "test_langchain4j";
+
+ static CassandraContainer> cassandraContainer;
+
+ /**
+ * Check Docker is installed and running on host
+ */
+ @BeforeAll
+ static void ensureDockerIsRunning() {
+ DockerClientFactory.instance().client();
+ if (cassandraContainer == null) {
+ cassandraContainer = new CassandraContainer<>(
+ DockerImageName.parse(CASSANDRA_IMAGE))
+ .withEnv("CLUSTER_NAME", CLUSTER)
+ .withEnv("DC", DATACENTER);
+ cassandraContainer.start();
+
+ // Part of Database Creation, creating keyspace
+ final InetSocketAddress contactPoint = cassandraContainer.getContactPoint();
+ CqlSession.builder()
+ .addContactPoint(contactPoint)
+ .withLocalDatacenter(DATACENTER)
+ .build().execute(
+ "CREATE KEYSPACE IF NOT EXISTS " + CLUSTER +
+ " WITH replication = {'class':'SimpleStrategy', 'replication_factor':'1'};");
+ }
+ }
+
+ /**
+ * Stop Cassandra Node
+ */
+ @AfterAll
+ static void afterTests() throws Exception {
+ cassandraContainer.stop();
+ }
+
+ @Test
+ @EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = "sk.*")
+ void shouldRagWithOpenAiAndAstra() {
+ // Parsing input file
+ Path textFile = new File(Objects.requireNonNull(getClass()
+ .getResource("/story-about-happy-carrot.txt"))
+ .getFile())
+ .toPath();
+
+ // === INGESTION ===
+
+ EmbeddingModel embeddingModel = initEmbeddingModelOpenAi();
+ EmbeddingStore embeddingStore = initEmbeddingStoreCassandra();
+ EmbeddingStoreIngestor.builder()
+ .documentSplitter(recursive(100, 10, new OpenAiTokenizer(GPT_3_5_TURBO)))
+ .embeddingModel(embeddingModel)
+ .embeddingStore(embeddingStore)
+ .build()
+ .ingest(loadDocument(textFile, new TextDocumentParser()));
+
+ // === NAIVE RETRIEVER ===
+
+ ContentRetriever contentRetriever = EmbeddingStoreContentRetriever.builder()
+ .embeddingStore(embeddingStore)
+ .embeddingModel(embeddingModel)
+ .maxResults(2)
+ .minScore(0.5)
+ .build();
+
+ CassandraAssistant ai = AiServices.builder(CassandraAssistant.class)
+ .contentRetriever(contentRetriever)
+ .chatLanguageModel(initChatLanguageModelOpenAi())
+ .chatMemory(MessageWindowChatMemory.withMaxMessages(10))
+ .build();
+
+ String response = ai.answer("What vegetable is Happy?");
+ Assertions.assertNotNull(response);
+
+ }
+
+ private EmbeddingStore initEmbeddingStoreCassandra() {
+ return CassandraCassioEmbeddingStore.builder()
+ .contactPoints(Collections.singletonList(cassandraContainer.getContactPoint().getHostName()))
+ .port(cassandraContainer.getContactPoint().getPort())
+ .localDataCenter(DATACENTER)
+ .keyspace(CLUSTER)
+ .table(VECTOR_STORE)
+ .dimension(1536)
+ .metric(SimilarityMetric.COSINE)
+ .build();
+ }
+
+ private ChatLanguageModel initChatLanguageModelOpenAi() {
+ return OpenAiChatModel.builder()
+ .apiKey(System.getenv(VAR_OPENAI_API_KEY))
+ .modelName(GPT_3_5_TURBO)
+ .temperature(0.7)
+ .timeout(ofSeconds(15))
+ .maxRetries(3)
+ .logResponses(true)
+ .logRequests(true)
+ .build();
+ }
+
+ private EmbeddingModel initEmbeddingModelOpenAi() {
+ return OpenAiEmbeddingModel.builder()
+ .apiKey(System.getenv(VAR_OPENAI_API_KEY))
+ .modelName(TEXT_EMBEDDING_ADA_002)
+ .build();
+ }
+}
\ No newline at end of file
diff --git a/cassandra-examples/src/test/resources/logback-test.xml b/cassandra-examples/src/test/resources/logback-test.xml
new file mode 100644
index 00000000..73314a62
--- /dev/null
+++ b/cassandra-examples/src/test/resources/logback-test.xml
@@ -0,0 +1,32 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} %magenta(%-5level) %cyan(%-47logger) : %msg%n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/cassandra-examples/src/test/resources/story-about-happy-carrot.txt b/cassandra-examples/src/test/resources/story-about-happy-carrot.txt
new file mode 100644
index 00000000..66ae976d
--- /dev/null
+++ b/cassandra-examples/src/test/resources/story-about-happy-carrot.txt
@@ -0,0 +1,28 @@
+Once upon a time in the town of VeggieVille, there lived a cheerful carrot named Charlie.
+Charlie was a radiant carrot, always beaming with joy and positivity.
+His vibrant orange skin and lush green top were a sight to behold, but it was his infectious laughter and warm personality that really set him apart.
+
+Charlie had a diverse group of friends, each a vegetable with their own unique characteristics.
+There was Bella the blushing beetroot, always ready with a riddle or two; Timmy the timid tomato, a gentle soul with a heart of gold; and Percy the prankster potato, whose jokes always brought a smile to everyone's faces.
+Despite their differences, they shared a close bond, their friendship as robust as their natural goodness.
+
+Their lives were filled with delightful adventures, from playing hide-and-seek amidst the leafy lettuce to swimming in the dewy droplets that pooled on the cabbage leaves.
+Their favorite place, though, was the sunlit corner of the vegetable patch, where they would bask in the warmth of the sun, share stories, and have hearty laughs.
+
+One day, a bunch of pesky caterpillars invaded VeggieVille.
+The vegetables were terrified, fearing they would be nibbled to nothingness.
+But Charlie, with his usual sunny disposition, had an idea.
+He proposed they host a grand feast for the caterpillars, with the juiciest leaves from the outskirts of the town.
+Charlie's optimism was contagious, and his friends eagerly joined in to prepare the feast.
+
+When the caterpillars arrived, they were pleasantly surprised.
+They enjoyed the feast and were so impressed with the vegetables' hospitality that they promised not to trouble VeggieVille again.
+In return, they agreed to help pollinate the flowers, contributing to a more lush and vibrant VeggieVille.
+
+Charlie's idea had saved the day, but he humbly attributed the success to their teamwork and friendship.
+They celebrated their victory with a grand party, filled with laughter, dance, and merry games.
+That night, under the twinkling stars, they made a pact to always stand by each other, come what may.
+
+From then on, the story of the happy carrot and his friends spread far and wide, a tale of friendship, unity, and positivity.
+Charlie, Bella, Timmy, and Percy continued to live their joyful lives, their laughter echoing through VeggieVille.
+And so, the tale of the happy carrot and his friends serves as a reminder that no matter the challenge, with optimism, teamwork, and a bit of creativity, anything is possible.
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 869f13a4..c3af367a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -35,6 +35,8 @@
weaviate-example
javafx-example
quarkus-example
+ astradb-examples
+ cassandra-examples
\ No newline at end of file