diff --git a/langchain4j/pom.xml b/langchain4j/pom.xml
index 80ffdef49c7..fd3b56fe95b 100644
--- a/langchain4j/pom.xml
+++ b/langchain4j/pom.xml
@@ -13,7 +13,9 @@
langchain4j
LangChain4j
- Java implementation of LangChain: Integrate your Java application with countless AI tools and services smoothly
+ Java implementation of LangChain: Integrate your Java application with countless AI
+ tools and services smoothly
+
@@ -28,12 +30,6 @@
opennlp-tools
-
- org.projectlombok
- lombok
- provided
-
-
org.slf4j
slf4j-api
diff --git a/langchain4j/src/main/java/dev/langchain4j/chain/ConversationalChain.java b/langchain4j/src/main/java/dev/langchain4j/chain/ConversationalChain.java
index 7c35faa3965..99f11bd0ef9 100644
--- a/langchain4j/src/main/java/dev/langchain4j/chain/ConversationalChain.java
+++ b/langchain4j/src/main/java/dev/langchain4j/chain/ConversationalChain.java
@@ -5,7 +5,6 @@
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.service.AiServices;
-import lombok.Builder;
import static dev.langchain4j.data.message.UserMessage.userMessage;
import static dev.langchain4j.internal.ValidationUtils.ensureNotBlank;
@@ -22,12 +21,15 @@ public class ConversationalChain implements Chain {
private final ChatLanguageModel chatLanguageModel;
private final ChatMemory chatMemory;
- @Builder
private ConversationalChain(ChatLanguageModel chatLanguageModel, ChatMemory chatMemory) {
this.chatLanguageModel = ensureNotNull(chatLanguageModel, "chatLanguageModel");
this.chatMemory = chatMemory == null ? MessageWindowChatMemory.withMaxMessages(10) : chatMemory;
}
+ public static ConversationalChainBuilder builder() {
+ return new ConversationalChainBuilder();
+ }
+
@Override
public String execute(String userMessage) {
@@ -39,4 +41,30 @@ public String execute(String userMessage) {
return aiMessage.text();
}
+
+ public static class ConversationalChainBuilder {
+ private ChatLanguageModel chatLanguageModel;
+ private ChatMemory chatMemory;
+
+ ConversationalChainBuilder() {
+ }
+
+ public ConversationalChainBuilder chatLanguageModel(ChatLanguageModel chatLanguageModel) {
+ this.chatLanguageModel = chatLanguageModel;
+ return this;
+ }
+
+ public ConversationalChainBuilder chatMemory(ChatMemory chatMemory) {
+ this.chatMemory = chatMemory;
+ return this;
+ }
+
+ public ConversationalChain build() {
+ return new ConversationalChain(this.chatLanguageModel, this.chatMemory);
+ }
+
+ public String toString() {
+ return "ConversationalChain.ConversationalChainBuilder(chatLanguageModel=" + this.chatLanguageModel + ", chatMemory=" + this.chatMemory + ")";
+ }
+ }
}
diff --git a/langchain4j/src/main/java/dev/langchain4j/data/document/loader/FileSystemDocumentLoader.java b/langchain4j/src/main/java/dev/langchain4j/data/document/loader/FileSystemDocumentLoader.java
index 12eec27cbf9..6982e522858 100644
--- a/langchain4j/src/main/java/dev/langchain4j/data/document/loader/FileSystemDocumentLoader.java
+++ b/langchain4j/src/main/java/dev/langchain4j/data/document/loader/FileSystemDocumentLoader.java
@@ -1,7 +1,7 @@
package dev.langchain4j.data.document.loader;
-import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.BlankDocumentException;
+import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.DocumentLoader;
import dev.langchain4j.data.document.DocumentParser;
import dev.langchain4j.data.document.parser.TextDocumentParser;
diff --git a/langchain4j/src/main/java/dev/langchain4j/data/document/parser/TextDocumentParser.java b/langchain4j/src/main/java/dev/langchain4j/data/document/parser/TextDocumentParser.java
index 8184596c0c5..d4444ecfe39 100644
--- a/langchain4j/src/main/java/dev/langchain4j/data/document/parser/TextDocumentParser.java
+++ b/langchain4j/src/main/java/dev/langchain4j/data/document/parser/TextDocumentParser.java
@@ -1,14 +1,12 @@
package dev.langchain4j.data.document.parser;
-import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.BlankDocumentException;
+import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.DocumentParser;
-import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.nio.charset.Charset;
-import static dev.langchain4j.internal.Utils.isNullOrBlank;
import static dev.langchain4j.internal.ValidationUtils.ensureNotNull;
import static java.nio.charset.StandardCharsets.UTF_8;
diff --git a/langchain4j/src/main/java/dev/langchain4j/data/document/splitter/HierarchicalDocumentSplitter.java b/langchain4j/src/main/java/dev/langchain4j/data/document/splitter/HierarchicalDocumentSplitter.java
index faadf60f126..1f70fa8ef85 100644
--- a/langchain4j/src/main/java/dev/langchain4j/data/document/splitter/HierarchicalDocumentSplitter.java
+++ b/langchain4j/src/main/java/dev/langchain4j/data/document/splitter/HierarchicalDocumentSplitter.java
@@ -5,7 +5,6 @@
import dev.langchain4j.data.document.Metadata;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.Tokenizer;
-import lombok.Getter;
import java.util.ArrayList;
import java.util.Arrays;
@@ -14,7 +13,9 @@
import java.util.concurrent.atomic.AtomicInteger;
import static dev.langchain4j.internal.Utils.firstChars;
-import static dev.langchain4j.internal.ValidationUtils.*;
+import static dev.langchain4j.internal.ValidationUtils.ensureBetween;
+import static dev.langchain4j.internal.ValidationUtils.ensureGreaterThanZero;
+import static dev.langchain4j.internal.ValidationUtils.ensureNotNull;
/**
* Base class for hierarchical document splitters.
@@ -23,9 +24,14 @@
* when a single segment is too long.
*/
public abstract class HierarchicalDocumentSplitter implements DocumentSplitter {
- @Getter(lazy = true)
- private final HierarchicalDocumentSplitter overlapSentenceSplitter =
- new DocumentBySentenceSplitter(1, 0, null, null);
+ private HierarchicalDocumentSplitter overlapSentenceSplitter;
+
+ private HierarchicalDocumentSplitter getOverlapSentenceSplitter() {
+ if (overlapSentenceSplitter == null) {
+ overlapSentenceSplitter = new DocumentBySentenceSplitter(1, 0, null, null);
+ }
+ return overlapSentenceSplitter;
+ }
private static final String INDEX = "index";
diff --git a/langchain4j/src/main/java/dev/langchain4j/service/Result.java b/langchain4j/src/main/java/dev/langchain4j/service/Result.java
index f1721263412..a0efd53dd0f 100644
--- a/langchain4j/src/main/java/dev/langchain4j/service/Result.java
+++ b/langchain4j/src/main/java/dev/langchain4j/service/Result.java
@@ -1,10 +1,9 @@
package dev.langchain4j.service;
-import dev.langchain4j.service.tool.ToolExecution;
import dev.langchain4j.model.output.FinishReason;
import dev.langchain4j.model.output.TokenUsage;
import dev.langchain4j.rag.content.Content;
-import lombok.Builder;
+import dev.langchain4j.service.tool.ToolExecution;
import java.util.List;
@@ -17,7 +16,7 @@
* such as {@link TokenUsage} and sources ({@link Content}s retrieved during RAG).
*
* @param The type of the content. Can be of any return type supported by AI Services,
- * such as String, Enum, MyCustomPojo, etc.
+ * such as String, Enum, MyCustomPojo, etc.
*/
public class Result {
@@ -27,7 +26,6 @@ public class Result {
private final FinishReason finishReason;
private final List toolExecutions;
- @Builder
public Result(T content, TokenUsage tokenUsage, List sources, FinishReason finishReason, List toolExecutions) {
this.content = ensureNotNull(content, "content");
this.tokenUsage = tokenUsage;
@@ -36,6 +34,10 @@ public Result(T content, TokenUsage tokenUsage, List sources, FinishRea
this.toolExecutions = copyIfNotNull(toolExecutions);
}
+ public static ResultBuilder builder() {
+ return new ResultBuilder();
+ }
+
public T content() {
return content;
}
@@ -55,4 +57,48 @@ public FinishReason finishReason() {
public List toolExecutions() {
return toolExecutions;
}
+
+ public static class ResultBuilder {
+ private T content;
+ private TokenUsage tokenUsage;
+ private List sources;
+ private FinishReason finishReason;
+ private List toolExecutions;
+
+ ResultBuilder() {
+ }
+
+ public ResultBuilder content(T content) {
+ this.content = content;
+ return this;
+ }
+
+ public ResultBuilder tokenUsage(TokenUsage tokenUsage) {
+ this.tokenUsage = tokenUsage;
+ return this;
+ }
+
+ public ResultBuilder sources(List sources) {
+ this.sources = sources;
+ return this;
+ }
+
+ public ResultBuilder finishReason(FinishReason finishReason) {
+ this.finishReason = finishReason;
+ return this;
+ }
+
+ public ResultBuilder toolExecutions(List toolExecutions) {
+ this.toolExecutions = toolExecutions;
+ return this;
+ }
+
+ public Result build() {
+ return new Result(this.content, this.tokenUsage, this.sources, this.finishReason, this.toolExecutions);
+ }
+
+ public String toString() {
+ return "Result.ResultBuilder(content=" + this.content + ", tokenUsage=" + this.tokenUsage + ", sources=" + this.sources + ", finishReason=" + this.finishReason + ", toolExecutions=" + this.toolExecutions + ")";
+ }
+ }
}
diff --git a/langchain4j/src/main/java/dev/langchain4j/service/output/DefaultOutputParserFactory.java b/langchain4j/src/main/java/dev/langchain4j/service/output/DefaultOutputParserFactory.java
index dce02bfd622..6081582349e 100644
--- a/langchain4j/src/main/java/dev/langchain4j/service/output/DefaultOutputParserFactory.java
+++ b/langchain4j/src/main/java/dev/langchain4j/service/output/DefaultOutputParserFactory.java
@@ -5,7 +5,12 @@
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
-import java.util.*;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
class DefaultOutputParserFactory implements OutputParserFactory {
diff --git a/langchain4j/src/main/java/dev/langchain4j/store/embedding/inmemory/InMemoryEmbeddingStore.java b/langchain4j/src/main/java/dev/langchain4j/store/embedding/inmemory/InMemoryEmbeddingStore.java
index f8973c54247..79f024da20b 100644
--- a/langchain4j/src/main/java/dev/langchain4j/store/embedding/inmemory/InMemoryEmbeddingStore.java
+++ b/langchain4j/src/main/java/dev/langchain4j/store/embedding/inmemory/InMemoryEmbeddingStore.java
@@ -4,19 +4,32 @@
import dev.langchain4j.data.embedding.Embedding;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.spi.store.embedding.inmemory.InMemoryEmbeddingStoreJsonCodecFactory;
-import dev.langchain4j.store.embedding.*;
+import dev.langchain4j.store.embedding.CosineSimilarity;
+import dev.langchain4j.store.embedding.EmbeddingMatch;
+import dev.langchain4j.store.embedding.EmbeddingSearchRequest;
+import dev.langchain4j.store.embedding.EmbeddingSearchResult;
+import dev.langchain4j.store.embedding.EmbeddingStore;
+import dev.langchain4j.store.embedding.RelevanceScore;
import dev.langchain4j.store.embedding.filter.Filter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Objects;
+import java.util.PriorityQueue;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.IntStream;
import static dev.langchain4j.internal.Utils.randomUUID;
-import static dev.langchain4j.internal.ValidationUtils.*;
+import static dev.langchain4j.internal.ValidationUtils.ensureNotBlank;
+import static dev.langchain4j.internal.ValidationUtils.ensureNotEmpty;
+import static dev.langchain4j.internal.ValidationUtils.ensureNotNull;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.nio.file.StandardOpenOption.CREATE;
import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
diff --git a/langchain4j/src/test/java/dev/langchain4j/data/document/splitter/SegmentBuilderTest.java b/langchain4j/src/test/java/dev/langchain4j/data/document/splitter/SegmentBuilderTest.java
index 1b8e88f00b6..89772531d63 100644
--- a/langchain4j/src/test/java/dev/langchain4j/data/document/splitter/SegmentBuilderTest.java
+++ b/langchain4j/src/test/java/dev/langchain4j/data/document/splitter/SegmentBuilderTest.java
@@ -51,7 +51,7 @@ public void test_reset() {
builder.reset();
assertThat(builder.isNotEmpty()).isFalse();
- assertThat(builder.getSize()).isEqualTo(0);
+ assertThat(builder.getSize()).isZero();
assertThat(builder.toString()).isEqualTo("");
}
@@ -70,4 +70,4 @@ public void test_append_prepend() {
assertThat(builder.toString()).isEqualTo("Hello world");
}
}
-}
\ No newline at end of file
+}
diff --git a/langchain4j/src/test/java/dev/langchain4j/rag/query/router/LanguageModelQueryRouterIT.java b/langchain4j/src/test/java/dev/langchain4j/rag/query/router/LanguageModelQueryRouterIT.java
index db1de838118..22eeec2ea44 100644
--- a/langchain4j/src/test/java/dev/langchain4j/rag/query/router/LanguageModelQueryRouterIT.java
+++ b/langchain4j/src/test/java/dev/langchain4j/rag/query/router/LanguageModelQueryRouterIT.java
@@ -4,6 +4,7 @@
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.rag.content.retriever.ContentRetriever;
import dev.langchain4j.rag.query.Query;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
@@ -19,6 +20,7 @@
import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(MockitoExtension.class)
+@EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+")
class LanguageModelQueryRouterIT {
@Mock
diff --git a/langchain4j/src/test/java/dev/langchain4j/rag/query/transformer/CompressingQueryTransformerIT.java b/langchain4j/src/test/java/dev/langchain4j/rag/query/transformer/CompressingQueryTransformerIT.java
index 235a5a82bee..9780493486e 100644
--- a/langchain4j/src/test/java/dev/langchain4j/rag/query/transformer/CompressingQueryTransformerIT.java
+++ b/langchain4j/src/test/java/dev/langchain4j/rag/query/transformer/CompressingQueryTransformerIT.java
@@ -7,6 +7,7 @@
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.rag.query.Metadata;
import dev.langchain4j.rag.query.Query;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
@@ -18,6 +19,7 @@
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
+@EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+")
class CompressingQueryTransformerIT {
@ParameterizedTest
diff --git a/langchain4j/src/test/java/dev/langchain4j/rag/query/transformer/ExpandingQueryTransformerIT.java b/langchain4j/src/test/java/dev/langchain4j/rag/query/transformer/ExpandingQueryTransformerIT.java
index e419c6001b5..74b9bd7f941 100644
--- a/langchain4j/src/test/java/dev/langchain4j/rag/query/transformer/ExpandingQueryTransformerIT.java
+++ b/langchain4j/src/test/java/dev/langchain4j/rag/query/transformer/ExpandingQueryTransformerIT.java
@@ -3,6 +3,7 @@
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.rag.query.Query;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
@@ -12,6 +13,7 @@
import static org.assertj.core.api.Assertions.assertThat;
+@EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+")
class ExpandingQueryTransformerIT {
@ParameterizedTest
@@ -49,4 +51,4 @@ static Stream should_expand_query() {
// TODO add more models
);
}
-}
\ No newline at end of file
+}
diff --git a/langchain4j/src/test/java/dev/langchain4j/service/AiServicesIT.java b/langchain4j/src/test/java/dev/langchain4j/service/AiServicesIT.java
index 2b4a5845fd1..3a5e8dfa7a2 100644
--- a/langchain4j/src/test/java/dev/langchain4j/service/AiServicesIT.java
+++ b/langchain4j/src/test/java/dev/langchain4j/service/AiServicesIT.java
@@ -10,10 +10,9 @@
import dev.langchain4j.model.openai.OpenAiModerationModel;
import dev.langchain4j.model.output.TokenUsage;
import dev.langchain4j.model.output.structured.Description;
-import lombok.Builder;
-import lombok.ToString;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;
@@ -47,7 +46,8 @@
import static org.mockito.Mockito.verifyNoMoreInteractions;
@ExtendWith(MockitoExtension.class)
-public class AiServicesIT {
+@EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+")
+class AiServicesIT {
@Spy
ChatLanguageModel chatLanguageModel = OpenAiChatModel.builder()
@@ -358,19 +358,18 @@ void should_extract_map() {
verify(chatLanguageModel).supportedCapabilities();
}
- @ToString
- static class Address {
- private Integer streetNumber;
- private String street;
- private String city;
+ record Address(
+ Integer streetNumber,
+ String street,
+ String city
+ ) {
}
- @ToString
- static class Person {
- private String firstName;
- private String lastName;
- private LocalDate birthDate;
- private Address address;
+ static record Person(
+ String firstName,
+ String lastName,
+ LocalDate birthDate,
+ Address address) {
}
interface PersonExtractor {
@@ -463,14 +462,13 @@ void should_extract_custom_POJO_with_explicit_json_response_format() {
}
- @ToString
- static class Recipe {
+ static record Recipe(
- private String title;
- private String description;
- @Description("each step should be described in 4 words, steps should rhyme")
- private String[] steps;
- private Integer preparationTimeMinutes;
+ String title,
+ String description,
+ @Description("each step should be described in 4 words, steps should rhyme")
+ String[] steps,
+ Integer preparationTimeMinutes) {
}
interface Chef {
@@ -628,12 +626,10 @@ void should_fail_when_user_message_resource_is_blank() {
.hasMessage("@UserMessage's template cannot be empty");
}
- @Builder
@StructuredPrompt("Create a recipe of a {{dish}} that can be prepared using only {{ingredients}}")
- static class CreateRecipePrompt {
-
- private String dish;
- private List ingredients;
+ record CreateRecipePrompt(
+ String dish,
+ List ingredients) {
}
@Test
@@ -641,10 +637,10 @@ void test_create_recipe_using_structured_prompt() {
Chef chef = AiServices.create(Chef.class, chatLanguageModel);
- CreateRecipePrompt prompt = CreateRecipePrompt.builder()
- .dish("salad")
- .ingredients(asList("cucumber", "tomato", "feta", "onion", "olives"))
- .build();
+ CreateRecipePrompt prompt = new CreateRecipePrompt(
+ "salad",
+ List.of("cucumber", "tomato", "feta", "onion", "olives")
+ );
Recipe recipe = chef.createRecipeFrom(prompt);
@@ -669,11 +665,9 @@ void test_create_recipe_using_structured_prompt_and_system_message() {
Chef chef = AiServices.create(Chef.class, chatLanguageModel);
- CreateRecipePrompt prompt = CreateRecipePrompt
- .builder()
- .dish("salad")
- .ingredients(asList("cucumber", "tomato", "feta", "onion", "olives"))
- .build();
+ CreateRecipePrompt prompt = new CreateRecipePrompt(
+ "salad",
+ List.of("cucumber", "tomato", "feta", "onion", "olives"));
Recipe recipe = chef.createRecipeFrom(prompt, "funny");
@@ -700,11 +694,9 @@ void test_create_recipe_using_structured_prompt_and_system_message_from_resource
Chef chef = AiServices.create(Chef.class, chatLanguageModel);
- CreateRecipePrompt prompt = CreateRecipePrompt
- .builder()
- .dish("salad")
- .ingredients(asList("cucumber", "tomato", "feta", "onion", "olives"))
- .build();
+ CreateRecipePrompt prompt = new CreateRecipePrompt(
+ "salad",
+ List.of("cucumber", "tomato", "feta", "onion", "olives"));
Recipe recipe = chef.createRecipeFromUsingResource(prompt, "funny");
diff --git a/langchain4j/src/test/java/dev/langchain4j/service/AiServicesWithChatMemoryIT.java b/langchain4j/src/test/java/dev/langchain4j/service/AiServicesWithChatMemoryIT.java
index c03f4321825..f50c4d0bc36 100644
--- a/langchain4j/src/test/java/dev/langchain4j/service/AiServicesWithChatMemoryIT.java
+++ b/langchain4j/src/test/java/dev/langchain4j/service/AiServicesWithChatMemoryIT.java
@@ -9,6 +9,7 @@
import dev.langchain4j.store.memory.chat.ChatMemoryStore;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;
@@ -28,9 +29,12 @@
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
@ExtendWith(MockitoExtension.class)
+@EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+")
class AiServicesWithChatMemoryIT {
@Spy
diff --git a/langchain4j/src/test/java/dev/langchain4j/service/AiServicesWithJsonSchemaWithDescriptionsIT.java b/langchain4j/src/test/java/dev/langchain4j/service/AiServicesWithJsonSchemaWithDescriptionsIT.java
index 53d0e870fa4..4f541bb8c5c 100644
--- a/langchain4j/src/test/java/dev/langchain4j/service/AiServicesWithJsonSchemaWithDescriptionsIT.java
+++ b/langchain4j/src/test/java/dev/langchain4j/service/AiServicesWithJsonSchemaWithDescriptionsIT.java
@@ -16,6 +16,7 @@
import dev.langchain4j.model.output.structured.Description;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;
@@ -38,7 +39,8 @@
import static org.mockito.Mockito.verifyNoMoreInteractions;
@ExtendWith(MockitoExtension.class)
-public class AiServicesWithJsonSchemaWithDescriptionsIT {
+@EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+")
+class AiServicesWithJsonSchemaWithDescriptionsIT {
@Spy
ChatLanguageModel model = OpenAiChatModel.builder()
diff --git a/langchain4j/src/test/java/dev/langchain4j/service/AiServicesWithNewToolsIT.java b/langchain4j/src/test/java/dev/langchain4j/service/AiServicesWithNewToolsIT.java
index 87cca4380bd..d738b7acf3c 100644
--- a/langchain4j/src/test/java/dev/langchain4j/service/AiServicesWithNewToolsIT.java
+++ b/langchain4j/src/test/java/dev/langchain4j/service/AiServicesWithNewToolsIT.java
@@ -13,9 +13,6 @@
import dev.langchain4j.model.chat.request.json.JsonSchemaElement;
import dev.langchain4j.model.chat.request.json.JsonStringSchema;
import dev.langchain4j.model.output.Response;
-import lombok.AllArgsConstructor;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledIf;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -81,22 +78,22 @@ int add(int a, int b) {
@Test
protected void should_execute_tool_with_primitive_parameters() {
- for (ChatLanguageModel model : models()) {
+ for (var model : models()) {
// given
model = spy(model);
- ToolWithPrimitiveParameters tool = spy(new ToolWithPrimitiveParameters());
+ var tool = spy(new ToolWithPrimitiveParameters());
- Assistant assistant = AiServices.builder(Assistant.class)
+ var assistant = AiServices.builder(Assistant.class)
.chatLanguageModel(model)
.tools(tool)
.build();
- String text = "How much is 37 plus 87?";
+ var text = "How much is 37 plus 87?";
// when
- Response response = assistant.chat(text);
+ var response = assistant.chat(text);
// then
assertThat(response.content().text()).contains("124");
@@ -109,9 +106,9 @@ protected void should_execute_tool_with_primitive_parameters() {
verify(model, times(2)).generate(anyList(), toolSpecificationCaptor.capture());
verifyNoMoreInteractions(model);
- List toolSpecifications = toolSpecificationCaptor.getValue();
+ var toolSpecifications = toolSpecificationCaptor.getValue();
assertThat(toolSpecifications).hasSize(1);
- ToolSpecification toolSpecification = toolSpecifications.get(0);
+ var toolSpecification = toolSpecifications.get(0);
assertThat(toolSpecification.name()).isEqualTo("add");
assertThat(toolSpecification.description()).isNull();
assertThat(toolSpecification.parameters()).isEqualTo(ToolWithPrimitiveParameters.EXPECTED_SCHEMA);
@@ -121,15 +118,12 @@ protected void should_execute_tool_with_primitive_parameters() {
static class ToolWithPojoParameter {
- @ToString
- @AllArgsConstructor
- @EqualsAndHashCode
- static class Person {
+ record Person(
- String name;
- int age;
- Double height;
- boolean married;
+ String name,
+ int age,
+ Double height,
+ boolean married) {
}
@Tool
@@ -150,20 +144,19 @@ void process(Person person) {
@Test
protected void should_execute_tool_with_pojo_with_primitives() {
-
- for (ChatLanguageModel model : models()) {
+ for (var model : models()) {
// given
model = spy(model);
- ToolWithPojoParameter tool = spy(new ToolWithPojoParameter());
+ var tool = spy(new ToolWithPojoParameter());
- Assistant assistant = AiServices.builder(Assistant.class)
+ var assistant = AiServices.builder(Assistant.class)
.chatLanguageModel(model)
.tools(tool)
.build();
- String text = "Use 'process' tool to process the following: Klaus is 37 years old, 1.78m height and single";
+ var text = "Use 'process' tool to process the following: Klaus is 37 years old, 1.78m height and single";
// when
assistant.chat(text);
@@ -177,9 +170,9 @@ protected void should_execute_tool_with_pojo_with_primitives() {
verify(model, times(2)).generate(anyList(), toolSpecificationCaptor.capture());
verifyNoMoreInteractions(model);
- List toolSpecifications = toolSpecificationCaptor.getValue();
+ var toolSpecifications = toolSpecificationCaptor.getValue();
assertThat(toolSpecifications).hasSize(1);
- ToolSpecification toolSpecification = toolSpecifications.get(0);
+ var toolSpecification = toolSpecifications.get(0);
assertThat(toolSpecification.name()).isEqualTo("process");
assertThat(toolSpecification.description()).isNull();
assertThat(toolSpecification.parameters()).isEqualTo(ToolWithPojoParameter.EXPECTED_SCHEMA);
@@ -189,21 +182,13 @@ protected void should_execute_tool_with_pojo_with_primitives() {
static class ToolWithNestedPojoParameter {
- @ToString
- @AllArgsConstructor
- @EqualsAndHashCode
- static class Person {
-
- String name;
- Address address;
+ record Person(
+ String name,
+ Address address
+ ) {
}
- @ToString
- @AllArgsConstructor
- @EqualsAndHashCode
- static class Address {
-
- String city;
+ record Address(String city) {
}
@Tool
@@ -226,19 +211,19 @@ void process(Person person) {
@Test
protected void should_execute_tool_with_pojo_with_nested_pojo() {
- for (ChatLanguageModel model : models()) {
+ for (var model : models()) {
// given
model = spy(model);
- ToolWithNestedPojoParameter tool = spy(new ToolWithNestedPojoParameter());
+ var tool = spy(new ToolWithNestedPojoParameter());
- Assistant assistant = AiServices.builder(Assistant.class)
+ var assistant = AiServices.builder(Assistant.class)
.chatLanguageModel(model)
.tools(tool)
.build();
- String text = "Use 'process' tool to process the following: Klaus lives in Langley Falls";
+ var text = "Use 'process' tool to process the following: Klaus lives in Langley Falls";
// when
assistant.chat(text);
@@ -252,9 +237,9 @@ protected void should_execute_tool_with_pojo_with_nested_pojo() {
verify(model, times(2)).generate(anyList(), toolSpecificationCaptor.capture());
verifyNoMoreInteractions(model);
- List toolSpecifications = toolSpecificationCaptor.getValue();
+ var toolSpecifications = toolSpecificationCaptor.getValue();
assertThat(toolSpecifications).hasSize(1);
- ToolSpecification toolSpecification = toolSpecifications.get(0);
+ var toolSpecification = toolSpecifications.get(0);
assertThat(toolSpecification.name()).isEqualTo("process");
assertThat(toolSpecification.description()).isNull();
assertThat(toolSpecification.parameters()).isEqualTo(ToolWithNestedPojoParameter.EXPECTED_SCHEMA);
@@ -264,13 +249,10 @@ protected void should_execute_tool_with_pojo_with_nested_pojo() {
static class ToolWithRecursion {
- @ToString
- @AllArgsConstructor
- @EqualsAndHashCode
- static class Person {
-
- String name;
- List children;
+ record Person(
+ String name,
+ List children
+ ) {
}
@Tool
@@ -280,7 +262,7 @@ void process(Person person) {
static final String REFERENCE = generateUUIDFrom(ToolWithRecursion.Person.class.getName());
static final JsonObjectSchema PERSON_SCHEMA = JsonObjectSchema.builder()
- .properties(new LinkedHashMap() {{
+ .properties(new LinkedHashMap<>() {{
put("name", new JsonStringSchema());
put("children", JsonArraySchema.builder()
.items(JsonReferenceSchema.builder()
@@ -302,19 +284,19 @@ void process(Person person) {
@EnabledIf("supportsRecursion")
protected void should_execute_tool_with_pojo_with_recursion() {
- for (ChatLanguageModel model : models()) {
+ for (var model : models()) {
// given
model = spy(model);
- ToolWithRecursion tool = spy(new ToolWithRecursion());
+ var tool = spy(new ToolWithRecursion());
- Assistant assistant = AiServices.builder(Assistant.class)
+ var assistant = AiServices.builder(Assistant.class)
.chatLanguageModel(model)
.tools(tool)
.build();
- String text = "Use 'process' tool to process the following: Francine has 2 children: Steve and Hayley";
+ var text = "Use 'process' tool to process the following: Francine has 2 children: Steve and Hayley";
// when
assistant.chat(text);
@@ -336,9 +318,9 @@ protected void should_execute_tool_with_pojo_with_recursion() {
verify(model, times(2)).generate(anyList(), toolSpecificationCaptor.capture());
verifyNoMoreInteractions(model);
- List toolSpecifications = toolSpecificationCaptor.getValue();
+ var toolSpecifications = toolSpecificationCaptor.getValue();
assertThat(toolSpecifications).hasSize(1);
- ToolSpecification toolSpecification = toolSpecifications.get(0);
+ var toolSpecification = toolSpecifications.get(0);
assertThat(toolSpecification.name()).isEqualTo("process");
assertThat(toolSpecification.description()).isNull();
assertThat(toolSpecification.parameters()).isEqualTo(ToolWithRecursion.EXPECTED_SCHEMA);
@@ -361,22 +343,22 @@ LocalTime currentTime() { // TODO support LocalTime
@Test
protected void should_execute_tool_without_parameters() {
- for (ChatLanguageModel model : models()) {
+ for (var model : models()) {
// given
model = spy(model);
- ToolWithoutParameters tools = spy(new ToolWithoutParameters());
+ var tools = spy(new ToolWithoutParameters());
- Assistant assistant = AiServices.builder(Assistant.class)
+ var assistant = AiServices.builder(Assistant.class)
.chatLanguageModel(model)
.tools(tools)
.build();
- String text = "What is the time now? Respond in HH:MM:SS format.";
+ var text = "What is the time now? Respond in HH:MM:SS format.";
// when
- Response response = assistant.chat(text);
+ var response = assistant.chat(text);
// then
assertThat(response.content().text()).contains("17:11:45");
@@ -389,9 +371,9 @@ protected void should_execute_tool_without_parameters() {
verify(model, times(2)).generate(anyList(), toolSpecificationCaptor.capture());
verifyNoMoreInteractions(model);
- List toolSpecifications = toolSpecificationCaptor.getValue();
+ var toolSpecifications = toolSpecificationCaptor.getValue();
assertThat(toolSpecifications).hasSize(1);
- ToolSpecification toolSpecification = toolSpecifications.get(0);
+ var toolSpecification = toolSpecifications.get(0);
assertThat(toolSpecification.name()).isEqualTo("currentTime");
assertThat(toolSpecification.description()).isNull();
assertThat(toolSpecification.parameters()).isNull();
@@ -426,22 +408,22 @@ int currentTemperature(String city, TemperatureUnit unit) {
@Test
protected void should_execute_tool_with_enum_parameter() {
- for (ChatLanguageModel model : models()) {
+ for (var model : models()) {
// given
model = spy(model);
- ToolWithEnumParameter tool = spy(new ToolWithEnumParameter());
+ var tool = spy(new ToolWithEnumParameter());
- Assistant assistant = AiServices.builder(Assistant.class)
+ var assistant = AiServices.builder(Assistant.class)
.chatLanguageModel(model)
.tools(tool)
.build();
- String text = "What is the weather in Munich in celsius?";
+ var text = "What is the weather in Munich in celsius?";
// when
- Response response = assistant.chat(text);
+ var response = assistant.chat(text);
// then
assertThat(response.content().text()).contains("19");
@@ -454,7 +436,7 @@ protected void should_execute_tool_with_enum_parameter() {
verify(model, times(2)).generate(anyList(), toolSpecificationCaptor.capture());
verifyNoMoreInteractions(model);
- List toolSpecifications = toolSpecificationCaptor.getValue();
+ var toolSpecifications = toolSpecificationCaptor.getValue();
assertThat(toolSpecifications).hasSize(1);
assertThat(toolSpecifications.get(0)).isEqualTo(ToolWithEnumParameter.EXPECTED_SPECIFICATION);
}
@@ -482,19 +464,19 @@ void process(@P("map from name to age") Map ages) {
@EnabledIf("supportsMapParameters")
protected void should_execute_tool_with_map_parameter() {
- for (ChatLanguageModel model : modelsSupportingMapParametersInTools()) {
+ for (var model : modelsSupportingMapParametersInTools()) {
// given
model = spy(model);
- ToolWithMapParameter tool = spy(new ToolWithMapParameter());
+ var tool = spy(new ToolWithMapParameter());
- Assistant assistant = AiServices.builder(Assistant.class)
+ var assistant = AiServices.builder(Assistant.class)
.chatLanguageModel(model)
.tools(tool)
.build();
- String text = "Process the following: Klaus is 42 years old and Francine is 47 years old";
+ var text = "Process the following: Klaus is 42 years old and Francine is 47 years old";
// when
assistant.chat(text);
@@ -511,7 +493,7 @@ protected void should_execute_tool_with_map_parameter() {
verify(model, times(2)).generate(anyList(), toolSpecificationCaptor.capture());
verifyNoMoreInteractions(model);
- List toolSpecifications = toolSpecificationCaptor.getValue();
+ var toolSpecifications = toolSpecificationCaptor.getValue();
assertThat(toolSpecifications).hasSize(1);
assertThat(toolSpecifications.get(0)).isEqualTo(ToolWithMapParameter.EXPECTED_SPECIFICATION);
}
@@ -542,19 +524,19 @@ void processNames(List names) {
@Test
protected void should_execute_tool_with_list_of_strings_parameter() {
- for (ChatLanguageModel model : models()) {
+ for (var model : models()) {
// given
model = spy(model);
- ToolWithListOfStringsParameter tool = spy(new ToolWithListOfStringsParameter());
+ var tool = spy(new ToolWithListOfStringsParameter());
- Assistant assistant = AiServices.builder(Assistant.class)
+ var assistant = AiServices.builder(Assistant.class)
.chatLanguageModel(model)
.tools(tool)
.build();
- String text = "Process the following names: Klaus and Franny";
+ var text = "Process the following names: Klaus and Franny";
// when
assistant.chat(text);
@@ -568,7 +550,7 @@ protected void should_execute_tool_with_list_of_strings_parameter() {
verify(model, times(2)).generate(anyList(), toolSpecificationCaptor.capture());
verifyNoMoreInteractions(model);
- List toolSpecifications = toolSpecificationCaptor.getValue();
+ var toolSpecifications = toolSpecificationCaptor.getValue();
assertThat(toolSpecifications).hasSize(1);
assertThat(toolSpecifications.get(0)).isEqualTo(ToolWithListOfStringsParameter.EXPECTED_SPECIFICATION);
}
@@ -602,19 +584,19 @@ void process(Set colors) {
@Test
protected void should_execute_tool_with_set_of_enums_parameter() {
- for (ChatLanguageModel model : models()) {
+ for (var model : models()) {
// given
model = spy(model);
- ToolWithSetOfEnumsParameter tool = spy(new ToolWithSetOfEnumsParameter());
+ var tool = spy(new ToolWithSetOfEnumsParameter());
- Assistant assistant = AiServices.builder(Assistant.class)
+ var assistant = AiServices.builder(Assistant.class)
.chatLanguageModel(model)
.tools(tool)
.build();
- String text = "Process the following colors: RED and GREEN";
+ var text = "Process the following colors: RED and GREEN";
// when
assistant.chat(text);
@@ -628,7 +610,7 @@ protected void should_execute_tool_with_set_of_enums_parameter() {
verify(model, times(2)).generate(anyList(), toolSpecificationCaptor.capture());
verifyNoMoreInteractions(model);
- List toolSpecifications = toolSpecificationCaptor.getValue();
+ var toolSpecifications = toolSpecificationCaptor.getValue();
assertThat(toolSpecifications).hasSize(1);
assertThat(toolSpecifications.get(0)).isEqualTo(ToolWithSetOfEnumsParameter.EXPECTED_SPECIFICATION);
}
@@ -655,19 +637,19 @@ void processNumbers(Collection names) {
@Test
protected void should_execute_tool_with_collection_of_integers_parameter() {
- for (ChatLanguageModel model : models()) {
+ for (var model : models()) {
// given
model = spy(model);
- ToolWithCollectionOfIntegersParameter tool = spy(new ToolWithCollectionOfIntegersParameter());
+ var tool = spy(new ToolWithCollectionOfIntegersParameter());
- Assistant assistant = AiServices.builder(Assistant.class)
+ var assistant = AiServices.builder(Assistant.class)
.chatLanguageModel(model)
.tools(tool)
.build();
- String text = "Process the following integers: 37, 73";
+ var text = "Process the following integers: 37, 73";
// when
assistant.chat(text);
@@ -681,7 +663,7 @@ protected void should_execute_tool_with_collection_of_integers_parameter() {
verify(model, times(2)).generate(anyList(), toolSpecificationCaptor.capture());
verifyNoMoreInteractions(model);
- List toolSpecifications = toolSpecificationCaptor.getValue();
+ var toolSpecifications = toolSpecificationCaptor.getValue();
assertThat(toolSpecifications).hasSize(1);
assertThat(toolSpecifications.get(0)).isEqualTo(ToolWithCollectionOfIntegersParameter.EXPECTED_SPECIFICATION);
}
@@ -690,12 +672,7 @@ protected void should_execute_tool_with_collection_of_integers_parameter() {
static class ToolWithListOfPojoParameter {
- @ToString
- @AllArgsConstructor
- @EqualsAndHashCode
- static class Person {
-
- String name;
+ record Person(String name) {
}
@Tool
@@ -720,19 +697,19 @@ void process(List people) {
@Test
protected void should_execute_tool_with_list_of_POJOs_parameter() {
- for (ChatLanguageModel model : models()) {
+ for (var model : models()) {
// given
model = spy(model);
- ToolWithListOfPojoParameter tool = spy(new ToolWithListOfPojoParameter());
+ var tool = spy(new ToolWithListOfPojoParameter());
- Assistant assistant = AiServices.builder(Assistant.class)
+ var assistant = AiServices.builder(Assistant.class)
.chatLanguageModel(model)
.tools(tool)
.build();
- String text = "Process the following people: Klaus and Franny";
+ var text = "Process the following people: Klaus and Franny";
// when
assistant.chat(text);
@@ -754,7 +731,7 @@ protected void should_execute_tool_with_list_of_POJOs_parameter() {
verify(model, times(2)).generate(anyList(), toolSpecificationCaptor.capture());
verifyNoMoreInteractions(model);
- List toolSpecifications = toolSpecificationCaptor.getValue();
+ var toolSpecifications = toolSpecificationCaptor.getValue();
assertThat(toolSpecifications).hasSize(1);
assertThat(toolSpecifications.get(0)).isEqualTo(ToolWithListOfPojoParameter.EXPECTED_SPECIFICATION);
}
diff --git a/langchain4j/src/test/java/dev/langchain4j/service/AiServicesWithNewToolsWithDescriptionIT.java b/langchain4j/src/test/java/dev/langchain4j/service/AiServicesWithNewToolsWithDescriptionIT.java
index e50f2236425..c3a93d319ba 100644
--- a/langchain4j/src/test/java/dev/langchain4j/service/AiServicesWithNewToolsWithDescriptionIT.java
+++ b/langchain4j/src/test/java/dev/langchain4j/service/AiServicesWithNewToolsWithDescriptionIT.java
@@ -14,9 +14,7 @@
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.model.output.structured.Description;
-import lombok.AllArgsConstructor;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
@@ -45,6 +43,7 @@
import static org.mockito.Mockito.verifyNoMoreInteractions;
@ExtendWith(MockitoExtension.class)
+@EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+")
class AiServicesWithNewToolsWithDescriptionIT {
@Captor
@@ -123,27 +122,26 @@ void should_execute_tool_with_primitive_parameters(ChatLanguageModel model) {
static class ToolWithPojoParameter {
- @ToString
- @AllArgsConstructor
- @EqualsAndHashCode
@Description("a person")
- static class Person {
+ record Person(
- @Description("a name")
- String name;
+ @Description("a name")
+ String name,
- @Description("an age")
- int age;
+ @Description("an age")
+ int age,
- @Description("a height")
- Double height;
+ @Description("a height")
+ Double height,
- @Description("is married")
- boolean married;
+ @Description("is married")
+ boolean married
+ ) {
}
@Tool("processes a person")
void process(@P("a person 2") Person person) {
+ // this method is empty
}
static JsonSchemaElement EXPECTED_SCHEMA = JsonObjectSchema.builder()
@@ -197,27 +195,20 @@ void should_execute_tool_with_pojo_with_primitives(ChatLanguageModel model) {
static class ToolWithNestedPojoParameter {
- @ToString
- @AllArgsConstructor
- @EqualsAndHashCode
@Description("a person")
- static class Person {
+ record Person(
- @Description("a name")
- String name;
+ @Description("a name")
+ String name,
- @Description("an address 2")
- Address address;
+ @Description("an address 2")
+ Address address) {
}
- @ToString
- @AllArgsConstructor
- @EqualsAndHashCode
@Description("an address")
- static class Address {
-
- @Description("a city")
- String city;
+ record Address(
+ @Description("a city")
+ String city) {
}
@Tool("processes a person")
@@ -276,21 +267,19 @@ void should_execute_tool_with_pojo_with_nested_pojo(ChatLanguageModel model) {
static class ToolWithRecursion {
- @ToString
- @AllArgsConstructor
- @EqualsAndHashCode
@Description("a person")
- static class Person {
-
- @Description("a name")
- String name;
+ record Person(
+ @Description("a name")
+ String name,
- @Description("a list of person")
- List children;
+ @Description("a list of person")
+ List children
+ ) {
}
@Tool("processes a person")
void process(@P("a person 2") Person person) {
+ // this method is empty
}
static final String REFERENCE = generateUUIDFrom(Person.class.getName());
@@ -422,6 +411,7 @@ static class ToolWithMapParameter {
@Tool("processes ages")
void process(@P("map from name to age") Map ages) {
+ // this method is empty
}
static ToolSpecification EXPECTED_SPECIFICATION = ToolSpecification.builder()
@@ -456,7 +446,7 @@ void should_execute_tool_with_map_parameter(ChatLanguageModel model) {
assistant.chat(text);
// then
- verify(tool).process(new HashMap() {{
+ verify(tool).process(new HashMap<>() {{
put("Klaus", 42);
put("Francine", 47);
}});
diff --git a/langchain4j/src/test/java/dev/langchain4j/service/AiServicesWithRagIT.java b/langchain4j/src/test/java/dev/langchain4j/service/AiServicesWithRagIT.java
index 2777fb3c019..addf55c63a7 100644
--- a/langchain4j/src/test/java/dev/langchain4j/service/AiServicesWithRagIT.java
+++ b/langchain4j/src/test/java/dev/langchain4j/service/AiServicesWithRagIT.java
@@ -9,8 +9,8 @@
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.ChatLanguageModel;
-import dev.langchain4j.model.embedding.onnx.allminilml6v2q.AllMiniLmL6V2QuantizedEmbeddingModel;
import dev.langchain4j.model.embedding.EmbeddingModel;
+import dev.langchain4j.model.embedding.onnx.allminilml6v2q.AllMiniLmL6V2QuantizedEmbeddingModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.model.openai.OpenAiTokenizer;
import dev.langchain4j.model.output.Response;
@@ -37,6 +37,7 @@
import dev.langchain4j.store.embedding.filter.builder.sql.TableDefinition;
import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
@@ -59,8 +60,15 @@
import static java.util.Collections.emptyList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import static org.mockito.Mockito.*;
-
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+@EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+")
class AiServicesWithRagIT {
private static final String ALLOWED_CANCELLATION_PERIOD_DAYS = "61";
diff --git a/langchain4j/src/test/java/dev/langchain4j/service/AiServicesWithToolsIT.java b/langchain4j/src/test/java/dev/langchain4j/service/AiServicesWithToolsIT.java
index a231c862212..15c6084e4e3 100644
--- a/langchain4j/src/test/java/dev/langchain4j/service/AiServicesWithToolsIT.java
+++ b/langchain4j/src/test/java/dev/langchain4j/service/AiServicesWithToolsIT.java
@@ -29,9 +29,8 @@
import dev.langchain4j.service.tool.ToolProvider;
import dev.langchain4j.service.tool.ToolProviderRequest;
import dev.langchain4j.service.tool.ToolProviderResult;
-import lombok.AllArgsConstructor;
-import lombok.Data;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
@@ -65,6 +64,7 @@
import static org.mockito.Mockito.verifyNoMoreInteractions;
@ExtendWith(MockitoExtension.class)
+@EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+")
class AiServicesWithToolsIT {
static Stream models() {
@@ -626,35 +626,32 @@ String executeQuery(@P("query to execute") Query query) {
}
}
- @Data
- static class Query {
+ static record Query(
@Description("List of fields to fetch records")
- List select;
+ List select,
@Description("List of conditions to filter on. Pass null if no condition")
- List where;
+ List where,
@Description("limit on number of records")
- Integer limit;
+ Integer limit,
@Description("offset for fetching records")
- Integer offset;
- }
+ Integer offset)
+ {}
- @Data
- @AllArgsConstructor
- static class Condition {
+ static record Condition(
@Description("Field to filter on")
- String field;
+ String field,
@Description("Operator to apply")
- Operator operator;
+ Operator operator,
@Description("Value to compare with")
- String value;
- }
+ String value)
+ {}
enum Operator {
@@ -941,7 +938,8 @@ public void should_execute_a_tool_and_context_included_in_result(ChatLanguageMod
@ParameterizedTest
@MethodSource("models")
- public void should_execute_multi_tool_in_parallel_and_context_included_in_result(ChatLanguageModel chatLanguageModel) {
+ @EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+")
+ void should_execute_multi_tool_in_parallel_and_context_included_in_result(ChatLanguageModel chatLanguageModel) {
// given
TransactionService transactionService = spy(new TransactionService());
diff --git a/langchain4j/src/test/java/dev/langchain4j/service/AiServicesWithToolsWithoutMemoryIT.java b/langchain4j/src/test/java/dev/langchain4j/service/AiServicesWithToolsWithoutMemoryIT.java
index ee651995ef5..7d5cd84636f 100644
--- a/langchain4j/src/test/java/dev/langchain4j/service/AiServicesWithToolsWithoutMemoryIT.java
+++ b/langchain4j/src/test/java/dev/langchain4j/service/AiServicesWithToolsWithoutMemoryIT.java
@@ -8,6 +8,7 @@
import dev.langchain4j.model.output.Response;
import dev.langchain4j.model.output.TokenUsage;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;
@@ -16,9 +17,12 @@
import static dev.langchain4j.model.output.FinishReason.STOP;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.data.Percentage.withPercentage;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
@ExtendWith(MockitoExtension.class)
+@EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+")
class AiServicesWithToolsWithoutMemoryIT {
@Spy
diff --git a/langchain4j/src/test/java/dev/langchain4j/service/OpenAiAiServiceWithToolsIT.java b/langchain4j/src/test/java/dev/langchain4j/service/OpenAiAiServiceWithToolsIT.java
index 1ae84d4d747..5afd1a8c672 100644
--- a/langchain4j/src/test/java/dev/langchain4j/service/OpenAiAiServiceWithToolsIT.java
+++ b/langchain4j/src/test/java/dev/langchain4j/service/OpenAiAiServiceWithToolsIT.java
@@ -2,6 +2,7 @@
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
import java.util.List;
@@ -10,6 +11,7 @@
import static java.util.Collections.singletonList;
// TODO move to langchain4j-open-ai module once cyclic dependency is resolved
+@EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+")
class OpenAiAiServiceWithToolsIT extends AiServicesWithNewToolsIT {
@Override
diff --git a/langchain4j/src/test/java/dev/langchain4j/service/OpenAiAiServicesWithJsonSchemaIT.java b/langchain4j/src/test/java/dev/langchain4j/service/OpenAiAiServicesWithJsonSchemaIT.java
index 78bcdd0f3b4..52c9b656c02 100644
--- a/langchain4j/src/test/java/dev/langchain4j/service/OpenAiAiServicesWithJsonSchemaIT.java
+++ b/langchain4j/src/test/java/dev/langchain4j/service/OpenAiAiServicesWithJsonSchemaIT.java
@@ -2,6 +2,7 @@
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
import java.util.List;
@@ -9,6 +10,7 @@
import static java.util.Arrays.asList;
// TODO move to langchain4j-open-ai module once dependency cycle is resolved
+@EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+")
class OpenAiAiServicesWithJsonSchemaIT extends AiServicesWithJsonSchemaIT {
@Override
diff --git a/langchain4j/src/test/java/dev/langchain4j/service/StreamingAiServicesIT.java b/langchain4j/src/test/java/dev/langchain4j/service/StreamingAiServicesIT.java
index ecf27503ce1..933d370e75d 100644
--- a/langchain4j/src/test/java/dev/langchain4j/service/StreamingAiServicesIT.java
+++ b/langchain4j/src/test/java/dev/langchain4j/service/StreamingAiServicesIT.java
@@ -17,6 +17,7 @@
import dev.langchain4j.rag.RetrievalAugmentor;
import dev.langchain4j.rag.content.Content;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
@@ -36,7 +37,8 @@
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
-public class StreamingAiServicesIT {
+@EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+")
+class StreamingAiServicesIT {
static Stream models() {
return Stream.of(
diff --git a/langchain4j/src/test/java/dev/langchain4j/service/StreamingAiServicesWithToolsIT.java b/langchain4j/src/test/java/dev/langchain4j/service/StreamingAiServicesWithToolsIT.java
index 1d6274f2c63..f150d5a5361 100644
--- a/langchain4j/src/test/java/dev/langchain4j/service/StreamingAiServicesWithToolsIT.java
+++ b/langchain4j/src/test/java/dev/langchain4j/service/StreamingAiServicesWithToolsIT.java
@@ -20,6 +20,7 @@
import dev.langchain4j.service.tool.ToolProvider;
import dev.langchain4j.service.tool.ToolProviderResult;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
@@ -43,6 +44,7 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
+@EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+")
class StreamingAiServicesWithToolsIT {
static Stream models() {
diff --git a/langchain4j/src/test/java/dev/langchain4j/service/StreamingAiServicesWithToolsWithoutMemoryIT.java b/langchain4j/src/test/java/dev/langchain4j/service/StreamingAiServicesWithToolsWithoutMemoryIT.java
index 0b3573bb31d..3434c85235a 100644
--- a/langchain4j/src/test/java/dev/langchain4j/service/StreamingAiServicesWithToolsWithoutMemoryIT.java
+++ b/langchain4j/src/test/java/dev/langchain4j/service/StreamingAiServicesWithToolsWithoutMemoryIT.java
@@ -11,6 +11,7 @@
import dev.langchain4j.model.output.Response;
import dev.langchain4j.model.output.TokenUsage;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Spy;
@@ -23,9 +24,15 @@
import static dev.langchain4j.model.openai.OpenAiChatModelName.GPT_4_O_MINI;
import static dev.langchain4j.model.output.FinishReason.STOP;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyList;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
@ExtendWith(MockitoExtension.class)
+@EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+")
class StreamingAiServicesWithToolsWithoutMemoryIT {
@Spy
diff --git a/langchain4j/src/test/java/dev/langchain4j/service/tool/DefaultToolExecutorTest.java b/langchain4j/src/test/java/dev/langchain4j/service/tool/DefaultToolExecutorTest.java
index f61851995f4..7c22fb71e5e 100644
--- a/langchain4j/src/test/java/dev/langchain4j/service/tool/DefaultToolExecutorTest.java
+++ b/langchain4j/src/test/java/dev/langchain4j/service/tool/DefaultToolExecutorTest.java
@@ -4,8 +4,6 @@
import dev.langchain4j.agent.tool.Tool;
import dev.langchain4j.agent.tool.ToolExecutionRequest;
import dev.langchain4j.agent.tool.ToolMemoryId;
-import lombok.AllArgsConstructor;
-import lombok.EqualsAndHashCode;
import org.assertj.core.api.WithAssertions;
import org.junit.jupiter.api.Test;
@@ -149,12 +147,10 @@ public void test_prepareArguments() throws Exception {
}
}
- @AllArgsConstructor
- @EqualsAndHashCode
- static class Person {
+ record Person(
- String name;
- int age;
+ String name,
+ int age) {
}
@Test
@@ -481,4 +477,4 @@ public void should_execute_tools_with_collection() {
" }\n" +
"]");
}
-}
\ No newline at end of file
+}