Skip to content

Commit 139f09b

Browse files
Merge pull request #1126 from marttp:issue_1124
PiperOrigin-RevId: 1000745296
2 parents 4721491 + 03036c3 commit 139f09b

2 files changed

Lines changed: 116 additions & 1 deletion

File tree

‎contrib/langchain4j/src/main/java/com/google/adk/models/langchain4j/LangChain4j.java‎

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import dev.langchain4j.model.chat.ChatModel;
5858
import dev.langchain4j.model.chat.StreamingChatModel;
5959
import dev.langchain4j.model.chat.request.ChatRequest;
60+
import dev.langchain4j.model.chat.request.ChatRequestParameters;
6061
import dev.langchain4j.model.chat.request.ToolChoice;
6162
import dev.langchain4j.model.chat.request.json.JsonArraySchema;
6263
import dev.langchain4j.model.chat.request.json.JsonBooleanSchema;
@@ -100,6 +101,7 @@ public abstract class LangChain4j extends BaseLlm {
100101

101102
public abstract ObjectMapper objectMapper();
102103

104+
@Nullable
103105
public abstract String modelName();
104106

105107
@Nullable
@@ -126,7 +128,33 @@ public abstract static class Builder {
126128

127129
public abstract Builder modelName(String modelName);
128130

129-
public abstract LangChain4j build();
131+
abstract @Nullable ChatModel chatModel();
132+
133+
abstract @Nullable StreamingChatModel streamingChatModel();
134+
135+
abstract @Nullable String modelName();
136+
137+
abstract LangChain4j autoBuild();
138+
139+
public LangChain4j build() {
140+
if (modelName() == null) {
141+
String name = chatModel() == null ? null : nameOf(chatModel().defaultRequestParameters());
142+
if (name == null && streamingChatModel() != null) {
143+
name = nameOf(streamingChatModel().defaultRequestParameters());
144+
}
145+
if (name == null) {
146+
throw new IllegalStateException(
147+
"Set modelName(), or use a ChatModel or StreamingChatModel whose"
148+
+ " defaultRequestParameters() declare a model name");
149+
}
150+
modelName(name);
151+
}
152+
return autoBuild();
153+
}
154+
155+
private static @Nullable String nameOf(@Nullable ChatRequestParameters parameters) {
156+
return parameters == null ? null : parameters.modelName();
157+
}
130158
}
131159

132160
public LangChain4j(ChatModel chatModel) {

‎contrib/langchain4j/src/test/java/com/google/adk/models/langchain4j/LangChain4jTest.java‎

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package com.google.adk.models.langchain4j;
1717

1818
import static org.assertj.core.api.Assertions.*;
19+
import static org.junit.jupiter.api.Assertions.assertThrows;
1920
import static org.mockito.ArgumentMatchers.any;
2021
import static org.mockito.Mockito.*;
2122

@@ -31,6 +32,7 @@
3132
import dev.langchain4j.model.chat.ChatModel;
3233
import dev.langchain4j.model.chat.StreamingChatModel;
3334
import dev.langchain4j.model.chat.request.ChatRequest;
35+
import dev.langchain4j.model.chat.request.ChatRequestParameters;
3436
import dev.langchain4j.model.chat.request.json.JsonObjectSchema;
3537
import dev.langchain4j.model.chat.request.json.JsonStringSchema;
3638
import dev.langchain4j.model.chat.response.ChatResponse;
@@ -1145,4 +1147,89 @@ void testGenerateContentWithMalformedCharsetFallback() {
11451147

11461148
assertThat(textContent.text()).isEqualTo(textPayload);
11471149
}
1150+
1151+
@Test
1152+
@DisplayName("Should auto-detect model name from ChatModel when not explicitly set")
1153+
void testBuilderAutoDetectsModelNameFromChatModel() {
1154+
// Given
1155+
final ChatRequestParameters params = mock(ChatRequestParameters.class);
1156+
when(params.modelName()).thenReturn("auto-detected-model");
1157+
when(chatModel.defaultRequestParameters()).thenReturn(params);
1158+
1159+
// When
1160+
final LangChain4j lc4j = LangChain4j.builder().chatModel(chatModel).build();
1161+
1162+
// Then
1163+
assertThat(lc4j.modelName()).isEqualTo("auto-detected-model");
1164+
assertThat(lc4j.model()).isEqualTo("auto-detected-model");
1165+
}
1166+
1167+
@Test
1168+
@DisplayName("Should auto-detect model name from StreamingChatModel when not explicitly set")
1169+
void testBuilderAutoDetectsModelNameFromStreamingChatModel() {
1170+
// Given
1171+
final ChatRequestParameters params = mock(ChatRequestParameters.class);
1172+
when(params.modelName()).thenReturn("auto-detected-streaming-model");
1173+
when(streamingChatModel.defaultRequestParameters()).thenReturn(params);
1174+
1175+
// When
1176+
final LangChain4j lc4j = LangChain4j.builder().streamingChatModel(streamingChatModel).build();
1177+
1178+
// Then
1179+
assertThat(lc4j.modelName()).isEqualTo("auto-detected-streaming-model");
1180+
assertThat(lc4j.model()).isEqualTo("auto-detected-streaming-model");
1181+
}
1182+
1183+
@Test
1184+
@DisplayName("Should prefer explicit model name over auto-detected one")
1185+
void testBuilderPrefersExplicitModelName() {
1186+
// Given
1187+
final ChatRequestParameters params = mock(ChatRequestParameters.class);
1188+
when(params.modelName()).thenReturn("auto-detected-model");
1189+
when(chatModel.defaultRequestParameters()).thenReturn(params);
1190+
1191+
// When
1192+
final LangChain4j lc4j =
1193+
LangChain4j.builder().chatModel(chatModel).modelName("explicit-model").build();
1194+
1195+
// Then
1196+
assertThat(lc4j.modelName()).isEqualTo("explicit-model");
1197+
}
1198+
1199+
@Test
1200+
@DisplayName("Should fall back to StreamingChatModel name when ChatModel has none")
1201+
void testBuilderFallsBackToStreamingModelNameWhenChatModelHasNone() {
1202+
// Given
1203+
final ChatRequestParameters emptyParams = mock(ChatRequestParameters.class);
1204+
when(chatModel.defaultRequestParameters()).thenReturn(emptyParams);
1205+
final ChatRequestParameters streamingParams = mock(ChatRequestParameters.class);
1206+
when(streamingParams.modelName()).thenReturn("streaming-model");
1207+
when(streamingChatModel.defaultRequestParameters()).thenReturn(streamingParams);
1208+
1209+
// When
1210+
final LangChain4j lc4j =
1211+
LangChain4j.builder().chatModel(chatModel).streamingChatModel(streamingChatModel).build();
1212+
1213+
// Then
1214+
assertThat(lc4j.modelName()).isEqualTo("streaming-model");
1215+
}
1216+
1217+
@Test
1218+
@DisplayName("Should fail when no source declares a model name")
1219+
void testBuilderFailsWhenNoModelNameAvailable() {
1220+
// Given
1221+
final ChatRequestParameters emptyParams = mock(ChatRequestParameters.class);
1222+
when(chatModel.defaultRequestParameters()).thenReturn(emptyParams);
1223+
when(streamingChatModel.defaultRequestParameters()).thenReturn(emptyParams);
1224+
1225+
// When / Then
1226+
assertThrows(
1227+
IllegalStateException.class,
1228+
() ->
1229+
LangChain4j.builder()
1230+
.chatModel(chatModel)
1231+
.streamingChatModel(streamingChatModel)
1232+
.build());
1233+
assertThrows(IllegalStateException.class, () -> LangChain4j.builder().build());
1234+
}
11481235
}

0 commit comments

Comments
 (0)