Revert ServiceHelper refactoring (#485)

This commit is contained in:
LangChain4j 2024-02-05 14:39:17 +01:00
parent e1c02b6f52
commit 13c7ee7f1c
52 changed files with 316 additions and 351 deletions

View File

@ -16,7 +16,6 @@ import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.chat.TokenCountEstimator;
import dev.langchain4j.model.openai.OpenAiTokenizer;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.spi.ServiceHelper;
import java.time.Duration;
import java.util.List;
@ -24,6 +23,7 @@ import java.util.List;
import static dev.langchain4j.internal.Utils.getOrDefault;
import static dev.langchain4j.model.azure.AzureOpenAiModelName.GPT_3_5_TURBO;
import static dev.langchain4j.model.azure.InternalAzureOpenAiHelper.*;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.util.Collections.singletonList;
/**
@ -205,10 +205,10 @@ public class AzureOpenAiChatModel implements ChatLanguageModel, TokenCountEstima
}
public static Builder builder() {
return ServiceHelper.loadFactoryService(
AzureOpenAiChatModelBuilderFactory.class,
Builder::new
);
for (AzureOpenAiChatModelBuilderFactory factory : loadFactories(AzureOpenAiChatModelBuilderFactory.class)) {
return factory.get();
}
return new Builder();
}
public static class Builder {
@ -280,6 +280,7 @@ public class AzureOpenAiChatModel implements ChatLanguageModel, TokenCountEstima
/**
* Used to authenticate to Azure OpenAI with Azure Active Directory credentials.
*
* @param tokenCredential the credentials to authenticate with Azure Active Directory
* @return builder
*/

View File

@ -16,7 +16,6 @@ import dev.langchain4j.model.embedding.TokenCountEstimator;
import dev.langchain4j.model.openai.OpenAiTokenizer;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.model.output.TokenUsage;
import dev.langchain4j.spi.ServiceHelper;
import java.time.Duration;
import java.util.ArrayList;
@ -25,6 +24,7 @@ import java.util.List;
import static dev.langchain4j.internal.Utils.getOrDefault;
import static dev.langchain4j.model.azure.AzureOpenAiModelName.TEXT_EMBEDDING_ADA_002;
import static dev.langchain4j.model.azure.InternalAzureOpenAiHelper.setupOpenAIClient;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.util.stream.Collectors.toList;
/**
@ -172,10 +172,10 @@ public class AzureOpenAiEmbeddingModel implements EmbeddingModel, TokenCountEsti
}
public static Builder builder() {
return ServiceHelper.loadFactoryService(
AzureOpenAiEmbeddingModelBuilderFactory.class,
Builder::new
);
for (AzureOpenAiEmbeddingModelBuilderFactory factory : loadFactories(AzureOpenAiEmbeddingModelBuilderFactory.class)) {
return factory.get();
}
return new Builder();
}
public static class Builder {

View File

@ -9,13 +9,13 @@ import dev.langchain4j.data.image.Image;
import dev.langchain4j.model.azure.spi.AzureOpenAiImageModelBuilderFactory;
import dev.langchain4j.model.image.ImageModel;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.spi.ServiceHelper;
import java.time.Duration;
import static dev.langchain4j.internal.Utils.getOrDefault;
import static dev.langchain4j.model.azure.InternalAzureOpenAiHelper.imageFrom;
import static dev.langchain4j.model.azure.InternalAzureOpenAiHelper.setupOpenAIClient;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
/**
* Represents an OpenAI image model, hosted on Azure, such as dall-e-3.
@ -155,10 +155,10 @@ public class AzureOpenAiImageModel implements ImageModel {
}
public static Builder builder() {
return ServiceHelper.loadFactoryService(
AzureOpenAiImageModelBuilderFactory.class,
Builder::new
);
for (AzureOpenAiImageModelBuilderFactory factory : loadFactories(AzureOpenAiImageModelBuilderFactory.class)) {
return factory.get();
}
return new Builder();
}
public static class Builder {

View File

@ -12,7 +12,6 @@ import dev.langchain4j.model.language.LanguageModel;
import dev.langchain4j.model.language.TokenCountEstimator;
import dev.langchain4j.model.openai.OpenAiTokenizer;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.spi.ServiceHelper;
import java.time.Duration;
import java.util.Collections;
@ -20,6 +19,7 @@ import java.util.Collections;
import static dev.langchain4j.internal.Utils.getOrDefault;
import static dev.langchain4j.model.azure.AzureOpenAiModelName.GPT_3_5_TURBO_INSTRUCT;
import static dev.langchain4j.model.azure.InternalAzureOpenAiHelper.*;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
/**
* Represents an OpenAI language model, hosted on Azure, such as gpt-3.5-turbo-instruct.
@ -167,10 +167,10 @@ public class AzureOpenAiLanguageModel implements LanguageModel, TokenCountEstima
}
public static Builder builder() {
return ServiceHelper.loadFactoryService(
AzureOpenAiLanguageModelBuilderFactory.class,
Builder::new
);
for (AzureOpenAiLanguageModelBuilderFactory factory : loadFactories(AzureOpenAiLanguageModelBuilderFactory.class)) {
return factory.get();
}
return new Builder();
}
public static class Builder {

View File

@ -18,7 +18,6 @@ import dev.langchain4j.model.chat.StreamingChatLanguageModel;
import dev.langchain4j.model.chat.TokenCountEstimator;
import dev.langchain4j.model.openai.OpenAiTokenizer;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.spi.ServiceHelper;
import java.time.Duration;
import java.util.List;
@ -28,6 +27,7 @@ import static dev.langchain4j.internal.Utils.isNullOrEmpty;
import static dev.langchain4j.model.azure.AzureOpenAiModelName.GPT_3_5_TURBO;
import static dev.langchain4j.model.azure.InternalAzureOpenAiHelper.setupOpenAIClient;
import static dev.langchain4j.model.azure.InternalAzureOpenAiHelper.toFunctions;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.util.Collections.singletonList;
/**
@ -241,10 +241,10 @@ public class AzureOpenAiStreamingChatModel implements StreamingChatLanguageModel
}
public static Builder builder() {
return ServiceHelper.loadFactoryService(
AzureOpenAiStreamingChatModelBuilderFactory.class,
Builder::new
);
for (AzureOpenAiStreamingChatModelBuilderFactory factory : loadFactories(AzureOpenAiStreamingChatModelBuilderFactory.class)) {
return factory.get();
}
return new Builder();
}
public static class Builder {

View File

@ -16,7 +16,6 @@ import dev.langchain4j.model.language.TokenCountEstimator;
import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
import dev.langchain4j.model.openai.OpenAiTokenizer;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.spi.ServiceHelper;
import java.time.Duration;
import java.util.Collections;
@ -25,6 +24,7 @@ import java.util.List;
import static dev.langchain4j.internal.Utils.getOrDefault;
import static dev.langchain4j.model.azure.AzureOpenAiModelName.GPT_3_5_TURBO_INSTRUCT;
import static dev.langchain4j.model.azure.InternalAzureOpenAiHelper.setupOpenAIClient;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
/**
* Represents an OpenAI language model, hosted on Azure, such as gpt-3.5-turbo-instruct.
@ -200,10 +200,10 @@ public class AzureOpenAiStreamingLanguageModel implements StreamingLanguageModel
}
public static Builder builder() {
return ServiceHelper.loadFactoryService(
AzureOpenAiStreamingLanguageModelBuilderFactory.class,
Builder::new
);
for (AzureOpenAiStreamingLanguageModelBuilderFactory factory : loadFactories(AzureOpenAiStreamingLanguageModelBuilderFactory.class)) {
return factory.get();
}
return new Builder();
}
public static class Builder {

View File

@ -6,7 +6,6 @@ import dev.langchain4j.data.message.ChatMessageType;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.chatglm.spi.ChatGlmChatModelBuilderFactory;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import java.time.Duration;
@ -16,6 +15,7 @@ import java.util.stream.Collectors;
import static dev.langchain4j.internal.RetryUtils.withRetry;
import static dev.langchain4j.internal.Utils.getOrDefault;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
/**
* Support <a href="https://github.com/THUDM/ChatGLM-6B">ChatGLM</a>,
@ -85,10 +85,10 @@ public class ChatGlmChatModel implements ChatLanguageModel {
}
public static ChatGlmChatModelBuilder builder() {
return ServiceHelper.loadFactoryService(
ChatGlmChatModelBuilderFactory.class,
ChatGlmChatModelBuilder::new
);
for (ChatGlmChatModelBuilderFactory factory : loadFactories(ChatGlmChatModelBuilderFactory.class)) {
return factory.get();
}
return new ChatGlmChatModelBuilder();
}
public static class ChatGlmChatModelBuilder {

View File

@ -1,22 +1,21 @@
package dev.langchain4j.data.message;
import dev.langchain4j.spi.ServiceHelper;
import dev.langchain4j.spi.data.message.ChatMessageJsonCodecFactory;
import java.util.List;
/**
* A serializer for {@link ChatMessage} objects.
*/
public class ChatMessageSerializer {
private ChatMessageSerializer() {}
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
/**
* The {@link ChatMessageJsonCodec} instance used for serialization and deserialization.
*/
static final ChatMessageJsonCodec CODEC = ServiceHelper.loadFactoryService(
ChatMessageJsonCodecFactory.class,
ChatMessageJsonCodecFactory::create,
GsonChatMessageJsonCodec::new);
public class ChatMessageSerializer {
static final ChatMessageJsonCodec CODEC = loadCodec();
private static ChatMessageJsonCodec loadCodec() {
for (ChatMessageJsonCodecFactory factory : loadFactories(ChatMessageJsonCodecFactory.class)) {
return factory.create();
}
return new GsonChatMessageJsonCodec();
}
/**
* Serializes a chat message into a JSON string.

View File

@ -1,16 +1,18 @@
package dev.langchain4j.internal;
import dev.langchain4j.spi.ServiceHelper;
import dev.langchain4j.spi.json.JsonCodecFactory;
import java.io.IOException;
import java.io.InputStream;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
/**
* A utility class for JSON.
*/
public class Json {
private Json() {}
private Json() {
}
/**
* The abstract JSON codec interface.
@ -19,6 +21,7 @@ public class Json {
/**
* Convert the given object to JSON.
*
* @param o the object to convert.
* @return the JSON string.
*/
@ -26,16 +29,18 @@ public class Json {
/**
* Convert the given JSON string to an object of the given type.
*
* @param json the JSON string.
* @param type the type of the object.
* @param <T> the type of the object.
* @param <T> the type of the object.
* @return the object.
*/
<T> T fromJson(String json, Class<T> type);
/**
* Convert the given object to an {@link InputStream}.
* @param o the object to convert.
*
* @param o the object to convert.
* @param type the type of the object.
* @return the {@link InputStream}.
* @throws IOException if an I/O error occurs.
@ -43,11 +48,18 @@ public class Json {
InputStream toInputStream(Object o, Class<?> type) throws IOException;
}
private static final JsonCodec CODEC = ServiceHelper.loadFactoryService(
JsonCodecFactory.class, JsonCodecFactory::create, GsonJsonCodec::new);
private static final JsonCodec CODEC = loadCodec();
private static JsonCodec loadCodec() {
for (JsonCodecFactory factory : loadFactories(JsonCodecFactory.class)) {
return factory.create();
}
return new GsonJsonCodec();
}
/**
* Convert the given object to JSON.
*
* @param o the object to convert.
* @return the JSON string.
*/
@ -57,9 +69,10 @@ public class Json {
/**
* Convert the given JSON string to an object of the given type.
*
* @param json the JSON string.
* @param type the type of the object.
* @param <T> the type of the object.
* @param <T> the type of the object.
* @return the object.
*/
public static <T> T fromJson(String json, Class<T> type) {
@ -68,7 +81,8 @@ public class Json {
/**
* Convert the given object to an {@link InputStream}.
* @param o the object to convert.
*
* @param o the object to convert.
* @param type the type of the object.
* @return the {@link InputStream}.
* @throws IOException if an I/O error occurs.

View File

@ -1,6 +1,5 @@
package dev.langchain4j.model.input;
import dev.langchain4j.spi.ServiceHelper;
import dev.langchain4j.spi.prompt.PromptTemplateFactory;
import java.time.Clock;
@ -12,6 +11,7 @@ import java.util.Map;
import static dev.langchain4j.internal.ValidationUtils.ensureNotBlank;
import static dev.langchain4j.internal.ValidationUtils.ensureNotNull;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.util.Collections.singletonMap;
/**
@ -23,8 +23,14 @@ import static java.util.Collections.singletonMap;
*/
public class PromptTemplate {
private static final PromptTemplateFactory FACTORY = ServiceHelper.loadService(
PromptTemplateFactory.class, DefaultPromptTemplateFactory::new);
private static final PromptTemplateFactory FACTORY = factory();
private static PromptTemplateFactory factory() {
for (PromptTemplateFactory factory : loadFactories(PromptTemplateFactory.class)) {
return factory;
}
return new DefaultPromptTemplateFactory();
}
static final String CURRENT_DATE = "current_date";
static final String CURRENT_TIME = "current_time";
@ -47,12 +53,24 @@ public class PromptTemplate {
/**
* Create a new PromptTemplate.
*
* @param template the template string of the prompt.
* @param clock the clock to use for the special variables.
* @param clock the clock to use for the special variables.
*/
PromptTemplate(String template, Clock clock) {
this.templateString = ensureNotBlank(template, "template");
this.template = FACTORY.create(() -> template);
this.template = FACTORY.create(new PromptTemplateFactory.Input() {
@Override
public String getTemplate() {
return template;
}
@Override
public String getName() {
return "template";
}
});
this.clock = ensureNotNull(clock, "clock");
}
@ -86,6 +104,7 @@ public class PromptTemplate {
/**
* Injects the special variables {{current_date}}, {{current_time}}, and {{current_date_time}} into the given map.
*
* @param variables the map to inject the variables into.
* @return a copy of the map with the variables injected.
*/
@ -99,6 +118,7 @@ public class PromptTemplate {
/**
* Create a new PromptTemplate.
*
* @param template the template string of the prompt.
* @return the PromptTemplate.
*/

View File

@ -1,21 +1,30 @@
package dev.langchain4j.model.input.structured;
import dev.langchain4j.model.input.Prompt;
import dev.langchain4j.spi.ServiceHelper;
import dev.langchain4j.spi.prompt.structured.StructuredPromptFactory;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
/**
* Utility class for structured prompts.
* Loads the {@link StructuredPromptFactory} SPI.
*/
public class StructuredPromptProcessor {
private StructuredPromptProcessor() {}
private StructuredPromptProcessor() {
}
private static final StructuredPromptFactory FACTORY = ServiceHelper.loadService(
StructuredPromptFactory.class, DefaultStructuredPromptFactory::new);
private static final StructuredPromptFactory FACTORY = factory();
private static StructuredPromptFactory factory() {
for (StructuredPromptFactory factory : loadFactories(StructuredPromptFactory.class)) {
return factory;
}
return new DefaultStructuredPromptFactory();
}
/**
* Converts the given structured prompt to a prompt.
*
* @param structuredPrompt the structured prompt.
* @return the prompt.
*/

View File

@ -4,8 +4,6 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.ServiceLoader;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* Utility wrapper around {@code ServiceLoader.load()}.
@ -17,53 +15,6 @@ public class ServiceHelper {
private ServiceHelper() {
}
/**
* Load a service.
*
* @param factoryClass the type of factory.
* @param defaultBuilder if no factory is found, build the service.
* @return the factory.
* @param <F> the type of factory.
*/
public static <F> F loadService(Class<F> factoryClass, Supplier<F> defaultBuilder) {
return loadFactoryService(factoryClass, f -> f, defaultBuilder);
}
/**
* Load a service provided by a service factory.
*
* @param factoryClass the type of service factory.
* @param factoryBuilder given a factory, build the service.
* @param defaultBuilder if no factory is found, build the service.
* @return the service.
* @param <F> the type of service factory.
* @param <T> the type of service.
*/
public static <F, T> T loadFactoryService(
Class<F> factoryClass, Function<F, T> factoryBuilder, Supplier<T> defaultBuilder) {
for (F factory : loadFactories(factoryClass)) {
return factoryBuilder.apply(factory);
}
return defaultBuilder.get();
}
/**
* Load a service provided by a service factory where the factory is itself a {@link Supplier}.
*
* @param factoryClass The type of service factory.
* @param defaultBuilder if no factory is found, build the service.
* @return the service.
* @param <T> the type of service.
* @param <F> the type of service factory
*/
public static <T, F extends Supplier<T>> T loadFactoryService(Class<F> factoryClass, Supplier<T> defaultBuilder) {
for (F factory : loadFactories(factoryClass)) {
return factory.get();
}
return defaultBuilder.get();
}
/**
* Load all the services of a given type.
*

View File

@ -6,43 +6,15 @@ import org.junit.jupiter.api.Test;
import java.util.Collection;
class ServiceHelperTest implements WithAssertions {
public void assertServices(Collection<ExampleService> services) {
private void assertServices(Collection<ExampleService> services) {
assertThat(services).extracting(ExampleService::getGreeting)
.containsExactlyInAnyOrder("Hello", "Goodbye");
}
@SuppressWarnings("unused")
interface ServiceWithNoProviders {
String build();
}
public static class ExampleServiceWithNoProviders implements ServiceWithNoProviders {
public String build() {
return "Hello";
}
}
@Test
public void test_loadService() {
{
// Existing Service.
ExampleService service = ServiceHelper.loadService(ExampleService.class, () -> () -> "Holla");
assertThat(service).isInstanceOfAny(ExampleServiceHello.class, ExampleServiceGoodbye.class);
assertThat(ServiceHelper.loadFactoryService(ExampleService.class, ExampleService::getGreeting, () -> "Holla"))
.isIn("Hello", "Goodbye");
}
{
// Fall back to default.
ServiceWithNoProviders service = ServiceHelper.loadService(ServiceWithNoProviders.class,
ExampleServiceWithNoProviders::new);
assertThat(service).isInstanceOf(ExampleServiceWithNoProviders.class);
assertThat(ServiceHelper.loadFactoryService(ServiceWithNoProviders.class, ServiceWithNoProviders::build, () -> "Holla"))
.isEqualTo("Holla");
}
interface NotAService {
int unused();
}
@Test
@ -50,15 +22,6 @@ class ServiceHelperTest implements WithAssertions {
assertServices(ServiceHelper.loadFactories(ExampleService.class));
assertServices(ServiceHelper.loadFactories(ExampleService.class, ServiceHelperTest.class.getClassLoader()));
assertThat(ServiceHelper.loadFactories(ServiceWithNoProviders.class)).isEmpty();
}
@Test
void test_supplierServices() {
assertThat(ServiceHelper.loadFactoryService(SupplierService.class, () -> "Not found"))
.isEqualTo("Hello world!");
assertThat(ServiceHelper.loadFactoryService(SupplierServiceNotFound.class, () -> "Not found"))
.isEqualTo("Not found");
assertThat(ServiceHelper.loadFactories(NotAService.class)).isEmpty();
}
}

View File

@ -16,13 +16,13 @@ import dev.langchain4j.internal.Utils;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.dashscope.spi.QwenChatModelBuilderFactory;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import java.util.List;
import static com.alibaba.dashscope.aigc.generation.models.QwenParam.ResultFormat.MESSAGE;
import static dev.langchain4j.model.dashscope.QwenHelper.*;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
public class QwenChatModel implements ChatLanguageModel {
private final String apiKey;
@ -137,10 +137,10 @@ public class QwenChatModel implements ChatLanguageModel {
}
public static QwenChatModelBuilder builder() {
return ServiceHelper.loadFactoryService(
QwenChatModelBuilderFactory.class,
QwenChatModelBuilder::new
);
for (QwenChatModelBuilderFactory factory : loadFactories(QwenChatModelBuilderFactory.class)) {
return factory.get();
}
return new QwenChatModelBuilder();
}
public static class QwenChatModelBuilder {

View File

@ -9,7 +9,6 @@ import dev.langchain4j.model.dashscope.spi.QwenEmbeddingModelBuilderFactory;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.model.output.TokenUsage;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import java.util.*;
@ -17,6 +16,7 @@ import java.util.stream.Collectors;
import static com.alibaba.dashscope.embeddings.TextEmbeddingParam.TextType.DOCUMENT;
import static com.alibaba.dashscope.embeddings.TextEmbeddingParam.TextType.QUERY;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.util.Collections.singletonList;
public class QwenEmbeddingModel implements EmbeddingModel {
@ -120,10 +120,10 @@ public class QwenEmbeddingModel implements EmbeddingModel {
}
public static QwenEmbeddingModelBuilder builder() {
return ServiceHelper.loadFactoryService(
QwenEmbeddingModelBuilderFactory.class,
QwenEmbeddingModelBuilder::new
);
for (QwenEmbeddingModelBuilderFactory factory : loadFactories(QwenEmbeddingModelBuilderFactory.class)) {
return factory.get();
}
return new QwenEmbeddingModelBuilder();
}
public static class QwenEmbeddingModelBuilder {

View File

@ -10,7 +10,6 @@ import dev.langchain4j.internal.Utils;
import dev.langchain4j.model.dashscope.spi.QwenLanguageModelBuilderFactory;
import dev.langchain4j.model.language.LanguageModel;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import java.util.List;
@ -19,6 +18,7 @@ import static com.alibaba.dashscope.aigc.generation.models.QwenParam.ResultForma
import static dev.langchain4j.internal.Utils.isNullOrBlank;
import static dev.langchain4j.model.dashscope.QwenHelper.*;
import static dev.langchain4j.model.dashscope.QwenModelName.QWEN_PLUS;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
public class QwenLanguageModel implements LanguageModel {
private final String apiKey;
@ -98,10 +98,10 @@ public class QwenLanguageModel implements LanguageModel {
}
public static QwenLanguageModelBuilder builder() {
return ServiceHelper.loadFactoryService(
QwenLanguageModelBuilderFactory.class,
QwenLanguageModelBuilder::new
);
for (QwenLanguageModelBuilderFactory factory : loadFactories(QwenLanguageModelBuilderFactory.class)) {
return factory.get();
}
return new QwenLanguageModelBuilder();
}
public static class QwenLanguageModelBuilder {

View File

@ -17,7 +17,6 @@ import dev.langchain4j.internal.Utils;
import dev.langchain4j.model.StreamingResponseHandler;
import dev.langchain4j.model.chat.StreamingChatLanguageModel;
import dev.langchain4j.model.dashscope.spi.QwenStreamingChatModelBuilderFactory;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import java.util.List;
@ -25,6 +24,7 @@ import java.util.List;
import static com.alibaba.dashscope.aigc.generation.models.QwenParam.ResultFormat.MESSAGE;
import static dev.langchain4j.model.dashscope.QwenHelper.toQwenMessages;
import static dev.langchain4j.model.dashscope.QwenHelper.toQwenMultiModalMessages;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
public class QwenStreamingChatModel implements StreamingChatLanguageModel {
private final String apiKey;
@ -177,10 +177,10 @@ public class QwenStreamingChatModel implements StreamingChatLanguageModel {
}
public static QwenStreamingChatModelBuilder builder() {
return ServiceHelper.loadFactoryService(
QwenStreamingChatModelBuilderFactory.class,
QwenStreamingChatModelBuilder::new
);
for (QwenStreamingChatModelBuilderFactory factory : loadFactories(QwenStreamingChatModelBuilderFactory.class)) {
return factory.get();
}
return new QwenStreamingChatModelBuilder();
}
public static class QwenStreamingChatModelBuilder {

View File

@ -13,7 +13,6 @@ import dev.langchain4j.model.StreamingResponseHandler;
import dev.langchain4j.model.dashscope.spi.QwenStreamingLanguageModelBuilderFactory;
import dev.langchain4j.model.language.StreamingLanguageModel;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import java.util.List;
@ -21,6 +20,7 @@ import java.util.List;
import static com.alibaba.dashscope.aigc.generation.models.QwenParam.ResultFormat.MESSAGE;
import static dev.langchain4j.internal.Utils.isNullOrBlank;
import static dev.langchain4j.model.dashscope.QwenModelName.QWEN_PLUS;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
public class QwenStreamingLanguageModel implements StreamingLanguageModel {
private final String apiKey;
@ -123,10 +123,10 @@ public class QwenStreamingLanguageModel implements StreamingLanguageModel {
}
public static QwenStreamingLanguageModelBuilder builder() {
return ServiceHelper.loadFactoryService(
QwenStreamingLanguageModelBuilderFactory.class,
QwenStreamingLanguageModelBuilder::new
);
for (QwenStreamingLanguageModelBuilderFactory factory : loadFactories(QwenStreamingLanguageModelBuilderFactory.class)) {
return factory.get();
}
return new QwenStreamingLanguageModelBuilder();
}
public static class QwenStreamingLanguageModelBuilder {

View File

@ -2,12 +2,19 @@ package dev.langchain4j.model.huggingface;
import dev.langchain4j.model.huggingface.client.HuggingFaceClient;
import dev.langchain4j.model.huggingface.spi.HuggingFaceClientFactory;
import dev.langchain4j.spi.ServiceHelper;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
class FactoryCreator {
static final HuggingFaceClientFactory FACTORY = ServiceHelper.loadService(
HuggingFaceClientFactory.class, DefaultHuggingFaceClientFactory::new);
static final HuggingFaceClientFactory FACTORY = factory();
private static HuggingFaceClientFactory factory() {
for (HuggingFaceClientFactory factory : loadFactories(HuggingFaceClientFactory.class)) {
return factory;
}
return new DefaultHuggingFaceClientFactory();
}
static class DefaultHuggingFaceClientFactory implements HuggingFaceClientFactory {

View File

@ -7,13 +7,13 @@ import dev.langchain4j.model.huggingface.client.*;
import dev.langchain4j.model.huggingface.spi.HuggingFaceChatModelBuilderFactory;
import dev.langchain4j.model.huggingface.spi.HuggingFaceClientFactory;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.spi.ServiceHelper;
import java.time.Duration;
import java.util.List;
import static dev.langchain4j.internal.Utils.isNullOrBlank;
import static dev.langchain4j.model.huggingface.HuggingFaceModelName.TII_UAE_FALCON_7B_INSTRUCT;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.util.stream.Collectors.joining;
public class HuggingFaceChatModel implements ChatLanguageModel {
@ -87,10 +87,10 @@ public class HuggingFaceChatModel implements ChatLanguageModel {
}
public static Builder builder() {
return ServiceHelper.loadFactoryService(
HuggingFaceChatModelBuilderFactory.class,
Builder::new
);
for (HuggingFaceChatModelBuilderFactory factory : loadFactories(HuggingFaceChatModelBuilderFactory.class)) {
return factory.get();
}
return new Builder();
}
public static final class Builder {

View File

@ -8,13 +8,13 @@ import dev.langchain4j.model.huggingface.client.HuggingFaceClient;
import dev.langchain4j.model.huggingface.spi.HuggingFaceClientFactory;
import dev.langchain4j.model.huggingface.spi.HuggingFaceEmbeddingModelBuilderFactory;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import java.time.Duration;
import java.util.List;
import static dev.langchain4j.model.huggingface.HuggingFaceModelName.SENTENCE_TRANSFORMERS_ALL_MINI_LM_L6_V2;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.util.stream.Collectors.toList;
public class HuggingFaceEmbeddingModel implements EmbeddingModel {
@ -76,10 +76,10 @@ public class HuggingFaceEmbeddingModel implements EmbeddingModel {
}
public static HuggingFaceEmbeddingModelBuilder builder() {
return ServiceHelper.loadFactoryService(
HuggingFaceEmbeddingModelBuilderFactory.class,
HuggingFaceEmbeddingModelBuilder::new
);
for (HuggingFaceEmbeddingModelBuilderFactory factory : loadFactories(HuggingFaceEmbeddingModelBuilderFactory.class)) {
return factory.get();
}
return new HuggingFaceEmbeddingModelBuilder();
}
public static class HuggingFaceEmbeddingModelBuilder {

View File

@ -5,11 +5,11 @@ import dev.langchain4j.model.huggingface.spi.HuggingFaceClientFactory;
import dev.langchain4j.model.huggingface.spi.HuggingFaceLanguageModelBuilderFactory;
import dev.langchain4j.model.language.LanguageModel;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.spi.ServiceHelper;
import java.time.Duration;
import static dev.langchain4j.model.huggingface.HuggingFaceModelName.TII_UAE_FALCON_7B_INSTRUCT;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
public class HuggingFaceLanguageModel implements LanguageModel {
@ -81,10 +81,10 @@ public class HuggingFaceLanguageModel implements LanguageModel {
}
public static Builder builder() {
return ServiceHelper.loadFactoryService(
HuggingFaceLanguageModelBuilderFactory.class,
Builder::new
);
for (HuggingFaceLanguageModelBuilderFactory factory : loadFactories(HuggingFaceLanguageModelBuilderFactory.class)) {
return factory.get();
}
return new Builder();
}
public static final class Builder {

View File

@ -9,7 +9,6 @@ import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.localai.spi.LocalAiChatModelBuilderFactory;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import java.time.Duration;
@ -18,6 +17,7 @@ import java.util.List;
import static dev.langchain4j.internal.RetryUtils.withRetry;
import static dev.langchain4j.internal.ValidationUtils.ensureNotBlank;
import static dev.langchain4j.model.openai.InternalOpenAiHelper.*;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.time.Duration.ofSeconds;
import static java.util.Collections.singletonList;
@ -110,10 +110,10 @@ public class LocalAiChatModel implements ChatLanguageModel {
}
public static LocalAiChatModelBuilder builder() {
return ServiceHelper.loadFactoryService(
LocalAiChatModelBuilderFactory.class,
LocalAiChatModelBuilder::new
);
for (LocalAiChatModelBuilderFactory factory : loadFactories(LocalAiChatModelBuilderFactory.class)) {
return factory.get();
}
return new LocalAiChatModelBuilder();
}
public static class LocalAiChatModelBuilder {

View File

@ -8,7 +8,6 @@ import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.localai.spi.LocalAiEmbeddingModelBuilderFactory;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import java.time.Duration;
@ -16,6 +15,7 @@ import java.util.List;
import static dev.langchain4j.internal.RetryUtils.withRetry;
import static dev.langchain4j.internal.ValidationUtils.ensureNotBlank;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.time.Duration.ofSeconds;
import static java.util.stream.Collectors.toList;
@ -75,10 +75,10 @@ public class LocalAiEmbeddingModel implements EmbeddingModel {
}
public static LocalAiEmbeddingModelBuilder builder() {
return ServiceHelper.loadFactoryService(
LocalAiEmbeddingModelBuilderFactory.class,
LocalAiEmbeddingModelBuilder::new
);
for (LocalAiEmbeddingModelBuilderFactory factory : loadFactories(LocalAiEmbeddingModelBuilderFactory.class)) {
return factory.get();
}
return new LocalAiEmbeddingModelBuilder();
}
public static class LocalAiEmbeddingModelBuilder {

View File

@ -6,7 +6,6 @@ import dev.ai4j.openai4j.completion.CompletionResponse;
import dev.langchain4j.model.language.LanguageModel;
import dev.langchain4j.model.localai.spi.LocalAiLanguageModelBuilderFactory;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import java.time.Duration;
@ -14,6 +13,7 @@ import java.time.Duration;
import static dev.langchain4j.internal.RetryUtils.withRetry;
import static dev.langchain4j.internal.ValidationUtils.ensureNotBlank;
import static dev.langchain4j.model.openai.InternalOpenAiHelper.finishReasonFrom;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.time.Duration.ofSeconds;
/**
@ -81,10 +81,10 @@ public class LocalAiLanguageModel implements LanguageModel {
}
public static LocalAiLanguageModelBuilder builder() {
return ServiceHelper.loadFactoryService(
LocalAiLanguageModelBuilderFactory.class,
LocalAiLanguageModelBuilder::new
);
for (LocalAiLanguageModelBuilderFactory factory : loadFactories(LocalAiLanguageModelBuilderFactory.class)) {
return factory.get();
}
return new LocalAiLanguageModelBuilder();
}
public static class LocalAiLanguageModelBuilder {

View File

@ -13,7 +13,6 @@ import dev.langchain4j.model.chat.StreamingChatLanguageModel;
import dev.langchain4j.model.localai.spi.LocalAiStreamingChatModelBuilderFactory;
import dev.langchain4j.model.openai.OpenAiStreamingResponseBuilder;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import java.time.Duration;
@ -22,6 +21,7 @@ import java.util.List;
import static dev.langchain4j.internal.ValidationUtils.ensureNotBlank;
import static dev.langchain4j.model.openai.InternalOpenAiHelper.toFunctions;
import static dev.langchain4j.model.openai.InternalOpenAiHelper.toOpenAiMessages;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.time.Duration.ofSeconds;
import static java.util.Collections.singletonList;
@ -131,10 +131,10 @@ public class LocalAiStreamingChatModel implements StreamingChatLanguageModel {
}
public static LocalAiStreamingChatModelBuilder builder() {
return ServiceHelper.loadFactoryService(
LocalAiStreamingChatModelBuilderFactory.class,
LocalAiStreamingChatModelBuilder::new
);
for (LocalAiStreamingChatModelBuilderFactory factory : loadFactories(LocalAiStreamingChatModelBuilderFactory.class)) {
return factory.get();
}
return new LocalAiStreamingChatModelBuilder();
}
public static class LocalAiStreamingChatModelBuilder {

View File

@ -8,12 +8,12 @@ import dev.langchain4j.model.language.StreamingLanguageModel;
import dev.langchain4j.model.localai.spi.LocalAiStreamingLanguageModelBuilderFactory;
import dev.langchain4j.model.openai.OpenAiStreamingResponseBuilder;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import java.time.Duration;
import static dev.langchain4j.internal.ValidationUtils.ensureNotBlank;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.time.Duration.ofSeconds;
/**
@ -90,10 +90,10 @@ public class LocalAiStreamingLanguageModel implements StreamingLanguageModel {
}
public static LocalAiStreamingLanguageModelBuilder builder() {
return ServiceHelper.loadFactoryService(
LocalAiStreamingLanguageModelBuilderFactory.class,
LocalAiStreamingLanguageModelBuilder::new
);
for (LocalAiStreamingLanguageModelBuilderFactory factory : loadFactories(LocalAiStreamingLanguageModelBuilderFactory.class)) {
return factory.get();
}
return new LocalAiStreamingLanguageModelBuilder();
}
public static class LocalAiStreamingLanguageModelBuilder {

View File

@ -6,7 +6,6 @@ import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.ollama.spi.OllamaChatModelBuilderFactory;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.model.output.TokenUsage;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import java.time.Duration;
@ -17,6 +16,7 @@ import static dev.langchain4j.internal.Utils.getOrDefault;
import static dev.langchain4j.internal.ValidationUtils.ensureNotBlank;
import static dev.langchain4j.internal.ValidationUtils.ensureNotEmpty;
import static dev.langchain4j.model.ollama.OllamaMessagesUtils.toOllamaMessages;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.time.Duration.ofSeconds;
/**
@ -84,10 +84,10 @@ public class OllamaChatModel implements ChatLanguageModel {
}
public static OllamaChatModelBuilder builder() {
return ServiceHelper.loadFactoryService(
OllamaChatModelBuilderFactory.class,
OllamaChatModelBuilder::new
);
for (OllamaChatModelBuilderFactory factory : loadFactories(OllamaChatModelBuilderFactory.class)) {
return factory.get();
}
return new OllamaChatModelBuilder();
}
public static class OllamaChatModelBuilder {

View File

@ -5,7 +5,6 @@ import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.ollama.spi.OllamaEmbeddingModelBuilderFactory;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import java.time.Duration;
@ -15,6 +14,7 @@ import java.util.List;
import static dev.langchain4j.internal.RetryUtils.withRetry;
import static dev.langchain4j.internal.Utils.getOrDefault;
import static dev.langchain4j.internal.ValidationUtils.ensureNotBlank;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.time.Duration.ofSeconds;
/**
@ -58,10 +58,10 @@ public class OllamaEmbeddingModel implements EmbeddingModel {
}
public static OllamaEmbeddingModelBuilder builder() {
return ServiceHelper.loadFactoryService(
OllamaEmbeddingModelBuilderFactory.class,
OllamaEmbeddingModelBuilder::new
);
for (OllamaEmbeddingModelBuilderFactory factory : loadFactories(OllamaEmbeddingModelBuilderFactory.class)) {
return factory.get();
}
return new OllamaEmbeddingModelBuilder();
}
public static class OllamaEmbeddingModelBuilder {

View File

@ -4,7 +4,6 @@ import dev.langchain4j.model.language.LanguageModel;
import dev.langchain4j.model.ollama.spi.OllamaLanguageModelBuilderFactory;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.model.output.TokenUsage;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import java.time.Duration;
@ -13,6 +12,7 @@ import java.util.List;
import static dev.langchain4j.internal.RetryUtils.withRetry;
import static dev.langchain4j.internal.Utils.getOrDefault;
import static dev.langchain4j.internal.ValidationUtils.ensureNotBlank;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.time.Duration.ofSeconds;
/**
@ -79,10 +79,10 @@ public class OllamaLanguageModel implements LanguageModel {
}
public static OllamaLanguageModelBuilder builder() {
return ServiceHelper.loadFactoryService(
OllamaLanguageModelBuilderFactory.class,
OllamaLanguageModelBuilder::new
);
for (OllamaLanguageModelBuilderFactory factory : loadFactories(OllamaLanguageModelBuilderFactory.class)) {
return factory.get();
}
return new OllamaLanguageModelBuilder();
}
public static class OllamaLanguageModelBuilder {

View File

@ -5,7 +5,6 @@ import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.model.StreamingResponseHandler;
import dev.langchain4j.model.chat.StreamingChatLanguageModel;
import dev.langchain4j.model.ollama.spi.OllamaStreamingChatModelBuilderFactory;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import java.time.Duration;
@ -15,6 +14,7 @@ import static dev.langchain4j.internal.Utils.getOrDefault;
import static dev.langchain4j.internal.ValidationUtils.ensureNotBlank;
import static dev.langchain4j.internal.ValidationUtils.ensureNotEmpty;
import static dev.langchain4j.model.ollama.OllamaMessagesUtils.toOllamaMessages;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.time.Duration.ofSeconds;
/**
@ -74,10 +74,10 @@ public class OllamaStreamingChatModel implements StreamingChatLanguageModel {
}
public static OllamaStreamingChatModelBuilder builder() {
return ServiceHelper.loadFactoryService(
OllamaStreamingChatModelBuilderFactory.class,
OllamaStreamingChatModelBuilder::new
);
for (OllamaStreamingChatModelBuilderFactory factory : loadFactories(OllamaStreamingChatModelBuilderFactory.class)) {
return factory.get();
}
return new OllamaStreamingChatModelBuilder();
}
public static class OllamaStreamingChatModelBuilder {

View File

@ -3,7 +3,6 @@ package dev.langchain4j.model.ollama;
import dev.langchain4j.model.StreamingResponseHandler;
import dev.langchain4j.model.language.StreamingLanguageModel;
import dev.langchain4j.model.ollama.spi.OllamaStreamingLanguageModelBuilderFactory;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import java.time.Duration;
@ -11,6 +10,7 @@ import java.util.List;
import static dev.langchain4j.internal.Utils.getOrDefault;
import static dev.langchain4j.internal.ValidationUtils.ensureNotBlank;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.time.Duration.ofSeconds;
/**
@ -68,10 +68,10 @@ public class OllamaStreamingLanguageModel implements StreamingLanguageModel {
}
public static OllamaStreamingLanguageModelBuilder builder() {
return ServiceHelper.loadFactoryService(
OllamaStreamingLanguageModelBuilderFactory.class,
OllamaStreamingLanguageModelBuilder::new
);
for (OllamaStreamingLanguageModelBuilderFactory factory : loadFactories(OllamaStreamingLanguageModelBuilderFactory.class)) {
return factory.get();
}
return new OllamaStreamingLanguageModelBuilder();
}
public static class OllamaStreamingLanguageModelBuilder {

View File

@ -11,7 +11,6 @@ import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.chat.TokenCountEstimator;
import dev.langchain4j.model.openai.spi.OpenAiChatModelBuilderFactory;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import java.net.Proxy;
@ -23,6 +22,7 @@ import static dev.langchain4j.internal.RetryUtils.withRetry;
import static dev.langchain4j.internal.Utils.getOrDefault;
import static dev.langchain4j.model.openai.InternalOpenAiHelper.*;
import static dev.langchain4j.model.openai.OpenAiModelName.GPT_3_5_TURBO;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.time.Duration.ofSeconds;
import static java.util.Collections.singletonList;
@ -164,10 +164,10 @@ public class OpenAiChatModel implements ChatLanguageModel, TokenCountEstimator {
}
public static OpenAiChatModelBuilder builder() {
return ServiceHelper.loadFactoryService(
OpenAiChatModelBuilderFactory.class,
OpenAiChatModelBuilder::new
);
for (OpenAiChatModelBuilderFactory factory : loadFactories(OpenAiChatModelBuilderFactory.class)) {
return factory.get();
}
return new OpenAiChatModelBuilder();
}
public static class OpenAiChatModelBuilder {

View File

@ -10,7 +10,6 @@ import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.embedding.TokenCountEstimator;
import dev.langchain4j.model.openai.spi.OpenAiEmbeddingModelBuilderFactory;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import java.net.Proxy;
@ -21,6 +20,7 @@ import static dev.langchain4j.internal.RetryUtils.withRetry;
import static dev.langchain4j.internal.Utils.getOrDefault;
import static dev.langchain4j.model.openai.InternalOpenAiHelper.*;
import static dev.langchain4j.model.openai.OpenAiModelName.TEXT_EMBEDDING_ADA_002;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.time.Duration.ofSeconds;
import static java.util.stream.Collectors.toList;
@ -117,10 +117,10 @@ public class OpenAiEmbeddingModel implements EmbeddingModel, TokenCountEstimator
}
public static OpenAiEmbeddingModelBuilder builder() {
return ServiceHelper.loadFactoryService(
OpenAiEmbeddingModelBuilderFactory.class,
OpenAiEmbeddingModelBuilder::new
);
for (OpenAiEmbeddingModelBuilderFactory factory : loadFactories(OpenAiEmbeddingModelBuilderFactory.class)) {
return factory.get();
}
return new OpenAiEmbeddingModelBuilder();
}
public static class OpenAiEmbeddingModelBuilder {

View File

@ -7,7 +7,6 @@ import dev.langchain4j.data.image.Image;
import dev.langchain4j.model.image.ImageModel;
import dev.langchain4j.model.openai.spi.OpenAiImageModelBuilderFactory;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import lombok.NonNull;
@ -21,6 +20,7 @@ import static dev.langchain4j.internal.RetryUtils.withRetry;
import static dev.langchain4j.internal.Utils.getOrDefault;
import static dev.langchain4j.model.openai.InternalOpenAiHelper.OPENAI_URL;
import static dev.langchain4j.model.openai.OpenAiModelName.DALL_E_2;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.time.Duration.ofSeconds;
/**
@ -123,10 +123,10 @@ public class OpenAiImageModel implements ImageModel {
}
public static OpenAiImageModelBuilder builder() {
return ServiceHelper.loadFactoryService(
OpenAiImageModelBuilderFactory.class,
OpenAiImageModelBuilder::new
);
for (OpenAiImageModelBuilderFactory factory : loadFactories(OpenAiImageModelBuilderFactory.class)) {
return factory.get();
}
return new OpenAiImageModelBuilder();
}
public static class OpenAiImageModelBuilder {

View File

@ -9,7 +9,6 @@ import dev.langchain4j.model.language.LanguageModel;
import dev.langchain4j.model.language.TokenCountEstimator;
import dev.langchain4j.model.openai.spi.OpenAiLanguageModelBuilderFactory;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import java.net.Proxy;
@ -19,6 +18,7 @@ import static dev.langchain4j.internal.RetryUtils.withRetry;
import static dev.langchain4j.internal.Utils.getOrDefault;
import static dev.langchain4j.model.openai.InternalOpenAiHelper.*;
import static dev.langchain4j.model.openai.OpenAiModelName.GPT_3_5_TURBO_INSTRUCT;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.time.Duration.ofSeconds;
/**
@ -96,10 +96,10 @@ public class OpenAiLanguageModel implements LanguageModel, TokenCountEstimator {
}
public static OpenAiLanguageModelBuilder builder() {
return ServiceHelper.loadFactoryService(
OpenAiLanguageModelBuilderFactory.class,
OpenAiLanguageModelBuilder::new
);
for (OpenAiLanguageModelBuilderFactory factory : loadFactories(OpenAiLanguageModelBuilderFactory.class)) {
return factory.get();
}
return new OpenAiLanguageModelBuilder();
}
public static class OpenAiLanguageModelBuilder {

View File

@ -9,7 +9,6 @@ import dev.langchain4j.model.moderation.Moderation;
import dev.langchain4j.model.moderation.ModerationModel;
import dev.langchain4j.model.openai.spi.OpenAiModerationModelBuilderFactory;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import java.net.Proxy;
@ -20,6 +19,7 @@ import static dev.langchain4j.internal.RetryUtils.withRetry;
import static dev.langchain4j.internal.Utils.getOrDefault;
import static dev.langchain4j.model.openai.InternalOpenAiHelper.*;
import static dev.langchain4j.model.openai.OpenAiModelName.TEXT_MODERATION_LATEST;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.time.Duration.ofSeconds;
import static java.util.Collections.singletonList;
import static java.util.stream.Collectors.toList;
@ -107,10 +107,10 @@ public class OpenAiModerationModel implements ModerationModel {
}
public static OpenAiModerationModelBuilder builder() {
return ServiceHelper.loadFactoryService(
OpenAiModerationModelBuilderFactory.class,
OpenAiModerationModelBuilder::new
);
for (OpenAiModerationModelBuilderFactory factory : loadFactories(OpenAiModerationModelBuilderFactory.class)) {
return factory.get();
}
return new OpenAiModerationModelBuilder();
}
public static class OpenAiModerationModelBuilder {

View File

@ -14,7 +14,6 @@ import dev.langchain4j.model.chat.StreamingChatLanguageModel;
import dev.langchain4j.model.chat.TokenCountEstimator;
import dev.langchain4j.model.openai.spi.OpenAiStreamingChatModelBuilderFactory;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import java.net.Proxy;
@ -26,6 +25,7 @@ import static dev.langchain4j.internal.Utils.getOrDefault;
import static dev.langchain4j.internal.Utils.isNullOrEmpty;
import static dev.langchain4j.model.openai.InternalOpenAiHelper.*;
import static dev.langchain4j.model.openai.OpenAiModelName.GPT_3_5_TURBO;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.time.Duration.ofSeconds;
import static java.util.Collections.singletonList;
@ -185,10 +185,10 @@ public class OpenAiStreamingChatModel implements StreamingChatLanguageModel, Tok
}
public static OpenAiStreamingChatModelBuilder builder() {
return ServiceHelper.loadFactoryService(
OpenAiStreamingChatModelBuilderFactory.class,
OpenAiStreamingChatModelBuilder::new
);
for (OpenAiStreamingChatModelBuilderFactory factory : loadFactories(OpenAiStreamingChatModelBuilderFactory.class)) {
return factory.get();
}
return new OpenAiStreamingChatModelBuilder();
}
public static class OpenAiStreamingChatModelBuilder {

View File

@ -9,7 +9,6 @@ import dev.langchain4j.model.language.StreamingLanguageModel;
import dev.langchain4j.model.language.TokenCountEstimator;
import dev.langchain4j.model.openai.spi.OpenAiStreamingLanguageModelBuilderFactory;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import java.net.Proxy;
@ -18,6 +17,7 @@ import java.time.Duration;
import static dev.langchain4j.internal.Utils.getOrDefault;
import static dev.langchain4j.model.openai.InternalOpenAiHelper.OPENAI_URL;
import static dev.langchain4j.model.openai.OpenAiModelName.GPT_3_5_TURBO_INSTRUCT;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.time.Duration.ofSeconds;
/**
@ -106,10 +106,10 @@ public class OpenAiStreamingLanguageModel implements StreamingLanguageModel, Tok
}
public static OpenAiStreamingLanguageModelBuilder builder() {
return ServiceHelper.loadFactoryService(
OpenAiStreamingLanguageModelBuilderFactory.class,
OpenAiStreamingLanguageModelBuilder::new
);
for (OpenAiStreamingLanguageModelBuilderFactory factory : loadFactories(OpenAiStreamingLanguageModelBuilderFactory.class)) {
return factory.get();
}
return new OpenAiStreamingLanguageModelBuilder();
}
public static class OpenAiStreamingLanguageModelBuilder {

View File

@ -9,12 +9,13 @@ import dev.langchain4j.model.output.Response;
import dev.langchain4j.model.qianfan.client.QianfanClient;
import dev.langchain4j.model.qianfan.client.chat.ChatCompletionResponse;
import dev.langchain4j.model.qianfan.spi.QianfanChatModelBuilderFactory;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import java.util.List;
import static dev.langchain4j.internal.RetryUtils.withRetry;
import static dev.langchain4j.internal.Utils.getOrDefault;
import static dev.langchain4j.model.qianfan.InternalQianfanHelper.*;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import dev.langchain4j.model.qianfan.client.chat.ChatCompletionRequest;
/**
@ -135,10 +136,10 @@ public class QianfanChatModel implements ChatLanguageModel {
public static QianfanChatModelBuilder builder() {
return ServiceHelper.loadFactoryService(
QianfanChatModelBuilderFactory.class,
QianfanChatModelBuilder::new
);
for (QianfanChatModelBuilderFactory factory : loadFactories(QianfanChatModelBuilderFactory.class)) {
return factory.get();
}
return new QianfanChatModelBuilder();
}
public static class QianfanChatModelBuilder {

View File

@ -9,12 +9,12 @@ import dev.langchain4j.model.qianfan.client.QianfanClient;
import dev.langchain4j.model.qianfan.client.embedding.EmbeddingResponse;
import dev.langchain4j.model.qianfan.client.embedding.EmbeddingRequest;
import dev.langchain4j.model.qianfan.spi.QianfanEmbeddingModelBuilderFactory;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import java.util.List;
import static dev.langchain4j.internal.RetryUtils.withRetry;
import static dev.langchain4j.internal.Utils.getOrDefault;
import static dev.langchain4j.model.qianfan.InternalQianfanHelper.*;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.util.stream.Collectors.toList;
/**
*
@ -103,10 +103,10 @@ public class QianfanEmbeddingModel implements EmbeddingModel {
}
public static QianfanEmbeddingModelBuilder builder() {
return ServiceHelper.loadFactoryService(
QianfanEmbeddingModelBuilderFactory.class,
QianfanEmbeddingModelBuilder::new
);
for (QianfanEmbeddingModelBuilderFactory factory : loadFactories(QianfanEmbeddingModelBuilderFactory.class)) {
return factory.get();
}
return new QianfanEmbeddingModelBuilder();
}
public static class QianfanEmbeddingModelBuilder {

View File

@ -9,11 +9,11 @@ import dev.langchain4j.model.qianfan.client.QianfanClient;
import dev.langchain4j.model.qianfan.client.completion.CompletionRequest;
import dev.langchain4j.model.qianfan.client.completion.CompletionResponse;
import dev.langchain4j.model.qianfan.spi.QianfanLanguageModelBuilderFactory;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import static dev.langchain4j.internal.RetryUtils.withRetry;
import static dev.langchain4j.internal.Utils.getOrDefault;
import static dev.langchain4j.model.qianfan.InternalQianfanHelper.*;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
/**
@ -102,10 +102,10 @@ public class QianfanLanguageModel implements LanguageModel {
}
public static QianfanLanguageModelBuilder builder() {
return ServiceHelper.loadFactoryService(
QianfanLanguageModelBuilderFactory.class,
QianfanLanguageModelBuilder::new
);
for (QianfanLanguageModelBuilderFactory factory : loadFactories(QianfanLanguageModelBuilderFactory.class)) {
return factory.get();
}
return new QianfanLanguageModelBuilder();
}
public static class QianfanLanguageModelBuilder {

View File

@ -14,11 +14,11 @@ import dev.langchain4j.model.qianfan.client.SyncOrAsyncOrStreaming;
import dev.langchain4j.model.qianfan.client.chat.ChatCompletionRequest;
import dev.langchain4j.model.qianfan.client.chat.ChatCompletionResponse;
import dev.langchain4j.model.qianfan.spi.QianfanStreamingChatModelBuilderFactory;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import static dev.langchain4j.model.qianfan.InternalQianfanHelper.*;
import java.util.List;
import static dev.langchain4j.internal.Utils.getOrDefault;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
/**
*
@ -145,10 +145,10 @@ public class QianfanStreamingChatModel implements StreamingChatLanguageModel {
}
public static QianfanStreamingChatModelBuilder builder() {
return ServiceHelper.loadFactoryService(
QianfanStreamingChatModelBuilderFactory.class,
QianfanStreamingChatModelBuilder::new
);
for (QianfanStreamingChatModelBuilderFactory factory : loadFactories(QianfanStreamingChatModelBuilderFactory.class)) {
return factory.get();
}
return new QianfanStreamingChatModelBuilder();
}
public static class QianfanStreamingChatModelBuilder {

View File

@ -11,9 +11,9 @@ import dev.langchain4j.model.qianfan.client.completion.CompletionRequest;
import dev.langchain4j.model.qianfan.client.SyncOrAsyncOrStreaming;
import dev.langchain4j.model.qianfan.client.completion.CompletionResponse;
import dev.langchain4j.model.qianfan.spi.QianfanStreamingLanguageModelBuilderFactory;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import static dev.langchain4j.internal.Utils.getOrDefault;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
/**
*
@ -120,10 +120,10 @@ public class QianfanStreamingLanguageModel implements StreamingLanguageModel {
}
public static QianfanStreamingLanguageModelBuilder builder() {
return ServiceHelper.loadFactoryService(
QianfanStreamingLanguageModelBuilderFactory.class,
QianfanStreamingLanguageModelBuilder::new
);
for (QianfanStreamingLanguageModelBuilderFactory factory : loadFactories(QianfanStreamingLanguageModelBuilderFactory.class)) {
return factory.get();
}
return new QianfanStreamingLanguageModelBuilder();
}
public static class QianfanStreamingLanguageModelBuilder {

View File

@ -11,7 +11,6 @@ import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.model.vertexai.spi.VertexAiGeminiChatModelBuilderFactory;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import java.io.IOException;
@ -21,6 +20,7 @@ import static dev.langchain4j.internal.RetryUtils.withRetry;
import static dev.langchain4j.internal.Utils.getOrDefault;
import static dev.langchain4j.internal.ValidationUtils.ensureNotBlank;
import static dev.langchain4j.internal.ValidationUtils.ensureNotNull;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
/**
* Represents a Google Vertex AI Gemini language model with a chat completion interface, such as gemini-pro.
@ -114,10 +114,10 @@ public class VertexAiGeminiChatModel implements ChatLanguageModel {
}
public static VertexAiGeminiChatModelBuilder builder() {
return ServiceHelper.loadFactoryService(
VertexAiGeminiChatModelBuilderFactory.class,
VertexAiGeminiChatModelBuilder::new
);
for (VertexAiGeminiChatModelBuilderFactory factory : loadFactories(VertexAiGeminiChatModelBuilderFactory.class)) {
return factory.get();
}
return new VertexAiGeminiChatModelBuilder();
}
public static class VertexAiGeminiChatModelBuilder {

View File

@ -10,7 +10,6 @@ import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.model.StreamingResponseHandler;
import dev.langchain4j.model.chat.StreamingChatLanguageModel;
import dev.langchain4j.model.vertexai.spi.VertexAiGeminiStreamingChatModelBuilderFactory;
import dev.langchain4j.spi.ServiceHelper;
import lombok.Builder;
import java.io.IOException;
@ -18,6 +17,7 @@ import java.util.List;
import static dev.langchain4j.internal.ValidationUtils.ensureNotBlank;
import static dev.langchain4j.internal.ValidationUtils.ensureNotNull;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
/**
* Represents a Google Vertex AI Gemini language model with a stream chat completion interface, such as gemini-pro.
@ -87,10 +87,10 @@ public class VertexAiGeminiStreamingChatModel implements StreamingChatLanguageMo
}
public static VertexAiGeminiStreamingChatModelBuilder builder() {
return ServiceHelper.loadFactoryService(
VertexAiGeminiStreamingChatModelBuilderFactory.class,
VertexAiGeminiStreamingChatModelBuilder::new
);
for (VertexAiGeminiStreamingChatModelBuilderFactory factory : loadFactories(VertexAiGeminiStreamingChatModelBuilderFactory.class)) {
return factory.get();
}
return new VertexAiGeminiStreamingChatModelBuilder();
}
public static class VertexAiGeminiStreamingChatModelBuilder {

View File

@ -12,7 +12,6 @@ import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.model.output.TokenUsage;
import dev.langchain4j.model.vertexai.spi.VertexAiChatModelBuilderFactory;
import dev.langchain4j.spi.ServiceHelper;
import java.io.IOException;
import java.util.List;
@ -22,6 +21,7 @@ import static dev.langchain4j.data.message.ChatMessageType.*;
import static dev.langchain4j.internal.Json.toJson;
import static dev.langchain4j.internal.RetryUtils.withRetry;
import static dev.langchain4j.internal.ValidationUtils.ensureNotBlank;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.util.Collections.singletonList;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
@ -152,10 +152,10 @@ public class VertexAiChatModel implements ChatLanguageModel {
}
public static Builder builder() {
return ServiceHelper.loadFactoryService(
VertexAiChatModelBuilderFactory.class,
Builder::new
);
for (VertexAiChatModelBuilderFactory factory : loadFactories(VertexAiChatModelBuilderFactory.class)) {
return factory.get();
}
return new Builder();
}
public static class Builder {

View File

@ -12,7 +12,6 @@ import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.model.output.TokenUsage;
import dev.langchain4j.model.vertexai.spi.VertexAiEmbeddingModelBuilderFactory;
import dev.langchain4j.spi.ServiceHelper;
import java.io.IOException;
import java.util.ArrayList;
@ -23,6 +22,7 @@ import static dev.langchain4j.internal.Json.toJson;
import static dev.langchain4j.internal.RetryUtils.withRetry;
import static dev.langchain4j.internal.Utils.getOrDefault;
import static dev.langchain4j.internal.ValidationUtils.ensureNotBlank;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.util.stream.Collectors.toList;
/**
@ -143,10 +143,10 @@ public class VertexAiEmbeddingModel implements EmbeddingModel {
}
public static Builder builder() {
return ServiceHelper.loadFactoryService(
VertexAiEmbeddingModelBuilderFactory.class,
Builder::new
);
for (VertexAiEmbeddingModelBuilderFactory factory : loadFactories(VertexAiEmbeddingModelBuilderFactory.class)) {
return factory.get();
}
return new Builder();
}
public static class Builder {

View File

@ -11,7 +11,6 @@ import dev.langchain4j.data.image.Image;
import dev.langchain4j.model.image.ImageModel;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.model.vertexai.spi.VertexAiImageModelBuilderFactory;
import dev.langchain4j.spi.ServiceHelper;
import java.io.IOException;
import java.net.URI;
@ -28,6 +27,7 @@ import static dev.langchain4j.internal.Json.toJson;
import static dev.langchain4j.internal.RetryUtils.withRetry;
import static dev.langchain4j.internal.ValidationUtils.ensureBetween;
import static dev.langchain4j.internal.ValidationUtils.ensureNotBlank;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.util.Collections.singletonList;
/**
@ -282,10 +282,10 @@ public class VertexAiImageModel implements ImageModel {
}
public static Builder builder() {
return ServiceHelper.loadFactoryService(
VertexAiImageModelBuilderFactory.class,
Builder::new
);
for (VertexAiImageModelBuilderFactory factory : loadFactories(VertexAiImageModelBuilderFactory.class)) {
return factory.get();
}
return new Builder();
}
public static class Builder {

View File

@ -10,7 +10,6 @@ import dev.langchain4j.model.language.LanguageModel;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.model.output.TokenUsage;
import dev.langchain4j.model.vertexai.spi.VertexAiLanguageModelBuilderFactory;
import dev.langchain4j.spi.ServiceHelper;
import java.io.IOException;
import java.util.List;
@ -20,6 +19,7 @@ import static dev.langchain4j.internal.Json.toJson;
import static dev.langchain4j.internal.RetryUtils.withRetry;
import static dev.langchain4j.internal.ValidationUtils.ensureNotBlank;
import static dev.langchain4j.model.vertexai.VertexAiChatModel.extractTokenCount;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.util.Collections.singletonList;
/**
@ -111,10 +111,10 @@ public class VertexAiLanguageModel implements LanguageModel {
}
public static Builder builder() {
return ServiceHelper.loadFactoryService(
VertexAiLanguageModelBuilderFactory.class,
Builder::new
);
for (VertexAiLanguageModelBuilderFactory factory : loadFactories(VertexAiLanguageModelBuilderFactory.class)) {
return factory.get();
}
return new Builder();
}
public static class Builder {

View File

@ -14,12 +14,11 @@ import dev.langchain4j.model.chat.StreamingChatLanguageModel;
import dev.langchain4j.model.input.structured.StructuredPrompt;
import dev.langchain4j.model.moderation.Moderation;
import dev.langchain4j.model.moderation.ModerationModel;
import dev.langchain4j.rag.content.retriever.ContentRetriever;
import dev.langchain4j.rag.DefaultRetrievalAugmentor;
import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever;
import dev.langchain4j.rag.RetrievalAugmentor;
import dev.langchain4j.rag.content.retriever.ContentRetriever;
import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever;
import dev.langchain4j.retriever.Retriever;
import dev.langchain4j.spi.ServiceHelper;
import dev.langchain4j.spi.services.AiServicesFactory;
import java.lang.reflect.Method;
@ -34,6 +33,7 @@ import java.util.concurrent.Future;
import static dev.langchain4j.agent.tool.ToolSpecifications.toolSpecificationFrom;
import static dev.langchain4j.exception.IllegalConfigurationException.illegalConfiguration;
import static dev.langchain4j.internal.ValidationUtils.ensureNotNull;
import static dev.langchain4j.spi.ServiceHelper.loadFactories;
import static java.util.stream.Collectors.toList;
/**
@ -161,10 +161,10 @@ public abstract class AiServices<T> {
*/
public static <T> AiServices<T> builder(Class<T> aiService) {
AiServiceContext context = new AiServiceContext(aiService);
return ServiceHelper.loadFactoryService(
AiServicesFactory.class,
f -> f.create(context),
() -> new DefaultAiServices<>(context));
for (AiServicesFactory factory : loadFactories(AiServicesFactory.class)) {
return factory.create(context);
}
return new DefaultAiServices<>(context);
}
/**

View File

@ -2,7 +2,6 @@ package dev.langchain4j.store.embedding.inmemory;
import dev.langchain4j.data.embedding.Embedding;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.spi.ServiceHelper;
import dev.langchain4j.spi.store.embedding.inmemory.InMemoryEmbeddingStoreJsonCodecFactory;
import dev.langchain4j.store.embedding.CosineSimilarity;
import dev.langchain4j.store.embedding.EmbeddingMatch;
@ -20,6 +19,7 @@ import java.util.stream.IntStream;
import static dev.langchain4j.internal.Utils.randomUUID;
import static dev.langchain4j.internal.ValidationUtils.ensureNotBlank;
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;
import static java.util.Comparator.comparingDouble;
@ -186,9 +186,9 @@ public class InMemoryEmbeddingStore<Embedded> implements EmbeddingStore<Embedded
}
private static InMemoryEmbeddingStoreJsonCodec loadCodec() {
return ServiceHelper.loadFactoryService(
InMemoryEmbeddingStoreJsonCodecFactory.class,
InMemoryEmbeddingStoreJsonCodecFactory::create,
GsonInMemoryEmbeddingStoreJsonCodec::new);
for (InMemoryEmbeddingStoreJsonCodecFactory factory : loadFactories(InMemoryEmbeddingStoreJsonCodecFactory.class)) {
return factory.create();
}
return new GsonInMemoryEmbeddingStoreJsonCodec();
}
}