Skip to content

Commit

Permalink
Make FunctionCallingOptions collections immutable
Browse files Browse the repository at this point in the history
Prevent external modification of internal state by returning unmodifiable
collections and adding defensive copies in setters and builders.

Co-authored-by: [email protected]
  • Loading branch information
Mark Pollack authored and tzolov committed Oct 23, 2024
1 parent c544d0c commit cf75640
Showing 1 changed file with 18 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package org.springframework.ai.model.function;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
Expand Down Expand Up @@ -111,14 +112,18 @@ public FunctionCallingOptionsBuilder withProxyToolCalls(Boolean proxyToolCalls)

public FunctionCallingOptionsBuilder withToolContext(Map<String, Object> context) {
Assert.notNull(context, "Tool context must not be null");
this.options.getToolContext().putAll(context);
Map<String, Object> newContext = new HashMap<>(this.options.getToolContext());
newContext.putAll(context);
this.options.setToolContext(newContext);
return this;
}

public FunctionCallingOptionsBuilder withToolContext(String key, Object value) {
Assert.notNull(key, "Key must not be null");
Assert.notNull(value, "Value must not be null");
this.options.getToolContext().put(key, value);
Map<String, Object> newContext = new HashMap<>(this.options.getToolContext());
newContext.put(key, value);
this.options.setToolContext(newContext);
return this;
}

Expand Down Expand Up @@ -158,22 +163,22 @@ public static FunctionCallingOptionsBuilder builder() {

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

public void setFunctionCallbacks(List<FunctionCallback> functionCallbacks) {
Assert.notNull(functionCallbacks, "FunctionCallbacks must not be null");
this.functionCallbacks = functionCallbacks;
this.functionCallbacks = new ArrayList<>(functionCallbacks);
}

@Override
public Set<String> getFunctions() {
return this.functions;
return Collections.unmodifiableSet(this.functions);
}

public void setFunctions(Set<String> functions) {
Assert.notNull(functions, "Functions must not be null");
this.functions = functions;
this.functions = new HashSet<>(functions);
}

@Override
Expand Down Expand Up @@ -258,11 +263,12 @@ public void setProxyToolCalls(Boolean proxyToolCalls) {
}

public Map<String, Object> getToolContext() {
return context;
return Collections.unmodifiableMap(this.context);
}

public void setToolContext(Map<String, Object> context) {
this.context = context;
Assert.notNull(context, "Context must not be null");
this.context = new HashMap<>(context);
}

@Override
Expand All @@ -271,14 +277,14 @@ public ChatOptions copy() {
.withFrequencyPenalty(this.frequencyPenalty)
.withMaxTokens(this.maxTokens)
.withPresencePenalty(this.presencePenalty)
.withStopSequences(this.stopSequences)
.withStopSequences(this.stopSequences != null ? new ArrayList<>(this.stopSequences) : null)
.withTemperature(this.temperature)
.withTopK(this.topK)
.withTopP(this.topP)
.withFunctions(this.functions)
.withFunctionCallbacks(this.functionCallbacks)
.withFunctions(new HashSet<>(this.functions))
.withFunctionCallbacks(new ArrayList<>(this.functionCallbacks))
.withProxyToolCalls(this.proxyToolCalls)
.withToolContext(this.getToolContext())
.withToolContext(new HashMap<>(this.getToolContext()))
.build();
}

Expand Down

0 comments on commit cf75640

Please sign in to comment.