Skip to content

Refactor Options #406

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
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 @@ -25,14 +25,8 @@ public interface ChatOptions extends ModelOptions {

Float getTemperature();

void setTemperature(Float temperature);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removing these setters also required to remove the @Override annotations on all implementing classes. As a result the project didn't compile. Please make sure the changes you make compile before sending a PR.


Float getTopP();

void setTopP(Float topP);

Integer getTopK();

void setTopK(Integer topK);

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,47 +18,11 @@

public class ChatOptionsBuilder {

private class ChatOptionsImpl implements ChatOptions {

private Float temperature;

private Float topP;

private Integer topK;

@Override
public Float getTemperature() {
return temperature;
}
private Float temperature;

@Override
public void setTemperature(Float temperature) {
this.temperature = temperature;
}
private Float topP;

@Override
public Float getTopP() {
return topP;
}

@Override
public void setTopP(Float topP) {
this.topP = topP;
}

@Override
public Integer getTopK() {
return topK;
}

@Override
public void setTopK(Integer topK) {
this.topK = topK;
}

}

private final ChatOptionsImpl options = new ChatOptionsImpl();
private Integer topK;

private ChatOptionsBuilder() {
}
Expand All @@ -67,23 +31,65 @@ public static ChatOptionsBuilder builder() {
return new ChatOptionsBuilder();
}

/**
* Constructs a new immutable object based on the provided ChatOptions object.
* @param options The original ChatOptions object to base the new object on.
* @return ChatOptionsBuilder to construct a new ChatOptions object.
*/
public static ChatOptionsBuilder builder(ChatOptions options) {
return builder().withTopK(options.getTopK())
.withTopP(options.getTopP())
.withTemperature(options.getTemperature());
}

public ChatOptionsBuilder withTemperature(Float temperature) {
options.setTemperature(temperature);
this.temperature = temperature;
return this;
}

public ChatOptionsBuilder withTopP(Float topP) {
options.setTopP(topP);
this.topP = topP;
return this;
}

public ChatOptionsBuilder withTopK(Integer topK) {
options.setTopK(topK);
this.topK = topK;
return this;
}

public ChatOptions build() {
return options;
return new ChatOptionsImpl(this.temperature, this.topP, this.topK);
}

private class ChatOptionsImpl implements ChatOptions {

private final Float temperature;

private final Float topP;

private final Integer topK;

ChatOptionsImpl(Float temperature, Float topP, Integer topK) {
this.temperature = temperature;
this.topP = topP;
this.topK = topK;
}

@Override
public Float getTemperature() {
return temperature;
}

@Override
public Float getTopP() {
return topP;
}

@Override
public Integer getTopK() {
return topK;
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@

import java.util.List;
import java.util.Set;
import org.springframework.ai.chat.prompt.ChatOptions;

/**
* @author Christian Tzolov
*/
public interface FunctionCallingOptions {
public interface FunctionCallingOptions extends ChatOptions {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FunctionCallingOptions not extending ChatOptions was intentional in order to provide support finer grained support of what features can be opted into. Also, the code didn't compile after this change, so be sure to do a compilation of the total project before submitting a PR please.


/**
* Function Callbacks to be registered with the ChatClient. For Prompt Options the
Expand All @@ -34,33 +35,10 @@ public interface FunctionCallingOptions {
*/
List<FunctionCallback> getFunctionCallbacks();

/**
* Set the Function Callbacks to be registered with the ChatClient.
* @param functionCallbacks the Function Callbacks to be registered with the
* ChatClient.
*/
void setFunctionCallbacks(List<FunctionCallback> functionCallbacks);

/**
* @return List of function names from the ChatClient registry to be used in the next
* chat completion requests.
*/
Set<String> getFunctions();

/**
* Set the list of function names from the ChatClient registry to be used in the next
* chat completion requests.
* @param functions the list of function names from the ChatClient registry to be used
* in the next chat completion requests.
*/
void setFunctions(Set<String> functions);

/**
* @return Returns FunctionCallingOptionsBuilder to create a new instance of
* FunctionCallingOptions.
*/
public static FunctionCallingOptionsBuilder builder() {
return new FunctionCallingOptionsBuilder();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.Set;

import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.ai.chat.prompt.ChatOptionsBuilder;
import org.springframework.util.Assert;

/**
Expand All @@ -34,117 +35,155 @@
*/
public class FunctionCallingOptionsBuilder {

private final PortableFunctionCallingOptions options;
private List<FunctionCallback> functionCallbacks = new ArrayList<>();

public FunctionCallingOptionsBuilder() {
this.options = new PortableFunctionCallingOptions();
private Set<String> functions = new HashSet<>();

private ChatOptionsBuilder chatOptionsBuilder = ChatOptionsBuilder.builder();

private FunctionCallingOptionsBuilder() {
}

/**
* Creates a new {@link FunctionCallingOptionsBuilder} instance.
* @return A new instance of FunctionCallingOptionsBuilder.
*/
public static FunctionCallingOptionsBuilder builder() {
return new FunctionCallingOptionsBuilder();
}

/**
* Initializes a new {@link FunctionCallingOptionsBuilder} with settings from an
* existing {@link ChatOptions} object. This allows for creating a new
* FunctionCallingOptions object based on the settings of an existing ChatOptions
* instance.
* @param options The ChatOptions object whose settings are to be used.
* @return A FunctionCallingOptionsBuilder instance initialized with the provided
* ChatOptions settings.
*/
public static FunctionCallingOptionsBuilder builder(ChatOptions options) {
return builder().withTopK(options.getTopK())
.withTopP(options.getTopP())
.withTemperature(options.getTemperature());
}

/**
* Initializes a new {@link FunctionCallingOptionsBuilder} with settings from an
* existing {@link FunctionCallingOptions} object. This method is useful for
* transferring settings between different instances of FunctionCallingOptions,
* including function callbacks and functions.
* @param options The PortableFunctionCallingOptions object whose settings are to be
* used.
* @return A FunctionCallingOptionsBuilder instance initialized with the provided
* PortableFunctionCallingOptions settings.
*/
public static FunctionCallingOptionsBuilder builder(FunctionCallingOptions options) {
return builder().withTopK(options.getTopK())
.withTopP(options.getTopP())
.withTemperature(options.getTemperature())
.withFunctions(options.getFunctions())
.withFunctionCallbacks(options.getFunctionCallbacks());
}

public FunctionCallingOptionsBuilder withFunctionCallbacks(List<FunctionCallback> functionCallbacks) {
this.options.setFunctionCallbacks(functionCallbacks);
Assert.notNull(functionCallbacks, "FunctionCallbacks must not be null");
this.functionCallbacks.addAll(functionCallbacks);
return this;
}

public FunctionCallingOptionsBuilder withFunctionCallback(FunctionCallback functionCallback) {
Assert.notNull(functionCallback, "FunctionCallback must not be null");
this.options.getFunctionCallbacks().add(functionCallback);
this.functionCallbacks.add(functionCallback);
return this;
}

public FunctionCallingOptionsBuilder withFunctions(Set<String> functions) {
this.options.setFunctions(functions);
Assert.notNull(functions, "Functions must not be null");
this.functions.addAll(functions);
return this;
}

public FunctionCallingOptionsBuilder withFunction(String function) {
Assert.notNull(function, "Function must not be null");
this.options.getFunctions().add(function);
this.functions.add(function);
return this;
}

public FunctionCallingOptionsBuilder withTemperature(Float temperature) {
this.options.setTemperature(temperature);
this.chatOptionsBuilder.withTemperature(temperature);
return this;
}

public FunctionCallingOptionsBuilder withTopP(Float topP) {
this.options.setTopP(topP);
this.chatOptionsBuilder.withTopP(topP);
return this;
}

public FunctionCallingOptionsBuilder withTopK(Integer topK) {
this.options.setTopK(topK);
this.chatOptionsBuilder.withTopK(topK);
return this;
}

public PortableFunctionCallingOptions build() {
return this.options;
return new PortableFunctionCallingOptions(this.functions, this.functionCallbacks,
this.chatOptionsBuilder.build());
}

public static class PortableFunctionCallingOptions implements FunctionCallingOptions, ChatOptions {
public class PortableFunctionCallingOptions implements FunctionCallingOptions {

private List<FunctionCallback> functionCallbacks = new ArrayList<>();
private final List<FunctionCallback> functionCallbacks;

private Set<String> functions = new HashSet<>();
private final Set<String> functions;

private Float temperature;
private final ChatOptions options;

private Float topP;

private Integer topK;

@Override
public List<FunctionCallback> getFunctionCallbacks() {
return this.functionCallbacks;
}

@Override
public void setFunctionCallbacks(List<FunctionCallback> functionCallbacks) {
Assert.notNull(functionCallbacks, "FunctionCallbacks must not be null");
PortableFunctionCallingOptions(final Set<String> functions, final List<FunctionCallback> functionCallbacks,
ChatOptions options) {
this.functions = functions;
this.functionCallbacks = functionCallbacks;
this.options = options;
}

/**
* Retrieves a list of function callbacks. This method returns a new list
* containing all currently set function callbacks. The returned list is a copy,
* ensuring that modifications to the returned list do not affect the original
* list of function callbacks. This ensures the immutability of the collection
* exposed to the clients.
* @return An immutable list of {@link FunctionCallback} instances.
*/
@Override
public Set<String> getFunctions() {
return this.functions;
public List<FunctionCallback> getFunctionCallbacks() {
return new ArrayList<>(this.functionCallbacks);
}

/**
* Retrieves a set of functions. This method returns a new set containing all
* currently set functions. The returned set is a copy, ensuring that
* modifications to the returned set do not affect the original set of functions.
* This ensures the immutability of the collection exposed to the clients.
* @return An immutable set of String representing the functions.
*/
@Override
public void setFunctions(Set<String> functions) {
Assert.notNull(functions, "Functions must not be null");
this.functions = functions;
public Set<String> getFunctions() {
return new HashSet<>(this.functions);
}

@Override
public Float getTemperature() {
return this.temperature;
}

@Override
public void setTemperature(Float temperature) {
this.temperature = temperature;
return this.options.getTemperature();
}

@Override
public Float getTopP() {
return this.topP;
}

@Override
public void setTopP(Float topP) {
this.topP = topP;
return this.options.getTopP();
}

@Override
public Integer getTopK() {
return this.topK;
}

@Override
public void setTopK(Integer topK) {
this.topK = topK;
return this.options.getTopK();
}

}

}
}
Loading