Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import org.jspecify.annotations.Nullable;

Expand All @@ -96,6 +97,7 @@ public abstract class LangChain4j extends BaseLlm {

public abstract ObjectMapper objectMapper();

@Nullable
public abstract String modelName();

@Nullable
Expand All @@ -122,7 +124,32 @@ public abstract static class Builder {

public abstract Builder modelName(String modelName);

public abstract LangChain4j build();
abstract @Nullable ChatModel chatModel();

abstract @Nullable StreamingChatModel streamingChatModel();

abstract @Nullable String modelName();

abstract LangChain4j autoBuild();

public LangChain4j build() {
if (Objects.isNull(modelName())) {
// Try to extract modelName from chatModel or streamingChatModel
if (!Objects.isNull(chatModel())
&& !Objects.isNull(chatModel().defaultRequestParameters())) {
modelName(chatModel().defaultRequestParameters().modelName());
} else if (!Objects.isNull(streamingChatModel())
&& !Objects.isNull(streamingChatModel().defaultRequestParameters())) {
modelName(streamingChatModel().defaultRequestParameters().modelName());
}
}
// Up to this step, if modelName still null - Fail fast
if (modelName() == null) {
throw new IllegalStateException(
"modelName is required. Either set it explicitly via modelName() or provide a ChatModel/StreamingChatModel");
}
return autoBuild();
}
}

public LangChain4j(ChatModel chatModel) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.chat.StreamingChatModel;
import dev.langchain4j.model.chat.request.ChatRequest;
import dev.langchain4j.model.chat.request.ChatRequestParameters;
import dev.langchain4j.model.chat.request.json.JsonObjectSchema;
import dev.langchain4j.model.chat.request.json.JsonStringSchema;
import dev.langchain4j.model.chat.response.ChatResponse;
Expand Down Expand Up @@ -993,4 +994,52 @@ void testGenerateContentWithNullAiMessageText() {
assertThat(response.content()).isPresent();
assertThat(response.content().get().parts().orElse(List.of())).isEmpty();
}

@Test
@DisplayName("Should auto-detect model name from ChatModel when not explicitly set")
void testBuilderAutoDetectsModelNameFromChatModel() {
// Given
final ChatRequestParameters params = mock(ChatRequestParameters.class);
when(params.modelName()).thenReturn("auto-detected-model");
when(chatModel.defaultRequestParameters()).thenReturn(params);

// When
final LangChain4j lc4j = LangChain4j.builder().chatModel(chatModel).build();

// Then
assertThat(lc4j.modelName()).isEqualTo("auto-detected-model");
assertThat(lc4j.model()).isEqualTo("auto-detected-model");
}

@Test
@DisplayName("Should auto-detect model name from StreamingChatModel when not explicitly set")
void testBuilderAutoDetectsModelNameFromStreamingChatModel() {
// Given
final ChatRequestParameters params = mock(ChatRequestParameters.class);
when(params.modelName()).thenReturn("auto-detected-streaming-model");
when(streamingChatModel.defaultRequestParameters()).thenReturn(params);

// When
final LangChain4j lc4j = LangChain4j.builder().streamingChatModel(streamingChatModel).build();

// Then
assertThat(lc4j.modelName()).isEqualTo("auto-detected-streaming-model");
assertThat(lc4j.model()).isEqualTo("auto-detected-streaming-model");
}

@Test
@DisplayName("Should prefer explicit model name over auto-detected one")
void testBuilderPrefersExplicitModelName() {
// Given
final ChatRequestParameters params = mock(ChatRequestParameters.class);
when(params.modelName()).thenReturn("auto-detected-model");
when(chatModel.defaultRequestParameters()).thenReturn(params);

// When
final LangChain4j lc4j =
LangChain4j.builder().chatModel(chatModel).modelName("explicit-model").build();

// Then
assertThat(lc4j.modelName()).isEqualTo("explicit-model");
}
}