Refactor WatsonxAiChatOptions builder methods
- Refactor the builder methods to remove `with` as the prefix. - Introduce new methods with updated naming conventions. - Deprecate the existing `with*` methods to maintain backward compatibility. - Update WatsonxAi documentation
This commit is contained in:
committed by
Ilayaperumal Gopinathan
parent
1d38fd11fd
commit
eccf33a6ec
@@ -49,6 +49,7 @@ import org.springframework.util.Assert;
|
||||
* @author Pablo Sanchidrian Herrera
|
||||
* @author John Jario Moreno Rojas
|
||||
* @author Christian Tzolov
|
||||
* @author Alexandros Pappas
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class WatsonxAiChatModel implements ChatModel, StreamingChatModel {
|
||||
@@ -60,14 +61,14 @@ public class WatsonxAiChatModel implements ChatModel, StreamingChatModel {
|
||||
public WatsonxAiChatModel(WatsonxAiApi watsonxAiApi) {
|
||||
this(watsonxAiApi,
|
||||
WatsonxAiChatOptions.builder()
|
||||
.withTemperature(0.7)
|
||||
.withTopP(1.0)
|
||||
.withTopK(50)
|
||||
.withDecodingMethod("greedy")
|
||||
.withMaxNewTokens(20)
|
||||
.withMinNewTokens(0)
|
||||
.withRepetitionPenalty(1.0)
|
||||
.withStopSequences(List.of())
|
||||
.temperature(0.7)
|
||||
.topP(1.0)
|
||||
.topK(50)
|
||||
.decodingMethod("greedy")
|
||||
.maxNewTokens(20)
|
||||
.minNewTokens(0)
|
||||
.repetitionPenalty(1.0)
|
||||
.stopSequences(List.of())
|
||||
.build());
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ import org.springframework.ai.chat.prompt.ChatOptions;
|
||||
* @author Pablo Sanchidrian Herrera
|
||||
* @author John Jairo Moreno Rojas
|
||||
* @author Thomas Vitale
|
||||
* @author Alexandros Pappas
|
||||
* @since 1.0.0
|
||||
* @see <a href=
|
||||
* "https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/fm-model-parameters.html?context=wx&audience=wdp">watsonx.ai
|
||||
@@ -155,17 +156,17 @@ public class WatsonxAiChatOptions implements ChatOptions {
|
||||
|
||||
public static WatsonxAiChatOptions fromOptions(WatsonxAiChatOptions fromOptions) {
|
||||
return WatsonxAiChatOptions.builder()
|
||||
.withTemperature(fromOptions.getTemperature())
|
||||
.withTopP(fromOptions.getTopP())
|
||||
.withTopK(fromOptions.getTopK())
|
||||
.withDecodingMethod(fromOptions.getDecodingMethod())
|
||||
.withMaxNewTokens(fromOptions.getMaxNewTokens())
|
||||
.withMinNewTokens(fromOptions.getMinNewTokens())
|
||||
.withStopSequences(fromOptions.getStopSequences())
|
||||
.withRepetitionPenalty(fromOptions.getRepetitionPenalty())
|
||||
.withRandomSeed(fromOptions.getRandomSeed())
|
||||
.withModel(fromOptions.getModel())
|
||||
.withAdditionalProperties(fromOptions.getAdditionalProperties())
|
||||
.temperature(fromOptions.getTemperature())
|
||||
.topP(fromOptions.getTopP())
|
||||
.topK(fromOptions.getTopK())
|
||||
.decodingMethod(fromOptions.getDecodingMethod())
|
||||
.maxNewTokens(fromOptions.getMaxNewTokens())
|
||||
.minNewTokens(fromOptions.getMinNewTokens())
|
||||
.stopSequences(fromOptions.getStopSequences())
|
||||
.repetitionPenalty(fromOptions.getRepetitionPenalty())
|
||||
.randomSeed(fromOptions.getRandomSeed())
|
||||
.model(fromOptions.getModel())
|
||||
.additionalProperties(fromOptions.getAdditionalProperties())
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -326,66 +327,162 @@ public class WatsonxAiChatOptions implements ChatOptions {
|
||||
|
||||
WatsonxAiChatOptions options = new WatsonxAiChatOptions();
|
||||
|
||||
public Builder withTemperature(Double temperature) {
|
||||
public Builder temperature(Double temperature) {
|
||||
this.options.temperature = temperature;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withTopP(Double topP) {
|
||||
public Builder topP(Double topP) {
|
||||
this.options.topP = topP;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withTopK(Integer topK) {
|
||||
public Builder topK(Integer topK) {
|
||||
this.options.topK = topK;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withDecodingMethod(String decodingMethod) {
|
||||
public Builder decodingMethod(String decodingMethod) {
|
||||
this.options.decodingMethod = decodingMethod;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withMaxNewTokens(Integer maxNewTokens) {
|
||||
public Builder maxNewTokens(Integer maxNewTokens) {
|
||||
this.options.maxNewTokens = maxNewTokens;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withMinNewTokens(Integer minNewTokens) {
|
||||
public Builder minNewTokens(Integer minNewTokens) {
|
||||
this.options.minNewTokens = minNewTokens;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withStopSequences(List<String> stopSequences) {
|
||||
public Builder stopSequences(List<String> stopSequences) {
|
||||
this.options.stopSequences = stopSequences;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withRepetitionPenalty(Double repetitionPenalty) {
|
||||
public Builder repetitionPenalty(Double repetitionPenalty) {
|
||||
this.options.repetitionPenalty = repetitionPenalty;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withRandomSeed(Integer randomSeed) {
|
||||
public Builder randomSeed(Integer randomSeed) {
|
||||
this.options.randomSeed = randomSeed;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withModel(String model) {
|
||||
public Builder model(String model) {
|
||||
this.options.model = model;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withAdditionalProperty(String key, Object value) {
|
||||
public Builder additionalProperty(String key, Object value) {
|
||||
this.options.additional.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withAdditionalProperties(Map<String, Object> properties) {
|
||||
public Builder additionalProperties(Map<String, Object> properties) {
|
||||
this.options.additional.putAll(properties);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #temperature(Double)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.0.0-M5")
|
||||
public Builder withTemperature(Double temperature) {
|
||||
return temperature(temperature);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #topP(Double)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.0.0-M5")
|
||||
public Builder withTopP(Double topP) {
|
||||
return topP(topP);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #topK(Integer)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.0.0-M5")
|
||||
public Builder withTopK(Integer topK) {
|
||||
return topK(topK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #decodingMethod(String)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.0.0-M5")
|
||||
public Builder withDecodingMethod(String decodingMethod) {
|
||||
return decodingMethod(decodingMethod);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #maxNewTokens(Integer)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.0.0-M5")
|
||||
public Builder withMaxNewTokens(Integer maxNewTokens) {
|
||||
return maxNewTokens(maxNewTokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #minNewTokens(Integer)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.0.0-M5")
|
||||
public Builder withMinNewTokens(Integer minNewTokens) {
|
||||
return minNewTokens(minNewTokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #stopSequences(List)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.0.0-M5")
|
||||
public Builder withStopSequences(List<String> stopSequences) {
|
||||
return stopSequences(stopSequences);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #repetitionPenalty(Double)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.0.0-M5")
|
||||
public Builder withRepetitionPenalty(Double repetitionPenalty) {
|
||||
return repetitionPenalty(repetitionPenalty);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #randomSeed(Integer)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.0.0-M5")
|
||||
public Builder withRandomSeed(Integer randomSeed) {
|
||||
return randomSeed(randomSeed);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #model(String)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.0.0-M5")
|
||||
public Builder withModel(String model) {
|
||||
return model(model);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #additionalProperty(String, Object)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.0.0-M5")
|
||||
public Builder withAdditionalProperty(String key, Object value) {
|
||||
return additionalProperty(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #additionalProperties(Map)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.0.0-M5")
|
||||
public Builder withAdditionalProperties(Map<String, Object> properties) {
|
||||
return additionalProperties(properties);
|
||||
}
|
||||
|
||||
public WatsonxAiChatOptions build() {
|
||||
return this.options;
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ import static org.mockito.Mockito.mock;
|
||||
/**
|
||||
* @author Pablo Sanchidrian Herrera
|
||||
* @author John Jairo Moreno Rojas
|
||||
* @author Alexandros Pappas
|
||||
*/
|
||||
public class WatsonxAiChatModelTest {
|
||||
|
||||
@@ -66,9 +67,7 @@ public class WatsonxAiChatModelTest {
|
||||
|
||||
String msg = "Test message";
|
||||
|
||||
WatsonxAiChatOptions modelOptions = WatsonxAiChatOptions.builder()
|
||||
.withModel("meta-llama/llama-2-70b-chat")
|
||||
.build();
|
||||
WatsonxAiChatOptions modelOptions = WatsonxAiChatOptions.builder().model("meta-llama/llama-2-70b-chat").build();
|
||||
Prompt prompt = new Prompt(msg, modelOptions);
|
||||
|
||||
WatsonxAiChatRequest request = this.chatModel.request(prompt);
|
||||
@@ -91,16 +90,16 @@ public class WatsonxAiChatModelTest {
|
||||
String msg = "Test message";
|
||||
|
||||
WatsonxAiChatOptions modelOptions = WatsonxAiChatOptions.builder()
|
||||
.withModel("meta-llama/llama-2-70b-chat")
|
||||
.withDecodingMethod("sample")
|
||||
.withTemperature(0.1)
|
||||
.withTopP(0.2)
|
||||
.withTopK(10)
|
||||
.withMaxNewTokens(30)
|
||||
.withMinNewTokens(10)
|
||||
.withRepetitionPenalty(1.4)
|
||||
.withStopSequences(List.of("\n\n\n"))
|
||||
.withRandomSeed(4)
|
||||
.model("meta-llama/llama-2-70b-chat")
|
||||
.decodingMethod("sample")
|
||||
.temperature(0.1)
|
||||
.topP(0.2)
|
||||
.topK(10)
|
||||
.maxNewTokens(30)
|
||||
.minNewTokens(10)
|
||||
.repetitionPenalty(1.4)
|
||||
.stopSequences(List.of("\n\n\n"))
|
||||
.randomSeed(4)
|
||||
.build();
|
||||
|
||||
Prompt prompt = new Prompt(msg, modelOptions);
|
||||
@@ -125,16 +124,16 @@ public class WatsonxAiChatModelTest {
|
||||
String msg = "Test message";
|
||||
|
||||
WatsonxAiChatOptions modelOptions = WatsonxAiChatOptions.builder()
|
||||
.withModel("meta-llama/llama-2-70b-chat")
|
||||
.withDecodingMethod("sample")
|
||||
.withTemperature(0.1)
|
||||
.withTopP(0.2)
|
||||
.withTopK(10)
|
||||
.withMaxNewTokens(30)
|
||||
.withMinNewTokens(10)
|
||||
.withRepetitionPenalty(1.4)
|
||||
.withStopSequences(List.of("\n\n\n"))
|
||||
.withRandomSeed(4)
|
||||
.model("meta-llama/llama-2-70b-chat")
|
||||
.decodingMethod("sample")
|
||||
.temperature(0.1)
|
||||
.topP(0.2)
|
||||
.topK(10)
|
||||
.maxNewTokens(30)
|
||||
.minNewTokens(10)
|
||||
.repetitionPenalty(1.4)
|
||||
.stopSequences(List.of("\n\n\n"))
|
||||
.randomSeed(4)
|
||||
.build();
|
||||
|
||||
Prompt prompt = new Prompt(msg, modelOptions);
|
||||
@@ -160,9 +159,9 @@ public class WatsonxAiChatModelTest {
|
||||
WatsonxAiChatModel chatModel = new WatsonxAiChatModel(mockChatApi);
|
||||
|
||||
Prompt prompt = new Prompt(List.of(new SystemMessage("Your prompt here")),
|
||||
WatsonxAiChatOptions.builder().withModel("google/flan-ul2").build());
|
||||
WatsonxAiChatOptions.builder().model("google/flan-ul2").build());
|
||||
|
||||
WatsonxAiChatOptions parameters = WatsonxAiChatOptions.builder().withModel("google/flan-ul2").build();
|
||||
WatsonxAiChatOptions parameters = WatsonxAiChatOptions.builder().model("google/flan-ul2").build();
|
||||
|
||||
WatsonxAiChatResults fakeResults = new WatsonxAiChatResults("LLM response", 4, 3, "max_tokens");
|
||||
|
||||
@@ -193,9 +192,9 @@ public class WatsonxAiChatModelTest {
|
||||
WatsonxAiChatModel chatModel = new WatsonxAiChatModel(mockChatApi);
|
||||
|
||||
Prompt prompt = new Prompt(List.of(new SystemMessage("Your prompt here")),
|
||||
WatsonxAiChatOptions.builder().withModel("google/flan-ul2").build());
|
||||
WatsonxAiChatOptions.builder().model("google/flan-ul2").build());
|
||||
|
||||
WatsonxAiChatOptions parameters = WatsonxAiChatOptions.builder().withModel("google/flan-ul2").build();
|
||||
WatsonxAiChatOptions parameters = WatsonxAiChatOptions.builder().model("google/flan-ul2").build();
|
||||
|
||||
WatsonxAiChatResults fakeResultsFirst = new WatsonxAiChatResults("LLM resp", 0, 0, "max_tokens");
|
||||
WatsonxAiChatResults fakeResultsSecond = new WatsonxAiChatResults("onse", 4, 3, "not_finished");
|
||||
|
||||
@@ -28,21 +28,22 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
/**
|
||||
* @author Pablo Sanchidrian Herrera
|
||||
* @author John Jairo Moreno Rojas
|
||||
* @author Alexandros Pappas
|
||||
*/
|
||||
public class WatsonxAiChatOptionTest {
|
||||
|
||||
@Test
|
||||
public void testOptions() {
|
||||
WatsonxAiChatOptions options = WatsonxAiChatOptions.builder()
|
||||
.withDecodingMethod("sample")
|
||||
.withTemperature(1.2)
|
||||
.withTopK(20)
|
||||
.withTopP(0.5)
|
||||
.withMaxNewTokens(100)
|
||||
.withMinNewTokens(20)
|
||||
.withStopSequences(List.of("\n\n\n"))
|
||||
.withRepetitionPenalty(1.1)
|
||||
.withRandomSeed(4)
|
||||
.decodingMethod("sample")
|
||||
.temperature(1.2)
|
||||
.topK(20)
|
||||
.topP(0.5)
|
||||
.maxNewTokens(100)
|
||||
.minNewTokens(20)
|
||||
.stopSequences(List.of("\n\n\n"))
|
||||
.repetitionPenalty(1.1)
|
||||
.randomSeed(4)
|
||||
.build();
|
||||
|
||||
var optionsMap = options.toMap();
|
||||
@@ -61,17 +62,17 @@ public class WatsonxAiChatOptionTest {
|
||||
@Test
|
||||
public void testOptionsWithAdditionalParamsOneByOne() {
|
||||
WatsonxAiChatOptions options = WatsonxAiChatOptions.builder()
|
||||
.withDecodingMethod("sample")
|
||||
.withTemperature(1.2)
|
||||
.withTopK(20)
|
||||
.withTopP(0.5)
|
||||
.withMaxNewTokens(100)
|
||||
.withMinNewTokens(20)
|
||||
.withStopSequences(List.of("\n\n\n"))
|
||||
.withRepetitionPenalty(1.1)
|
||||
.withRandomSeed(4)
|
||||
.withAdditionalProperty("HAP", true)
|
||||
.withAdditionalProperty("typicalP", 0.5f)
|
||||
.decodingMethod("sample")
|
||||
.temperature(1.2)
|
||||
.topK(20)
|
||||
.topP(0.5)
|
||||
.maxNewTokens(100)
|
||||
.minNewTokens(20)
|
||||
.stopSequences(List.of("\n\n\n"))
|
||||
.repetitionPenalty(1.1)
|
||||
.randomSeed(4)
|
||||
.additionalProperty("HAP", true)
|
||||
.additionalProperty("typicalP", 0.5f)
|
||||
.build();
|
||||
|
||||
var optionsMap = options.toMap();
|
||||
@@ -92,16 +93,16 @@ public class WatsonxAiChatOptionTest {
|
||||
@Test
|
||||
public void testOptionsWithAdditionalParamsMap() {
|
||||
WatsonxAiChatOptions options = WatsonxAiChatOptions.builder()
|
||||
.withDecodingMethod("sample")
|
||||
.withTemperature(1.2)
|
||||
.withTopK(20)
|
||||
.withTopP(0.5)
|
||||
.withMaxNewTokens(100)
|
||||
.withMinNewTokens(20)
|
||||
.withStopSequences(List.of("\n\n\n"))
|
||||
.withRepetitionPenalty(1.1)
|
||||
.withRandomSeed(4)
|
||||
.withAdditionalProperties(Map.of("HAP", true, "typicalP", 0.5f, "test_value", "test"))
|
||||
.decodingMethod("sample")
|
||||
.temperature(1.2)
|
||||
.topK(20)
|
||||
.topP(0.5)
|
||||
.maxNewTokens(100)
|
||||
.minNewTokens(20)
|
||||
.stopSequences(List.of("\n\n\n"))
|
||||
.repetitionPenalty(1.1)
|
||||
.randomSeed(4)
|
||||
.additionalProperties(Map.of("HAP", true, "typicalP", 0.5f, "test_value", "test"))
|
||||
.build();
|
||||
|
||||
var optionsMap = options.toMap();
|
||||
@@ -122,7 +123,7 @@ public class WatsonxAiChatOptionTest {
|
||||
|
||||
@Test
|
||||
public void testFilterOut() {
|
||||
WatsonxAiChatOptions options = WatsonxAiChatOptions.builder().withModel("google/flan-ul2").build();
|
||||
WatsonxAiChatOptions options = WatsonxAiChatOptions.builder().model("google/flan-ul2").build();
|
||||
var mappedOptions = WatsonxAiChatOptions.filterNonSupportedFields(options.toMap());
|
||||
assertThat(mappedOptions).doesNotContainEntry("model", "google/flan-ul2");
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ ChatResponse response = chatModel.call(
|
||||
new Prompt(
|
||||
"Generate the names of 5 famous pirates.",
|
||||
WatsonxAiChatOptions.builder()
|
||||
.withTemperature(0.4)
|
||||
.temperature(0.4)
|
||||
.build()
|
||||
));
|
||||
----
|
||||
@@ -112,10 +112,11 @@ public class MyClass {
|
||||
|
||||
public String generate(String userInput) {
|
||||
|
||||
WatsonxAiOptions options = WatsonxAiOptions.create()
|
||||
.withModel(MODEL)
|
||||
.withDecodingMethod("sample")
|
||||
.withRandomSeed(1);
|
||||
WatsonxAiChatOptions options = WatsonxAiChatOptions.builder()
|
||||
.model(MODEL)
|
||||
.decodingMethod("sample")
|
||||
.randomSeed(1)
|
||||
.build();
|
||||
|
||||
Prompt prompt = new Prompt(new SystemMessage(userInput), options);
|
||||
|
||||
@@ -128,10 +129,11 @@ public class MyClass {
|
||||
|
||||
public String generateStream(String userInput) {
|
||||
|
||||
WatsonxAiOptions options = WatsonxAiOptions.create()
|
||||
.withModel(MODEL)
|
||||
.withDecodingMethod("greedy")
|
||||
.withRandomSeed(2);
|
||||
WatsonxAiChatOptions options = WatsonxAiChatOptions.builder()
|
||||
.model(MODEL)
|
||||
.decodingMethod("greedy")
|
||||
.randomSeed(2)
|
||||
.build();
|
||||
|
||||
Prompt prompt = new Prompt(new SystemMessage(userInput), options);
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.springframework.boot.context.properties.NestedConfigurationProperty;
|
||||
* Chat properties for Watsonx.AI Chat.
|
||||
*
|
||||
* @author Christian Tzolov
|
||||
* @author Alexandros Pappas
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@ConfigurationProperties(WatsonxAiChatProperties.CONFIG_PREFIX)
|
||||
@@ -43,15 +44,15 @@ public class WatsonxAiChatProperties {
|
||||
*/
|
||||
@NestedConfigurationProperty
|
||||
private WatsonxAiChatOptions options = WatsonxAiChatOptions.builder()
|
||||
.withModel("google/flan-ul2")
|
||||
.withTemperature(0.7)
|
||||
.withTopP(1.0)
|
||||
.withTopK(50)
|
||||
.withDecodingMethod("greedy")
|
||||
.withMaxNewTokens(20)
|
||||
.withMinNewTokens(0)
|
||||
.withRepetitionPenalty(1.0)
|
||||
.withStopSequences(List.of())
|
||||
.model("google/flan-ul2")
|
||||
.temperature(0.7)
|
||||
.topP(1.0)
|
||||
.topK(50)
|
||||
.decodingMethod("greedy")
|
||||
.maxNewTokens(20)
|
||||
.minNewTokens(0)
|
||||
.repetitionPenalty(1.0)
|
||||
.stopSequences(List.of())
|
||||
.build();
|
||||
|
||||
public boolean isEnabled() {
|
||||
|
||||
Reference in New Issue
Block a user