Refactor OpenAI chat options

- Deprecate existing OpenAI chat options
 - Add the options' methods by removing the prefix "with"
   - Update the following options
    - OpenAI chat options
    - OpenAI image options
    - OpenAI moderation options
    - OpenAI embedding options
    - OpenAI audiospeech options
    - OpenAI audio transcription options
 - Update referecens and docs
 - Deprecate 'with' methods in builders
This commit is contained in:
Ilayaperumal Gopinathan
2024-12-16 10:25:17 +00:00
committed by Mark Pollack
parent c14618fe9a
commit 58efee6d90
53 changed files with 736 additions and 303 deletions

View File

@@ -79,10 +79,10 @@ public class OpenAiAudioSpeechModel implements SpeechModel, StreamingSpeechModel
public OpenAiAudioSpeechModel(OpenAiAudioApi audioApi) {
this(audioApi,
OpenAiAudioSpeechOptions.builder()
.withModel(OpenAiAudioApi.TtsModel.TTS_1.getValue())
.withResponseFormat(AudioResponseFormat.MP3)
.withVoice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY)
.withSpeed(SPEED)
.model(OpenAiAudioApi.TtsModel.TTS_1.getValue())
.responseFormat(AudioResponseFormat.MP3)
.voice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY)
.speed(SPEED)
.build());
}
@@ -189,12 +189,12 @@ public class OpenAiAudioSpeechModel implements SpeechModel, StreamingSpeechModel
private OpenAiAudioSpeechOptions merge(OpenAiAudioSpeechOptions source, OpenAiAudioSpeechOptions target) {
OpenAiAudioSpeechOptions.Builder mergedBuilder = OpenAiAudioSpeechOptions.builder();
mergedBuilder.withModel(source.getModel() != null ? source.getModel() : target.getModel());
mergedBuilder.withInput(source.getInput() != null ? source.getInput() : target.getInput());
mergedBuilder.withVoice(source.getVoice() != null ? source.getVoice() : target.getVoice());
mergedBuilder.withResponseFormat(
mergedBuilder.model(source.getModel() != null ? source.getModel() : target.getModel());
mergedBuilder.input(source.getInput() != null ? source.getInput() : target.getInput());
mergedBuilder.voice(source.getVoice() != null ? source.getVoice() : target.getVoice());
mergedBuilder.responseFormat(
source.getResponseFormat() != null ? source.getResponseFormat() : target.getResponseFormat());
mergedBuilder.withSpeed(source.getSpeed() != null ? source.getSpeed() : target.getSpeed());
mergedBuilder.speed(source.getSpeed() != null ? source.getSpeed() : target.getSpeed());
return mergedBuilder.build();
}

View File

@@ -28,6 +28,7 @@ import org.springframework.ai.openai.api.OpenAiAudioApi.SpeechRequest.Voice;
*
* @author Ahmed Yousri
* @author Hyunjoon Choi
* @author Ilayaperumal Gopinathan
* @since 1.0.0-M1
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@@ -186,26 +187,71 @@ public class OpenAiAudioSpeechOptions implements ModelOptions {
private final OpenAiAudioSpeechOptions options = new OpenAiAudioSpeechOptions();
public Builder model(String model) {
this.options.model = model;
return this;
}
public Builder input(String input) {
this.options.input = input;
return this;
}
public Builder voice(Voice voice) {
this.options.voice = voice;
return this;
}
public Builder responseFormat(AudioResponseFormat responseFormat) {
this.options.responseFormat = responseFormat;
return this;
}
public Builder speed(Float speed) {
this.options.speed = speed;
return this;
}
/**
* @deprecated use {@link #model(String)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withModel(String model) {
this.options.model = model;
return this;
}
/**
* @deprecated use {@link #input(String)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withInput(String input) {
this.options.input = input;
return this;
}
/**
* @deprecated use {@link #voice(Voice)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withVoice(Voice voice) {
this.options.voice = voice;
return this;
}
/**
* @deprecated use {@link #responseFormat(AudioResponseFormat)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withResponseFormat(AudioResponseFormat responseFormat) {
this.options.responseFormat = responseFormat;
return this;
}
/**
* @deprecated use {@link #speed(Float)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withSpeed(Float speed) {
this.options.speed = speed;
return this;

View File

@@ -63,9 +63,9 @@ public class OpenAiAudioTranscriptionModel implements Model<AudioTranscriptionPr
public OpenAiAudioTranscriptionModel(OpenAiAudioApi audioApi) {
this(audioApi,
OpenAiAudioTranscriptionOptions.builder()
.withModel(OpenAiAudioApi.WhisperModel.WHISPER_1.getValue())
.withResponseFormat(OpenAiAudioApi.TranscriptResponseFormat.JSON)
.withTemperature(0.7f)
.model(OpenAiAudioApi.WhisperModel.WHISPER_1.getValue())
.responseFormat(OpenAiAudioApi.TranscriptResponseFormat.JSON)
.temperature(0.7f)
.build());
}

View File

@@ -30,6 +30,7 @@ import org.springframework.ai.openai.api.OpenAiAudioApi.TranscriptionRequest.Gra
* @author Michael Lavelle
* @author Christian Tzolov
* @author Piotr Olaszewski
* @author Ilayaperumal Gopinathan
* @since 0.8.1
*/
@JsonInclude(Include.NON_NULL)
@@ -181,31 +182,85 @@ public class OpenAiAudioTranscriptionOptions implements AudioTranscriptionOption
this.options = options;
}
public Builder model(String model) {
this.options.model = model;
return this;
}
public Builder language(String language) {
this.options.language = language;
return this;
}
public Builder prompt(String prompt) {
this.options.prompt = prompt;
return this;
}
public Builder responseFormat(TranscriptResponseFormat responseFormat) {
this.options.responseFormat = responseFormat;
return this;
}
public Builder temperature(Float temperature) {
this.options.temperature = temperature;
return this;
}
public Builder granularityType(GranularityType granularityType) {
this.options.granularityType = granularityType;
return this;
}
/**
* @deprecated use {@link #model( String)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withModel(String model) {
this.options.model = model;
return this;
}
/**
* @deprecated use {@link #language( String)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withLanguage(String language) {
this.options.language = language;
return this;
}
/**
* @deprecated use {@link #prompt( String)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withPrompt(String prompt) {
this.options.prompt = prompt;
return this;
}
/**
* @deprecated use {@link #responseFormat( TranscriptResponseFormat)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withResponseFormat(TranscriptResponseFormat responseFormat) {
this.options.responseFormat = responseFormat;
return this;
}
/**
* @deprecated use {@link #temperature( Float)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withTemperature(Float temperature) {
this.options.temperature = temperature;
return this;
}
/**
* @deprecated use {@link #granularityType( GranularityType)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withGranularityType(GranularityType granularityType) {
this.options.granularityType = granularityType;
return this;

View File

@@ -143,8 +143,7 @@ public class OpenAiChatModel extends AbstractToolCallSupport implements ChatMode
* @throws IllegalArgumentException if openAiApi is null
*/
public OpenAiChatModel(OpenAiApi openAiApi) {
this(openAiApi,
OpenAiChatOptions.builder().withModel(OpenAiApi.DEFAULT_CHAT_MODEL).withTemperature(0.7).build());
this(openAiApi, OpenAiChatOptions.builder().model(OpenAiApi.DEFAULT_CHAT_MODEL).temperature(0.7).build());
}
/**
@@ -588,13 +587,13 @@ public class OpenAiChatModel extends AbstractToolCallSupport implements ChatMode
if (!CollectionUtils.isEmpty(enabledToolsToUse)) {
request = ModelOptionsUtils.merge(
OpenAiChatOptions.builder().withTools(this.getFunctionTools(enabledToolsToUse)).build(), request,
OpenAiChatOptions.builder().tools(this.getFunctionTools(enabledToolsToUse)).build(), request,
ChatCompletionRequest.class);
}
// Remove `streamOptions` from the request if it is not a streaming request
if (request.streamOptions() != null && !stream) {
logger.warn("Removing streamOptions from the request as it is not a streaming request!");
request = request.withStreamOptions(null);
request = request.streamOptions(null);
}
return request;

View File

@@ -220,32 +220,32 @@ public class OpenAiChatOptions implements FunctionCallingOptions {
public static OpenAiChatOptions fromOptions(OpenAiChatOptions fromOptions) {
return OpenAiChatOptions.builder()
.withModel(fromOptions.getModel())
.withFrequencyPenalty(fromOptions.getFrequencyPenalty())
.withLogitBias(fromOptions.getLogitBias())
.withLogprobs(fromOptions.getLogprobs())
.withTopLogprobs(fromOptions.getTopLogprobs())
.withMaxTokens(fromOptions.getMaxTokens())
.withMaxCompletionTokens(fromOptions.getMaxCompletionTokens())
.withN(fromOptions.getN())
.withOutputModalities(fromOptions.getOutputModalities())
.withOutputAudio(fromOptions.getOutputAudio())
.withPresencePenalty(fromOptions.getPresencePenalty())
.withResponseFormat(fromOptions.getResponseFormat())
.withStreamUsage(fromOptions.getStreamUsage())
.withSeed(fromOptions.getSeed())
.withStop(fromOptions.getStop())
.withTemperature(fromOptions.getTemperature())
.withTopP(fromOptions.getTopP())
.withTools(fromOptions.getTools())
.withToolChoice(fromOptions.getToolChoice())
.withUser(fromOptions.getUser())
.withParallelToolCalls(fromOptions.getParallelToolCalls())
.withFunctionCallbacks(fromOptions.getFunctionCallbacks())
.withFunctions(fromOptions.getFunctions())
.withHttpHeaders(fromOptions.getHttpHeaders())
.withProxyToolCalls(fromOptions.getProxyToolCalls())
.withToolContext(fromOptions.getToolContext())
.model(fromOptions.getModel())
.frequencyPenalty(fromOptions.getFrequencyPenalty())
.logitBias(fromOptions.getLogitBias())
.logprobs(fromOptions.getLogprobs())
.topLogprobs(fromOptions.getTopLogprobs())
.maxTokens(fromOptions.getMaxTokens())
.maxCompletionTokens(fromOptions.getMaxCompletionTokens())
.N(fromOptions.getN())
.outputModalities(fromOptions.getOutputModalities())
.outputAudio(fromOptions.getOutputAudio())
.presencePenalty(fromOptions.getPresencePenalty())
.responseFormat(fromOptions.getResponseFormat())
.streamUsage(fromOptions.getStreamUsage())
.seed(fromOptions.getSeed())
.stop(fromOptions.getStop())
.temperature(fromOptions.getTemperature())
.topP(fromOptions.getTopP())
.tools(fromOptions.getTools())
.toolChoice(fromOptions.getToolChoice())
.user(fromOptions.getUser())
.parallelToolCalls(fromOptions.getParallelToolCalls())
.functionCallbacks(fromOptions.getFunctionCallbacks())
.functions(fromOptions.getFunctions())
.httpHeaders(fromOptions.getHttpHeaders())
.proxyToolCalls(fromOptions.getProxyToolCalls())
.toolContext(fromOptions.getToolContext())
.build();
}
@@ -555,143 +555,402 @@ public class OpenAiChatOptions implements FunctionCallingOptions {
this.options = options;
}
public Builder model(String model) {
this.options.model = model;
return this;
}
public Builder model(OpenAiApi.ChatModel openAiChatModel) {
this.options.model = openAiChatModel.getName();
return this;
}
public Builder frequencyPenalty(Double frequencyPenalty) {
this.options.frequencyPenalty = frequencyPenalty;
return this;
}
public Builder logitBias(Map<String, Integer> logitBias) {
this.options.logitBias = logitBias;
return this;
}
public Builder logprobs(Boolean logprobs) {
this.options.logprobs = logprobs;
return this;
}
public Builder topLogprobs(Integer topLogprobs) {
this.options.topLogprobs = topLogprobs;
return this;
}
public Builder maxTokens(Integer maxTokens) {
this.options.maxTokens = maxTokens;
return this;
}
public Builder maxCompletionTokens(Integer maxCompletionTokens) {
this.options.maxCompletionTokens = maxCompletionTokens;
return this;
}
public Builder N(Integer n) {
this.options.n = n;
return this;
}
public Builder outputModalities(List<String> modalities) {
this.options.outputModalities = modalities;
return this;
}
public Builder outputAudio(AudioParameters audio) {
this.options.outputAudio = audio;
return this;
}
public Builder presencePenalty(Double presencePenalty) {
this.options.presencePenalty = presencePenalty;
return this;
}
public Builder responseFormat(ResponseFormat responseFormat) {
this.options.responseFormat = responseFormat;
return this;
}
public Builder streamUsage(boolean enableStreamUsage) {
this.options.streamOptions = (enableStreamUsage) ? StreamOptions.INCLUDE_USAGE : null;
return this;
}
public Builder seed(Integer seed) {
this.options.seed = seed;
return this;
}
public Builder stop(List<String> stop) {
this.options.stop = stop;
return this;
}
public Builder temperature(Double temperature) {
this.options.temperature = temperature;
return this;
}
public Builder topP(Double topP) {
this.options.topP = topP;
return this;
}
public Builder tools(List<OpenAiApi.FunctionTool> tools) {
this.options.tools = tools;
return this;
}
public Builder toolChoice(Object toolChoice) {
this.options.toolChoice = toolChoice;
return this;
}
public Builder user(String user) {
this.options.user = user;
return this;
}
public Builder parallelToolCalls(Boolean parallelToolCalls) {
this.options.parallelToolCalls = parallelToolCalls;
return this;
}
public Builder functionCallbacks(List<FunctionCallback> functionCallbacks) {
this.options.functionCallbacks = functionCallbacks;
return this;
}
public Builder functions(Set<String> functionNames) {
Assert.notNull(functionNames, "Function names must not be null");
this.options.functions = functionNames;
return this;
}
public Builder function(String functionName) {
Assert.hasText(functionName, "Function name must not be empty");
this.options.functions.add(functionName);
return this;
}
public Builder proxyToolCalls(Boolean proxyToolCalls) {
this.options.proxyToolCalls = proxyToolCalls;
return this;
}
public Builder httpHeaders(Map<String, String> httpHeaders) {
this.options.httpHeaders = httpHeaders;
return this;
}
public Builder toolContext(Map<String, Object> toolContext) {
if (this.options.toolContext == null) {
this.options.toolContext = toolContext;
}
else {
this.options.toolContext.putAll(toolContext);
}
return this;
}
/**
* @deprecated use {@link #model(String)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withModel(String model) {
this.options.model = model;
return this;
}
/**
* @deprecated use {@link #model(OpenAiApi.ChatModel)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withModel(OpenAiApi.ChatModel openAiChatModel) {
this.options.model = openAiChatModel.getName();
return this;
}
/**
* @deprecated use {@link #frequencyPenalty(Double)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withFrequencyPenalty(Double frequencyPenalty) {
this.options.frequencyPenalty = frequencyPenalty;
return this;
}
/**
* @deprecated use {@link #logitBias(Map)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withLogitBias(Map<String, Integer> logitBias) {
this.options.logitBias = logitBias;
return this;
}
/**
* @deprecated use {@link #logprobs(Boolean)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withLogprobs(Boolean logprobs) {
this.options.logprobs = logprobs;
return this;
}
/**
* @deprecated use {@link #topLogprobs(Integer)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withTopLogprobs(Integer topLogprobs) {
this.options.topLogprobs = topLogprobs;
return this;
}
/**
* @deprecated use {@link #maxTokens(Integer)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withMaxTokens(Integer maxTokens) {
this.options.maxTokens = maxTokens;
return this;
}
/**
* @deprecated use {@link #maxCompletionTokens(Integer)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withMaxCompletionTokens(Integer maxCompletionTokens) {
this.options.maxCompletionTokens = maxCompletionTokens;
return this;
}
/**
* @deprecated use {@link #N(Integer)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withN(Integer n) {
this.options.n = n;
return this;
}
/**
* @deprecated use {@link #outputModalities(List)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withOutputModalities(List<String> modalities) {
this.options.outputModalities = modalities;
return this;
}
/**
* @deprecated use {@link #outputAudio(AudioParameters)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withOutputAudio(AudioParameters audio) {
this.options.outputAudio = audio;
return this;
}
/**
* @deprecated use {@link #presencePenalty(Double)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withPresencePenalty(Double presencePenalty) {
this.options.presencePenalty = presencePenalty;
return this;
}
/**
* @deprecated use {@link #responseFormat(ResponseFormat)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withResponseFormat(ResponseFormat responseFormat) {
this.options.responseFormat = responseFormat;
return this;
}
/**
* @deprecated use {@link #streamUsage(boolean)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withStreamUsage(boolean enableStreamUsage) {
this.options.streamOptions = (enableStreamUsage) ? StreamOptions.INCLUDE_USAGE : null;
return this;
}
/**
* @deprecated use {@link #seed(Integer)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withSeed(Integer seed) {
this.options.seed = seed;
return this;
}
/**
* @deprecated use {@link #stop(List)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withStop(List<String> stop) {
this.options.stop = stop;
return this;
}
/**
* @deprecated use {@link #temperature(Double)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withTemperature(Double temperature) {
this.options.temperature = temperature;
return this;
}
/**
* @deprecated use {@link #topP(Double)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withTopP(Double topP) {
this.options.topP = topP;
return this;
}
/**
* @deprecated use {@link #tools(List)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withTools(List<OpenAiApi.FunctionTool> tools) {
this.options.tools = tools;
return this;
}
/**
* @deprecated use {@link #toolChoice(Object)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withToolChoice(Object toolChoice) {
this.options.toolChoice = toolChoice;
return this;
}
/**
* @deprecated use {@link #user(String)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withUser(String user) {
this.options.user = user;
return this;
}
/**
* @deprecated use {@link #parallelToolCalls(Boolean)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withParallelToolCalls(Boolean parallelToolCalls) {
this.options.parallelToolCalls = parallelToolCalls;
return this;
}
/**
* @deprecated use {@link #functionCallbacks(List)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withFunctionCallbacks(List<FunctionCallback> functionCallbacks) {
this.options.functionCallbacks = functionCallbacks;
return this;
}
/**
* @deprecated use {@link #functions(Set)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withFunctions(Set<String> functionNames) {
Assert.notNull(functionNames, "Function names must not be null");
this.options.functions = functionNames;
return this;
}
/**
* @deprecated use {@link #function(String)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withFunction(String functionName) {
Assert.hasText(functionName, "Function name must not be empty");
this.options.functions.add(functionName);
return this;
}
/**
* @deprecated use {@link #proxyToolCalls(Boolean)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withProxyToolCalls(Boolean proxyToolCalls) {
this.options.proxyToolCalls = proxyToolCalls;
return this;
}
/**
* @deprecated use {@link #httpHeaders(Map)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withHttpHeaders(Map<String, String> httpHeaders) {
this.options.httpHeaders = httpHeaders;
return this;
}
/**
* @deprecated use {@link #toolContext(Map)} instead.
*/
@Deprecated(forRemoval = true, since = "1.0.0-M5")
public Builder withToolContext(Map<String, Object> toolContext) {
if (this.options.toolContext == null) {
this.options.toolContext = toolContext;

View File

@@ -89,7 +89,7 @@ public class OpenAiEmbeddingModel extends AbstractEmbeddingModel {
*/
public OpenAiEmbeddingModel(OpenAiApi openAiApi, MetadataMode metadataMode) {
this(openAiApi, metadataMode,
OpenAiEmbeddingOptions.builder().withModel(OpenAiApi.DEFAULT_EMBEDDING_MODEL).build());
OpenAiEmbeddingOptions.builder().model(OpenAiApi.DEFAULT_EMBEDDING_MODEL).build());
}
/**
@@ -204,13 +204,13 @@ public class OpenAiEmbeddingModel extends AbstractEmbeddingModel {
return OpenAiEmbeddingOptions.builder()
// Handle portable embedding options
.withModel(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getModel(), defaultOptions.getModel()))
.withDimensions(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getDimensions(),
.model(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getModel(), defaultOptions.getModel()))
.dimensions(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getDimensions(),
defaultOptions.getDimensions()))
// Handle OpenAI specific embedding options
.withEncodingFormat(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getEncodingFormat(),
.encodingFormat(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getEncodingFormat(),
defaultOptions.getEncodingFormat()))
.withUser(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getUser(), defaultOptions.getUser()))
.user(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getUser(), defaultOptions.getUser()))
.build();
}

View File

@@ -26,6 +26,7 @@ import org.springframework.ai.embedding.EmbeddingOptions;
* OpenAI Embedding Options.
*
* @author Christian Tzolov
* @author Ilayaperumal Gopinathan
* @since 0.8.0
*/
@JsonInclude(Include.NON_NULL)
@@ -96,21 +97,53 @@ public class OpenAiEmbeddingOptions implements EmbeddingOptions {
this.options = new OpenAiEmbeddingOptions();
}
public Builder model(String model) {
this.options.setModel(model);
return this;
}
public Builder encodingFormat(String encodingFormat) {
this.options.setEncodingFormat(encodingFormat);
return this;
}
public Builder dimensions(Integer dimensions) {
this.options.dimensions = dimensions;
return this;
}
public Builder user(String user) {
this.options.setUser(user);
return this;
}
/**
* @deprecated use {@link #model(String)} instead.
*/
public Builder withModel(String model) {
this.options.setModel(model);
return this;
}
/**
* @deprecated use {@link #encodingFormat(String)} instead.
*/
public Builder withEncodingFormat(String encodingFormat) {
this.options.setEncodingFormat(encodingFormat);
return this;
}
/**
* @deprecated use {@link #dimensions(Integer)} instead.
*/
public Builder withDimensions(Integer dimensions) {
this.options.dimensions = dimensions;
return this;
}
/**
* @deprecated use {@link #user(String)} instead.
*/
public Builder withUser(String user) {
this.options.setUser(user);
return this;

View File

@@ -193,18 +193,16 @@ public class OpenAiImageModel implements ImageModel {
return OpenAiImageOptions.builder()
// Handle portable image options
.withModel(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getModel(), defaultOptions.getModel()))
.withN(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getN(), defaultOptions.getN()))
.withResponseFormat(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getResponseFormat(),
.model(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getModel(), defaultOptions.getModel()))
.N(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getN(), defaultOptions.getN()))
.responseFormat(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getResponseFormat(),
defaultOptions.getResponseFormat()))
.withWidth(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getWidth(), defaultOptions.getWidth()))
.withHeight(
ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getHeight(), defaultOptions.getHeight()))
.withStyle(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getStyle(), defaultOptions.getStyle()))
.width(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getWidth(), defaultOptions.getWidth()))
.height(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getHeight(), defaultOptions.getHeight()))
.style(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getStyle(), defaultOptions.getStyle()))
// Handle OpenAI specific image options
.withQuality(
ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getQuality(), defaultOptions.getQuality()))
.withUser(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getUser(), defaultOptions.getUser()))
.quality(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getQuality(), defaultOptions.getQuality()))
.user(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getUser(), defaultOptions.getUser()))
.build();
}

View File

@@ -242,6 +242,46 @@ public class OpenAiImageOptions implements ImageOptions {
this.options = new OpenAiImageOptions();
}
public Builder N(Integer n) {
this.options.setN(n);
return this;
}
public Builder model(String model) {
this.options.setModel(model);
return this;
}
public Builder quality(String quality) {
this.options.setQuality(quality);
return this;
}
public Builder responseFormat(String responseFormat) {
this.options.setResponseFormat(responseFormat);
return this;
}
public Builder width(Integer width) {
this.options.setWidth(width);
return this;
}
public Builder height(Integer height) {
this.options.setHeight(height);
return this;
}
public Builder style(String style) {
this.options.setStyle(style);
return this;
}
public Builder user(String user) {
this.options.setUser(user);
return this;
}
public Builder withN(Integer n) {
this.options.setN(n);
return this;

View File

@@ -173,7 +173,7 @@ public class OpenAiModerationModel implements ModerationModel {
OpenAiModerationOptions.Builder openAiModerationOptionsBuilder = OpenAiModerationOptions.builder();
// Handle portable moderation options
if (runtimeModerationOptions != null && runtimeModerationOptions.getModel() != null) {
openAiModerationOptionsBuilder.withModel(runtimeModerationOptions.getModel());
openAiModerationOptionsBuilder.model(runtimeModerationOptions.getModel());
}
return openAiModerationOptionsBuilder.build();
}

View File

@@ -26,6 +26,7 @@ import org.springframework.ai.openai.api.OpenAiModerationApi;
* OpenAI Moderation API options. OpenAiModerationOptions.java
*
* @author Ahmed Yousri
* @author Ilayaperumal Gopinathan
* @since 1.0.0
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@@ -58,6 +59,14 @@ public class OpenAiModerationOptions implements ModerationOptions {
this.options = new OpenAiModerationOptions();
}
public Builder model(String model) {
this.options.setModel(model);
return this;
}
/**
* @deprecated use {@link #model(String)} instead.
*/
public Builder withModel(String model) {
this.options.setModel(model);
return this;

View File

@@ -896,7 +896,7 @@ public class OpenAiApi {
* @param streamOptions The new stream options to use.
* @return A new {@link ChatCompletionRequest} with the specified stream options.
*/
public ChatCompletionRequest withStreamOptions(StreamOptions streamOptions) {
public ChatCompletionRequest streamOptions(StreamOptions streamOptions) {
return new ChatCompletionRequest(this.messages, this.model, this.store, this.metadata, this.frequencyPenalty, this.logitBias, this.logprobs,
this.topLogprobs, this.maxTokens, this.maxCompletionTokens, this.n, this.outputModalities, this.audioParameters, this.presencePenalty,
this.responseFormat, this.seed, this.serviceTier, this.stop, this.stream, streamOptions, this.temperature, this.topP,

View File

@@ -36,7 +36,7 @@ public class ChatCompletionRequestTests {
public void createRequestWithChatOptions() {
var client = new OpenAiChatModel(new OpenAiApi("TEST"),
OpenAiChatOptions.builder().withModel("DEFAULT_MODEL").withTemperature(66.6).build());
OpenAiChatOptions.builder().model("DEFAULT_MODEL").temperature(66.6).build());
var request = client.createRequest(new Prompt("Test message content"), false);
@@ -47,7 +47,7 @@ public class ChatCompletionRequestTests {
assertThat(request.temperature()).isEqualTo(66.6);
request = client.createRequest(new Prompt("Test message content",
OpenAiChatOptions.builder().withModel("PROMPT_MODEL").withTemperature(99.9).build()), true);
OpenAiChatOptions.builder().model("PROMPT_MODEL").temperature(99.9).build()), true);
assertThat(request.messages()).hasSize(1);
assertThat(request.stream()).isTrue();
@@ -62,12 +62,12 @@ public class ChatCompletionRequestTests {
final String TOOL_FUNCTION_NAME = "CurrentWeather";
var client = new OpenAiChatModel(new OpenAiApi("TEST"),
OpenAiChatOptions.builder().withModel("DEFAULT_MODEL").build());
OpenAiChatOptions.builder().model("DEFAULT_MODEL").build());
var request = client.createRequest(new Prompt("Test message content",
OpenAiChatOptions.builder()
.withModel("PROMPT_MODEL")
.withFunctionCallbacks(List.of(FunctionCallback.builder()
.model("PROMPT_MODEL")
.functionCallbacks(List.of(FunctionCallback.builder()
.function(TOOL_FUNCTION_NAME, new MockWeatherService())
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
@@ -93,8 +93,8 @@ public class ChatCompletionRequestTests {
var client = new OpenAiChatModel(new OpenAiApi("TEST"),
OpenAiChatOptions.builder()
.withModel("DEFAULT_MODEL")
.withFunctionCallbacks(List.of(FunctionCallback.builder()
.model("DEFAULT_MODEL")
.functionCallbacks(List.of(FunctionCallback.builder()
.function(TOOL_FUNCTION_NAME, new MockWeatherService())
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
@@ -116,8 +116,9 @@ public class ChatCompletionRequestTests {
.isNullOrEmpty();
// Explicitly enable the function
request = client.createRequest(new Prompt("Test message content",
OpenAiChatOptions.builder().withFunction(TOOL_FUNCTION_NAME).build()), false);
request = client.createRequest(
new Prompt("Test message content", OpenAiChatOptions.builder().function(TOOL_FUNCTION_NAME).build()),
false);
assertThat(request.tools()).hasSize(1);
assertThat(request.tools().get(0).getFunction().getName()).as("Explicitly enabled function")
@@ -126,7 +127,7 @@ public class ChatCompletionRequestTests {
// Override the default options function with one from the prompt
request = client.createRequest(new Prompt("Test message content",
OpenAiChatOptions.builder()
.withFunctionCallbacks(List.of(FunctionCallback.builder()
.functionCallbacks(List.of(FunctionCallback.builder()
.function(TOOL_FUNCTION_NAME, new MockWeatherService())
.description("Overridden function description")
.inputType(MockWeatherService.Request.class)

View File

@@ -60,7 +60,7 @@ public class OpenAiTestConfiguration {
@Bean
public OpenAiChatModel openAiChatModel(OpenAiApi api) {
OpenAiChatModel openAiChatModel = new OpenAiChatModel(api,
OpenAiChatOptions.builder().withModel(ChatModel.GPT_4_O_MINI).build());
OpenAiChatOptions.builder().model(ChatModel.GPT_4_O_MINI).build());
return openAiChatModel;
}

View File

@@ -37,12 +37,12 @@ public class TranscriptionRequestTests {
var client = new OpenAiAudioTranscriptionModel(new OpenAiAudioApi("TEST"),
OpenAiAudioTranscriptionOptions.builder()
.withModel("DEFAULT_MODEL")
.withResponseFormat(TranscriptResponseFormat.TEXT)
.withLanguage("en")
.withPrompt("Prompt1")
.withGranularityType(GranularityType.WORD)
.withTemperature(66.6f)
.model("DEFAULT_MODEL")
.responseFormat(TranscriptResponseFormat.TEXT)
.language("en")
.prompt("Prompt1")
.granularityType(GranularityType.WORD)
.temperature(66.6f)
.build());
var request = client.createRequest(
@@ -61,23 +61,23 @@ public class TranscriptionRequestTests {
var client = new OpenAiAudioTranscriptionModel(new OpenAiAudioApi("TEST"),
OpenAiAudioTranscriptionOptions.builder()
.withModel("DEFAULT_MODEL")
.withResponseFormat(TranscriptResponseFormat.TEXT)
.withLanguage("en")
.withPrompt("Prompt1")
.withGranularityType(GranularityType.WORD)
.withTemperature(66.6f)
.model("DEFAULT_MODEL")
.responseFormat(TranscriptResponseFormat.TEXT)
.language("en")
.prompt("Prompt1")
.granularityType(GranularityType.WORD)
.temperature(66.6f)
.build());
var request = client
.createRequest(new AudioTranscriptionPrompt(new DefaultResourceLoader().getResource("classpath:/test.png"),
OpenAiAudioTranscriptionOptions.builder()
.withModel("RUNTIME_MODEL")
.withResponseFormat(TranscriptResponseFormat.JSON)
.withLanguage("bg")
.withPrompt("Prompt2")
.withGranularityType(GranularityType.SEGMENT)
.withTemperature(99.9f)
.model("RUNTIME_MODEL")
.responseFormat(TranscriptResponseFormat.JSON)
.language("bg")
.prompt("Prompt2")
.granularityType(GranularityType.SEGMENT)
.temperature(99.9f)
.build()));
assertThat(request.model()).isEqualTo("RUNTIME_MODEL");

View File

@@ -55,10 +55,10 @@ class OpenAiSpeechModelIT extends AbstractIT {
@Test
void shouldGenerateNonEmptyMp3AudioFromSpeechPrompt() {
OpenAiAudioSpeechOptions speechOptions = OpenAiAudioSpeechOptions.builder()
.withVoice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY)
.withSpeed(SPEED)
.withResponseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3)
.withModel(OpenAiAudioApi.TtsModel.TTS_1.value)
.voice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY)
.speed(SPEED)
.responseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3)
.model(OpenAiAudioApi.TtsModel.TTS_1.value)
.build();
SpeechPrompt speechPrompt = new SpeechPrompt("Today is a wonderful day to build something people love!",
speechOptions);
@@ -73,10 +73,10 @@ class OpenAiSpeechModelIT extends AbstractIT {
@Test
void speechRateLimitTest() {
OpenAiAudioSpeechOptions speechOptions = OpenAiAudioSpeechOptions.builder()
.withVoice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY)
.withSpeed(SPEED)
.withResponseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3)
.withModel(OpenAiAudioApi.TtsModel.TTS_1.value)
.voice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY)
.speed(SPEED)
.responseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3)
.model(OpenAiAudioApi.TtsModel.TTS_1.value)
.build();
SpeechPrompt speechPrompt = new SpeechPrompt("Today is a wonderful day to build something people love!",
speechOptions);
@@ -93,10 +93,10 @@ class OpenAiSpeechModelIT extends AbstractIT {
void shouldStreamNonEmptyResponsesForValidSpeechPrompts() {
OpenAiAudioSpeechOptions speechOptions = OpenAiAudioSpeechOptions.builder()
.withVoice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY)
.withSpeed(SPEED)
.withResponseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3)
.withModel(OpenAiAudioApi.TtsModel.TTS_1.value)
.voice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY)
.speed(SPEED)
.responseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3)
.model(OpenAiAudioApi.TtsModel.TTS_1.value)
.build();
SpeechPrompt speechPrompt = new SpeechPrompt("Today is a wonderful day to build something people love!",

View File

@@ -70,10 +70,10 @@ public class OpenAiSpeechModelWithSpeechResponseMetadataTests {
prepareMock();
OpenAiAudioSpeechOptions speechOptions = OpenAiAudioSpeechOptions.builder()
.withVoice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY)
.withSpeed(SPEED)
.withResponseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3)
.withModel(OpenAiAudioApi.TtsModel.TTS_1.value)
.voice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY)
.speed(SPEED)
.responseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3)
.model(OpenAiAudioApi.TtsModel.TTS_1.value)
.build();
SpeechPrompt speechPrompt = new SpeechPrompt("Today is a wonderful day to build something people love!",

View File

@@ -42,8 +42,8 @@ class OpenAiTranscriptionModelIT extends AbstractIT {
@Test
void transcriptionTest() {
OpenAiAudioTranscriptionOptions transcriptionOptions = OpenAiAudioTranscriptionOptions.builder()
.withResponseFormat(TranscriptResponseFormat.TEXT)
.withTemperature(0f)
.responseFormat(TranscriptResponseFormat.TEXT)
.temperature(0f)
.build();
AudioTranscriptionPrompt transcriptionRequest = new AudioTranscriptionPrompt(this.audioFile,
transcriptionOptions);
@@ -57,10 +57,10 @@ class OpenAiTranscriptionModelIT extends AbstractIT {
OpenAiAudioApi.TranscriptResponseFormat responseFormat = OpenAiAudioApi.TranscriptResponseFormat.VTT;
OpenAiAudioTranscriptionOptions transcriptionOptions = OpenAiAudioTranscriptionOptions.builder()
.withLanguage("en")
.withPrompt("Ask not this, but ask that")
.withTemperature(0f)
.withResponseFormat(responseFormat)
.language("en")
.prompt("Ask not this, but ask that")
.temperature(0f)
.responseFormat(responseFormat)
.build();
AudioTranscriptionPrompt transcriptionRequest = new AudioTranscriptionPrompt(this.audioFile,
transcriptionOptions);

View File

@@ -54,7 +54,7 @@ public class OpenAiChatModeAdditionalHttpHeadersIT {
// Use the additional headers to override the Api Key.
// Mind that you have to prefix the Api Key with the "Bearer " prefix.
OpenAiChatOptions options = OpenAiChatOptions.builder()
.withHttpHeaders(Map.of("Authorization", "Bearer " + System.getenv("OPENAI_API_KEY")))
.httpHeaders(Map.of("Authorization", "Bearer " + System.getenv("OPENAI_API_KEY")))
.build();
ChatResponse response = this.openAiChatModel.call(new Prompt("Tell me a joke", options));

View File

@@ -83,8 +83,8 @@ class OpenAiChatModelFunctionCallingIT {
@Test
void functionCallTest() {
functionCallTest(OpenAiChatOptions.builder()
.withModel(OpenAiApi.ChatModel.GPT_4_O.getValue())
.withFunctionCallbacks(List.of(FunctionCallback.builder()
.model(OpenAiApi.ChatModel.GPT_4_O.getValue())
.functionCallbacks(List.of(FunctionCallback.builder()
.function("getCurrentWeather", new MockWeatherService())
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
@@ -119,13 +119,13 @@ class OpenAiChatModelFunctionCallingIT {
};
functionCallTest(OpenAiChatOptions.builder()
.withModel(OpenAiApi.ChatModel.GPT_4_O.getValue())
.withFunctionCallbacks(List.of(FunctionCallback.builder()
.model(OpenAiApi.ChatModel.GPT_4_O.getValue())
.functionCallbacks(List.of(FunctionCallback.builder()
.function("getCurrentWeather", biFunction)
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
.build()))
.withToolContext(Map.of("sessionId", "123"))
.toolContext(Map.of("sessionId", "123"))
.build());
}
@@ -146,7 +146,7 @@ class OpenAiChatModelFunctionCallingIT {
void streamFunctionCallTest() {
streamFunctionCallTest(OpenAiChatOptions.builder()
.withFunctionCallbacks(List.of((FunctionCallback.builder()
.functionCallbacks(List.of((FunctionCallback.builder()
.function("getCurrentWeather", new MockWeatherService())
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
@@ -182,12 +182,12 @@ class OpenAiChatModelFunctionCallingIT {
};
OpenAiChatOptions promptOptions = OpenAiChatOptions.builder()
.withFunctionCallbacks(List.of((FunctionCallback.builder()
.functionCallbacks(List.of((FunctionCallback.builder()
.function("getCurrentWeather", biFunction)
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
.build())))
.withToolContext(Map.of("sessionId", "123"))
.toolContext(Map.of("sessionId", "123"))
.build();
streamFunctionCallTest(promptOptions);

View File

@@ -206,7 +206,7 @@ public class OpenAiChatModelIT extends AbstractIT {
@Test
void streamingWithTokenUsage() {
var promptOptions = OpenAiChatOptions.builder().withStreamUsage(true).withSeed(1).build();
var promptOptions = OpenAiChatOptions.builder().streamUsage(true).seed(1).build();
var prompt = new Prompt("List two colors of the Polish flag. Be brief.", promptOptions);
var streamingTokenUsage = this.chatModel.stream(prompt).blockLast().getMetadata().getUsage();
@@ -335,8 +335,8 @@ public class OpenAiChatModelIT extends AbstractIT {
List<Message> messages = new ArrayList<>(List.of(userMessage));
var promptOptions = OpenAiChatOptions.builder()
.withModel(OpenAiApi.ChatModel.GPT_4_O.getValue())
.withFunctionCallbacks(List.of(FunctionCallback.builder()
.model(OpenAiApi.ChatModel.GPT_4_O.getValue())
.functionCallbacks(List.of(FunctionCallback.builder()
.function("getCurrentWeather", new MockWeatherService())
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
@@ -361,7 +361,7 @@ public class OpenAiChatModelIT extends AbstractIT {
var promptOptions = OpenAiChatOptions.builder()
// .withModel(OpenAiApi.ChatModel.GPT_4_TURBO_PREVIEW.getValue())
.withFunctionCallbacks(List.of(FunctionCallback.builder()
.functionCallbacks(List.of(FunctionCallback.builder()
.function("getCurrentWeather", new MockWeatherService())
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
@@ -394,7 +394,7 @@ public class OpenAiChatModelIT extends AbstractIT {
var promptOptions = OpenAiChatOptions.builder()
// .withModel(OpenAiApi.ChatModel.GPT_4_TURBO_PREVIEW.getValue())
.withFunctionCallbacks(List.of(FunctionCallback.builder()
.functionCallbacks(List.of(FunctionCallback.builder()
.function("getCurrentWeather", new MockWeatherService())
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
@@ -423,12 +423,12 @@ public class OpenAiChatModelIT extends AbstractIT {
var promptOptions = OpenAiChatOptions.builder()
// .withModel(OpenAiApi.ChatModel.GPT_4_TURBO_PREVIEW.getValue())
.withFunctionCallbacks(List.of(FunctionCallback.builder()
.functionCallbacks(List.of(FunctionCallback.builder()
.function("getCurrentWeather", new MockWeatherService())
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
.build()))
.withStreamUsage(true)
.streamUsage(true)
.build();
Flux<ChatResponse> response = this.streamingChatModel.stream(new Prompt(messages, promptOptions));
@@ -453,7 +453,7 @@ public class OpenAiChatModelIT extends AbstractIT {
List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData)));
var response = this.chatModel
.call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().withModel(modelName).build()));
.call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().model(modelName).build()));
logger.info(response.getResult().getOutput().getText());
assertThat(response.getResult().getOutput().getText()).containsAnyOf("bananas", "apple", "bowl", "basket",
@@ -471,7 +471,7 @@ public class OpenAiChatModelIT extends AbstractIT {
.build()));
ChatResponse response = this.chatModel
.call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().withModel(modelName).build()));
.call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().model(modelName).build()));
logger.info(response.getResult().getOutput().getText());
assertThat(response.getResult().getOutput().getText()).contains("bananas", "apple");
@@ -488,7 +488,7 @@ public class OpenAiChatModelIT extends AbstractIT {
.build()));
Flux<ChatResponse> response = this.streamingChatModel.stream(new Prompt(List.of(userMessage),
OpenAiChatOptions.builder().withModel(OpenAiApi.ChatModel.GPT_4_O.getValue()).build()));
OpenAiChatOptions.builder().model(OpenAiApi.ChatModel.GPT_4_O.getValue()).build()));
String content = response.collectList()
.block()
@@ -509,9 +509,9 @@ public class OpenAiChatModelIT extends AbstractIT {
ChatResponse response = chatModel.call(new Prompt(List.of(userMessage),
OpenAiChatOptions.builder()
.withModel(modelName)
.withOutputModalities(List.of("text", "audio"))
.withOutputAudio(new AudioParameters(Voice.ALLOY, AudioResponseFormat.WAV))
.model(modelName)
.outputModalities(List.of("text", "audio"))
.outputAudio(new AudioParameters(Voice.ALLOY, AudioResponseFormat.WAV))
.build()));
logger.info(response.getResult().getOutput().getText());
@@ -531,9 +531,9 @@ public class OpenAiChatModelIT extends AbstractIT {
assertThatThrownBy(() -> chatModel
.stream(new Prompt(List.of(userMessage),
OpenAiChatOptions.builder()
.withModel(modelName)
.withOutputModalities(List.of("text", "audio"))
.withOutputAudio(new AudioParameters(Voice.ALLOY, AudioResponseFormat.WAV))
.model(modelName)
.outputModalities(List.of("text", "audio"))
.outputAudio(new AudioParameters(Voice.ALLOY, AudioResponseFormat.WAV))
.build()))
.collectList()
.block()).isInstanceOf(IllegalArgumentException.class)
@@ -563,7 +563,7 @@ public class OpenAiChatModelIT extends AbstractIT {
List.of(new Media(MimeTypeUtils.parseMimeType("audio/mp3"), audioResource)));
Flux<ChatResponse> response = chatModel
.stream(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().withModel(modelName).build()));
.stream(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().model(modelName).build()));
String content = response.collectList()
.block()
@@ -582,7 +582,7 @@ public class OpenAiChatModelIT extends AbstractIT {
String model = OpenAiApi.ChatModel.GPT_3_5_TURBO.getName();
// @formatter:off
ChatResponse response = ChatClient.create(this.chatModel).prompt()
.options(OpenAiChatOptions.builder().withModel(model).build())
.options(OpenAiChatOptions.builder().model(model).build())
.user("Tell me about 3 famous pirates from the Golden Age of Piracy and what they did")
.call()
.chatResponse();

View File

@@ -70,13 +70,13 @@ public class OpenAiChatModelObservationIT {
void observationForChatOperation() {
var options = OpenAiChatOptions.builder()
.withModel(OpenAiApi.ChatModel.GPT_4_O_MINI.getValue())
.withFrequencyPenalty(0.0)
.withMaxTokens(2048)
.withPresencePenalty(0.0)
.withStop(List.of("this-is-the-end"))
.withTemperature(0.7)
.withTopP(1.0)
.model(OpenAiApi.ChatModel.GPT_4_O_MINI.getValue())
.frequencyPenalty(0.0)
.maxTokens(2048)
.presencePenalty(0.0)
.stop(List.of("this-is-the-end"))
.temperature(0.7)
.topP(1.0)
.build();
Prompt prompt = new Prompt("Why does a raven look like a desk?", options);
@@ -93,14 +93,14 @@ public class OpenAiChatModelObservationIT {
@Test
void observationForStreamingChatOperation() {
var options = OpenAiChatOptions.builder()
.withModel(OpenAiApi.ChatModel.GPT_4_O_MINI.getValue())
.withFrequencyPenalty(0.0)
.withMaxTokens(2048)
.withPresencePenalty(0.0)
.withStop(List.of("this-is-the-end"))
.withTemperature(0.7)
.withTopP(1.0)
.withStreamUsage(true)
.model(OpenAiApi.ChatModel.GPT_4_O_MINI.getValue())
.frequencyPenalty(0.0)
.maxTokens(2048)
.presencePenalty(0.0)
.stop(List.of("this-is-the-end"))
.temperature(0.7)
.topP(1.0)
.streamUsage(true)
.build();
Prompt prompt = new Prompt("Why does a raven look like a desk?", options);

View File

@@ -123,7 +123,7 @@ class OpenAiChatModelProxyToolCallsIT {
List<Message> messages = List
.of(new UserMessage("What's the weather like in San Francisco, Tokyo, and Paris?"));
var promptOptions = OpenAiChatOptions.builder().withFunctionCallbacks(List.of(this.functionDefinition)).build();
var promptOptions = OpenAiChatOptions.builder().functionCallbacks(List.of(this.functionDefinition)).build();
var prompt = new Prompt(messages, promptOptions);
@@ -197,7 +197,7 @@ class OpenAiChatModelProxyToolCallsIT {
List<Message> messages = List
.of(new UserMessage("What's the weather like in San Francisco, Tokyo, and Paris?"));
var promptOptions = OpenAiChatOptions.builder().withFunctionCallbacks(List.of(this.functionDefinition)).build();
var promptOptions = OpenAiChatOptions.builder().functionCallbacks(List.of(this.functionDefinition)).build();
var prompt = new Prompt(messages, promptOptions);
@@ -281,7 +281,7 @@ class OpenAiChatModelProxyToolCallsIT {
List<Message> messages = List
.of(new UserMessage("What's the weather like in San Francisco, Tokyo, and Paris?"));
var promptOptions = OpenAiChatOptions.builder().withFunctionCallbacks(List.of(this.functionDefinition)).build();
var promptOptions = OpenAiChatOptions.builder().functionCallbacks(List.of(this.functionDefinition)).build();
var prompt = new Prompt(messages, promptOptions);
@@ -315,7 +315,7 @@ class OpenAiChatModelProxyToolCallsIT {
List<Message> messages = List
.of(new UserMessage("What's the weather like in San Francisco, Tokyo, and Paris?"));
var promptOptions = OpenAiChatOptions.builder().withFunctionCallbacks(List.of(this.functionDefinition)).build();
var promptOptions = OpenAiChatOptions.builder().functionCallbacks(List.of(this.functionDefinition)).build();
var prompt = new Prompt(messages, promptOptions);
@@ -361,7 +361,7 @@ class OpenAiChatModelProxyToolCallsIT {
@Bean
public OpenAiChatModel openAiClient(OpenAiApi openAiApi, List<FunctionCallback> toolFunctionCallbacks) {
// enable the proxy tool calls option.
var options = OpenAiChatOptions.builder().withModel(DEFAULT_MODEL).withProxyToolCalls(true).build();
var options = OpenAiChatOptions.builder().model(DEFAULT_MODEL).proxyToolCalls(true).build();
return new OpenAiChatModel(openAiApi, options, null, toolFunctionCallbacks,
RetryUtils.DEFAULT_RETRY_TEMPLATE, ObservationRegistry.NOOP);

View File

@@ -82,7 +82,7 @@ public class OpenAiChatModelResponseFormatIT {
Prompt prompt = new Prompt("List 8 planets. Use JSON response",
OpenAiChatOptions.builder()
.withResponseFormat(ResponseFormat.builder().type(ResponseFormat.Type.JSON_OBJECT).build())
.responseFormat(ResponseFormat.builder().type(ResponseFormat.Type.JSON_OBJECT).build())
.build());
ChatResponse response = this.openAiChatModel.call(prompt);
@@ -124,8 +124,8 @@ public class OpenAiChatModelResponseFormatIT {
Prompt prompt = new Prompt("how can I solve 8x + 7 = -23",
OpenAiChatOptions.builder()
.withModel(ChatModel.GPT_4_O_MINI)
.withResponseFormat(new ResponseFormat(ResponseFormat.Type.JSON_SCHEMA, jsonSchema))
.model(ChatModel.GPT_4_O_MINI)
.responseFormat(new ResponseFormat(ResponseFormat.Type.JSON_SCHEMA, jsonSchema))
.build());
ChatResponse response = this.openAiChatModel.call(prompt);
@@ -205,8 +205,8 @@ public class OpenAiChatModelResponseFormatIT {
Prompt prompt = new Prompt("how can I solve 8x + 7 = -23",
OpenAiChatOptions.builder()
.withModel(ChatModel.GPT_4_O_MINI)
.withResponseFormat(new ResponseFormat(ResponseFormat.Type.JSON_SCHEMA, jsonSchema1))
.model(ChatModel.GPT_4_O_MINI)
.responseFormat(new ResponseFormat(ResponseFormat.Type.JSON_SCHEMA, jsonSchema1))
.build());
ChatResponse response = this.openAiChatModel.call(prompt);

View File

@@ -49,7 +49,7 @@ public class OpenAiCompatibleChatModelIT {
new UserMessage("Tell me about 3 most famous ones."));
static OpenAiChatOptions forModelName(String modelName) {
return OpenAiChatOptions.builder().withModel(modelName).build();
return OpenAiChatOptions.builder().model(modelName).build();
}
static Stream<ChatModel> openAiCompatibleApis() {

View File

@@ -223,10 +223,7 @@ public class OpenAiPaymentTransactionIT {
@Bean
public OpenAiChatModel openAiClient(OpenAiApi openAiApi, FunctionCallbackResolver functionCallbackResolver) {
return new OpenAiChatModel(openAiApi,
OpenAiChatOptions.builder()
.withModel(ChatModel.GPT_4_O_MINI.getName())
.withTemperature(0.1)
.build(),
OpenAiChatOptions.builder().model(ChatModel.GPT_4_O_MINI.getName()).temperature(0.1).build(),
functionCallbackResolver, RetryUtils.DEFAULT_RETRY_TEMPLATE);
}

View File

@@ -116,8 +116,8 @@ public class OpenAiRetryTests {
OpenAiEmbeddingOptions.builder().build(), this.retryTemplate);
this.audioTranscriptionModel = new OpenAiAudioTranscriptionModel(this.openAiAudioApi,
OpenAiAudioTranscriptionOptions.builder()
.withModel("model")
.withResponseFormat(TranscriptResponseFormat.JSON)
.model("model")
.responseFormat(TranscriptResponseFormat.JSON)
.build(),
this.retryTemplate);
this.imageModel = new OpenAiImageModel(this.openAiImageApi, OpenAiImageOptions.builder().build(),

View File

@@ -81,7 +81,7 @@ class OpenAiChatClientIT extends AbstractIT {
// @formatter:off
ChatClient chatClient = ChatClient.builder(this.chatModel)
.defaultOptions(OpenAiChatOptions.builder()
.withModel(OpenAiApi.ChatModel.GPT_4_O.getValue()).build())
.model(OpenAiApi.ChatModel.GPT_4_O.getValue()).build())
.defaultUser(REASON_QUESTION)
.build();
@@ -215,7 +215,7 @@ class OpenAiChatClientIT extends AbstractIT {
// @formatter:off
Flux<ChatResponse> chatResponse = ChatClient.create(this.chatModel)
.prompt()
.options(OpenAiChatOptions.builder().withStreamUsage(true).build())
.options(OpenAiChatOptions.builder().streamUsage(true).build())
.advisors(new SimpleLoggerAdvisor())
.user(u -> u
.text("Generate the filmography of 5 movies for Tom Hanks. " + System.lineSeparator()
@@ -312,7 +312,7 @@ class OpenAiChatClientIT extends AbstractIT {
// @formatter:off
String response = ChatClient.create(this.chatModel).prompt()
.options(OpenAiChatOptions.builder().withModel(modelName).build())
.options(OpenAiChatOptions.builder().model(modelName).build())
.user(u -> u.text("Explain what do you see on this picture?")
.media(MimeTypeUtils.IMAGE_PNG, new ClassPathResource("/test.png")))
.call()
@@ -334,7 +334,7 @@ class OpenAiChatClientIT extends AbstractIT {
// @formatter:off
String response = ChatClient.create(this.chatModel).prompt()
// TODO consider adding model(...) method to ChatClient as a shortcut to
.options(OpenAiChatOptions.builder().withModel(modelName).build())
.options(OpenAiChatOptions.builder().model(modelName).build())
.user(u -> u.text("Explain what do you see on this picture?").media(MimeTypeUtils.IMAGE_PNG, url))
.call()
.content();
@@ -353,7 +353,7 @@ class OpenAiChatClientIT extends AbstractIT {
// @formatter:off
Flux<String> response = ChatClient.create(this.chatModel).prompt()
.options(OpenAiChatOptions.builder().withModel(OpenAiApi.ChatModel.GPT_4_O.getValue())
.options(OpenAiChatOptions.builder().model(OpenAiApi.ChatModel.GPT_4_O.getValue())
.build())
.user(u -> u.text("Explain what do you see on this picture?")
.media(MimeTypeUtils.IMAGE_PNG, url))
@@ -373,10 +373,9 @@ class OpenAiChatClientIT extends AbstractIT {
ChatResponse response = ChatClient.create(this.chatModel)
.prompt("Tell me joke about Spring Framework")
.options(OpenAiChatOptions.builder()
.withModel(OpenAiApi.ChatModel.GPT_4_O_AUDIO_PREVIEW)
.withOutputAudio(
new AudioParameters(AudioParameters.Voice.ALLOY, AudioParameters.AudioResponseFormat.WAV))
.withOutputModalities(List.of("text", "audio"))
.model(OpenAiApi.ChatModel.GPT_4_O_AUDIO_PREVIEW)
.outputAudio(new AudioParameters(AudioParameters.Voice.ALLOY, AudioParameters.AudioResponseFormat.WAV))
.outputModalities(List.of("text", "audio"))
.build())
.call()
.chatResponse();

View File

@@ -124,7 +124,7 @@ class OpenAiChatClientProxyFunctionCallsIT extends AbstractIT {
chatResponse = chatClient.prompt()
.messages(messages)
.functions(this.functionDefinition)
.options(OpenAiChatOptions.builder().withProxyToolCalls(true).build())
.options(OpenAiChatOptions.builder().proxyToolCalls(true).build())
.call()
.chatResponse();

View File

@@ -118,7 +118,7 @@ class GroqWithOpenAiChatModelIT {
@Test
@Disabled("Not supported by the current Groq API")
void streamingWithTokenUsage() {
var promptOptions = OpenAiChatOptions.builder().withStreamUsage(true).withSeed(1).build();
var promptOptions = OpenAiChatOptions.builder().streamUsage(true).seed(1).build();
var prompt = new Prompt("List two colors of the Polish flag. Be brief.", promptOptions);
@@ -249,7 +249,7 @@ class GroqWithOpenAiChatModelIT {
List<Message> messages = new ArrayList<>(List.of(userMessage));
var promptOptions = OpenAiChatOptions.builder()
.withFunctionCallbacks(List.of(FunctionCallback.builder()
.functionCallbacks(List.of(FunctionCallback.builder()
.function("getCurrentWeather", new MockWeatherService())
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
@@ -272,7 +272,7 @@ class GroqWithOpenAiChatModelIT {
List<Message> messages = new ArrayList<>(List.of(userMessage));
var promptOptions = OpenAiChatOptions.builder()
.withFunctionCallbacks(List.of(FunctionCallback.builder()
.functionCallbacks(List.of(FunctionCallback.builder()
.function("getCurrentWeather", new MockWeatherService())
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
@@ -305,7 +305,7 @@ class GroqWithOpenAiChatModelIT {
List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData)));
var response = this.chatModel
.call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().withModel(modelName).build()));
.call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().model(modelName).build()));
logger.info(response.getResult().getOutput().getText());
assertThat(response.getResult().getOutput().getText()).contains("bananas", "apple");
@@ -324,7 +324,7 @@ class GroqWithOpenAiChatModelIT {
.build()));
ChatResponse response = this.chatModel
.call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().withModel(modelName).build()));
.call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().model(modelName).build()));
logger.info(response.getResult().getOutput().getText());
assertThat(response.getResult().getOutput().getText()).contains("bananas", "apple");
@@ -361,7 +361,7 @@ class GroqWithOpenAiChatModelIT {
void validateCallResponseMetadata(String model) {
// @formatter:off
ChatResponse response = ChatClient.create(this.chatModel).prompt()
.options(OpenAiChatOptions.builder().withModel(model).build())
.options(OpenAiChatOptions.builder().model(model).build())
.user("Tell me about 3 famous pirates from the Golden Age of Piracy and what they did")
.call()
.chatResponse();
@@ -389,7 +389,7 @@ class GroqWithOpenAiChatModelIT {
@Bean
public OpenAiChatModel openAiClient(OpenAiApi openAiApi) {
return new OpenAiChatModel(openAiApi, OpenAiChatOptions.builder().withModel(DEFAULT_GROQ_MODEL).build());
return new OpenAiChatModel(openAiApi, OpenAiChatOptions.builder().model(DEFAULT_GROQ_MODEL).build());
}
}

View File

@@ -117,7 +117,7 @@ class MistralWithOpenAiChatModelIT {
@Test
@Disabled("Not supported by the current Mistral AI API")
void streamingWithTokenUsage() {
var promptOptions = OpenAiChatOptions.builder().withStreamUsage(true).withSeed(1).build();
var promptOptions = OpenAiChatOptions.builder().streamUsage(true).seed(1).build();
var prompt = new Prompt("List two colors of the Polish flag. Be brief.", promptOptions);
@@ -250,8 +250,8 @@ class MistralWithOpenAiChatModelIT {
List<Message> messages = new ArrayList<>(List.of(userMessage));
var promptOptions = OpenAiChatOptions.builder()
.withModel(modelName)
.withFunctionCallbacks(List.of(FunctionCallback.builder()
.model(modelName)
.functionCallbacks(List.of(FunctionCallback.builder()
.function("getCurrentWeather", new MockWeatherService())
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
@@ -275,8 +275,8 @@ class MistralWithOpenAiChatModelIT {
List<Message> messages = new ArrayList<>(List.of(userMessage));
var promptOptions = OpenAiChatOptions.builder()
.withModel(modelName)
.withFunctionCallbacks(List.of(FunctionCallback.builder()
.model(modelName)
.functionCallbacks(List.of(FunctionCallback.builder()
.function("getCurrentWeather", new MockWeatherService())
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
@@ -309,7 +309,7 @@ class MistralWithOpenAiChatModelIT {
List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData)));
var response = this.chatModel
.call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().withModel(modelName).build()));
.call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().model(modelName).build()));
logger.info(response.getResult().getOutput().getText());
assertThat(response.getResult().getOutput().getText()).contains("bananas", "apple");
@@ -328,7 +328,7 @@ class MistralWithOpenAiChatModelIT {
.build()));
ChatResponse response = this.chatModel
.call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().withModel(modelName).build()));
.call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().model(modelName).build()));
logger.info(response.getResult().getOutput().getText());
assertThat(response.getResult().getOutput().getText()).contains("bananas", "apple");
@@ -366,7 +366,7 @@ class MistralWithOpenAiChatModelIT {
void validateCallResponseMetadata(String model) {
// @formatter:off
ChatResponse response = ChatClient.create(this.chatModel).prompt()
.options(OpenAiChatOptions.builder().withModel(model).build())
.options(OpenAiChatOptions.builder().model(model).build())
.user("Tell me about 3 famous pirates from the Golden Age of Piracy and what they did")
.call()
.chatResponse();
@@ -394,7 +394,7 @@ class MistralWithOpenAiChatModelIT {
@Bean
public OpenAiChatModel openAiClient(OpenAiApi openAiApi) {
return new OpenAiChatModel(openAiApi, OpenAiChatOptions.builder().withModel(MISTRAL_DEFAULT_MODEL).build());
return new OpenAiChatModel(openAiApi, OpenAiChatOptions.builder().model(MISTRAL_DEFAULT_MODEL).build());
}
}

View File

@@ -114,7 +114,7 @@ class NvidiaWithOpenAiChatModelIT {
@Test
void streamingWithTokenUsage() {
var promptOptions = OpenAiChatOptions.builder().withStreamUsage(true).withSeed(1).build();
var promptOptions = OpenAiChatOptions.builder().streamUsage(true).seed(1).build();
var prompt = new Prompt("List two colors of the Polish flag. Be brief.", promptOptions);
@@ -246,7 +246,7 @@ class NvidiaWithOpenAiChatModelIT {
List<Message> messages = new ArrayList<>(List.of(userMessage));
var promptOptions = OpenAiChatOptions.builder()
.withFunctionCallbacks(List.of(FunctionCallback.builder()
.functionCallbacks(List.of(FunctionCallback.builder()
.function("getCurrentWeather", new MockWeatherService())
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
@@ -269,7 +269,7 @@ class NvidiaWithOpenAiChatModelIT {
List<Message> messages = new ArrayList<>(List.of(userMessage));
var promptOptions = OpenAiChatOptions.builder()
.withFunctionCallbacks(List.of(FunctionCallback.builder()
.functionCallbacks(List.of(FunctionCallback.builder()
.function("getCurrentWeather", new MockWeatherService())
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
@@ -295,7 +295,7 @@ class NvidiaWithOpenAiChatModelIT {
void validateCallResponseMetadata() {
// @formatter:off
ChatResponse response = ChatClient.create(this.chatModel).prompt()
.options(OpenAiChatOptions.builder().withModel(DEFAULT_NVIDIA_MODEL).build())
.options(OpenAiChatOptions.builder().model(DEFAULT_NVIDIA_MODEL).build())
.user("Tell me about 3 famous pirates from the Golden Age of Piracy and what they did")
.call()
.chatResponse();
@@ -324,7 +324,7 @@ class NvidiaWithOpenAiChatModelIT {
@Bean
public OpenAiChatModel openAiClient(OpenAiApi openAiApi) {
return new OpenAiChatModel(openAiApi,
OpenAiChatOptions.builder().withMaxTokens(2048).withModel(DEFAULT_NVIDIA_MODEL).build());
OpenAiChatOptions.builder().maxTokens(2048).model(DEFAULT_NVIDIA_MODEL).build());
}
}

View File

@@ -135,7 +135,7 @@ class OllamaWithOpenAiChatModelIT {
@Test
@Disabled("Not supported by the current Ollama API")
void streamingWithTokenUsage() {
var promptOptions = OpenAiChatOptions.builder().withStreamUsage(true).withSeed(1).build();
var promptOptions = OpenAiChatOptions.builder().streamUsage(true).seed(1).build();
var prompt = new Prompt("List two colors of the Polish flag. Be brief.", promptOptions);
@@ -268,11 +268,11 @@ class OllamaWithOpenAiChatModelIT {
List<Message> messages = new ArrayList<>(List.of(userMessage));
var promptOptions = OpenAiChatOptions.builder()
.withModel(modelName)
.model(modelName)
// Note for Ollama you must set the tool choice to explicitly. Unlike OpenAI
// (which defaults to "auto") Ollama defaults to "nono"
.withToolChoice("auto")
.withFunctionCallbacks(List.of(FunctionCallback.builder()
.toolChoice("auto")
.functionCallbacks(List.of(FunctionCallback.builder()
.function("getCurrentWeather", new MockWeatherService())
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
@@ -296,11 +296,11 @@ class OllamaWithOpenAiChatModelIT {
List<Message> messages = new ArrayList<>(List.of(userMessage));
var promptOptions = OpenAiChatOptions.builder()
.withModel(modelName)
.model(modelName)
// Note for Ollama you must set the tool choice to explicitly. Unlike OpenAI
// (which defaults to "auto") Ollama defaults to "nono"
.withToolChoice("auto")
.withFunctionCallbacks(List.of(FunctionCallback.builder()
.toolChoice("auto")
.functionCallbacks(List.of(FunctionCallback.builder()
.function("getCurrentWeather", new MockWeatherService())
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
@@ -332,7 +332,7 @@ class OllamaWithOpenAiChatModelIT {
List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData)));
var response = this.chatModel
.call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().withModel(modelName).build()));
.call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().model(modelName).build()));
logger.info(response.getResult().getOutput().getText());
assertThat(response.getResult().getOutput().getText()).contains("bananas", "apple");
@@ -351,7 +351,7 @@ class OllamaWithOpenAiChatModelIT {
.build()));
ChatResponse response = this.chatModel
.call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().withModel(modelName).build()));
.call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().model(modelName).build()));
logger.info(response.getResult().getOutput().getText());
assertThat(response.getResult().getOutput().getText()).contains("bananas", "apple");
@@ -370,7 +370,7 @@ class OllamaWithOpenAiChatModelIT {
.build()));
Flux<ChatResponse> response = this.chatModel
.stream(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().withModel(modelName).build()));
.stream(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().model(modelName).build()));
String content = response.collectList()
.block()
@@ -390,7 +390,7 @@ class OllamaWithOpenAiChatModelIT {
void validateCallResponseMetadata(String model) {
// @formatter:off
ChatResponse response = ChatClient.create(this.chatModel).prompt()
.options(OpenAiChatOptions.builder().withModel(model).build())
.options(OpenAiChatOptions.builder().model(model).build())
.user("Tell me about 3 famous pirates from the Golden Age of Piracy and what they did")
.call()
.chatResponse();
@@ -418,7 +418,7 @@ class OllamaWithOpenAiChatModelIT {
@Bean
public OpenAiChatModel openAiClient(OpenAiApi openAiApi) {
return new OpenAiChatModel(openAiApi, OpenAiChatOptions.builder().withModel(DEFAULT_OLLAMA_MODEL).build());
return new OpenAiChatModel(openAiApi, OpenAiChatOptions.builder().model(DEFAULT_OLLAMA_MODEL).build());
}
}

View File

@@ -131,7 +131,7 @@ class PerplexityWithOpenAiChatModelIT {
@Test
void streamingWithTokenUsage() {
var promptOptions = OpenAiChatOptions.builder().withStreamUsage(true).withSeed(1).build();
var promptOptions = OpenAiChatOptions.builder().streamUsage(true).seed(1).build();
var prompt = new Prompt("List two colors of the Polish flag. Be brief.", promptOptions);
@@ -258,7 +258,7 @@ class PerplexityWithOpenAiChatModelIT {
List<Message> messages = new ArrayList<>(List.of(userMessage));
var promptOptions = OpenAiChatOptions.builder()
.withFunctionCallbacks(List.of(FunctionCallback.builder()
.functionCallbacks(List.of(FunctionCallback.builder()
.function("getCurrentWeather", new MockWeatherService())
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
@@ -280,7 +280,7 @@ class PerplexityWithOpenAiChatModelIT {
List<Message> messages = new ArrayList<>(List.of(userMessage));
var promptOptions = OpenAiChatOptions.builder()
.withFunctionCallbacks(List.of(FunctionCallback.builder()
.functionCallbacks(List.of(FunctionCallback.builder()
.function("getCurrentWeather", new MockWeatherService())
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
@@ -306,7 +306,7 @@ class PerplexityWithOpenAiChatModelIT {
void validateCallResponseMetadata() {
ChatResponse response = ChatClient.create(this.chatModel)
.prompt()
.options(OpenAiChatOptions.builder().withModel(DEFAULT_PERPLEXITY_MODEL).build())
.options(OpenAiChatOptions.builder().model(DEFAULT_PERPLEXITY_MODEL).build())
.user("Tell me about 3 famous pirates from the Golden Age of Piracy and what they did")
.call()
.chatResponse();
@@ -334,8 +334,7 @@ class PerplexityWithOpenAiChatModelIT {
@Bean
public OpenAiChatModel openAiClient(OpenAiApi openAiApi) {
return new OpenAiChatModel(openAiApi,
OpenAiChatOptions.builder().withModel(DEFAULT_PERPLEXITY_MODEL).build());
return new OpenAiChatModel(openAiApi, OpenAiChatOptions.builder().model(DEFAULT_PERPLEXITY_MODEL).build());
}
}

View File

@@ -68,7 +68,7 @@ class EmbeddingIT extends AbstractIT {
assertThat(this.embeddingModel).isNotNull();
List<float[]> embeddings = this.embeddingModel.embed(
List.of(new Document("Hello world"), new Document("Hello Spring"), new Document("Hello Spring AI!")),
OpenAiEmbeddingOptions.builder().withModel(OpenAiApi.DEFAULT_EMBEDDING_MODEL).build(),
OpenAiEmbeddingOptions.builder().model(OpenAiApi.DEFAULT_EMBEDDING_MODEL).build(),
new TokenCountBatchingStrategy());
assertThat(embeddings.size()).isEqualTo(3);
embeddings.forEach(embedding -> assertThat(embedding.length).isEqualTo(this.embeddingModel.dimensions()));
@@ -80,7 +80,7 @@ class EmbeddingIT extends AbstractIT {
String contentAsString = this.resource.getContentAsString(StandardCharsets.UTF_8);
assertThatThrownBy(
() -> this.embeddingModel.embed(List.of(new Document("Hello World"), new Document(contentAsString)),
OpenAiEmbeddingOptions.builder().withModel(OpenAiApi.DEFAULT_EMBEDDING_MODEL).build(),
OpenAiEmbeddingOptions.builder().model(OpenAiApi.DEFAULT_EMBEDDING_MODEL).build(),
new TokenCountBatchingStrategy()))
.isInstanceOf(IllegalArgumentException.class);
}
@@ -89,7 +89,7 @@ class EmbeddingIT extends AbstractIT {
void embedding3Large() {
EmbeddingResponse embeddingResponse = this.embeddingModel.call(new EmbeddingRequest(List.of("Hello World"),
OpenAiEmbeddingOptions.builder().withModel("text-embedding-3-large").build()));
OpenAiEmbeddingOptions.builder().model("text-embedding-3-large").build()));
assertThat(embeddingResponse.getResults()).hasSize(1);
assertThat(embeddingResponse.getResults().get(0)).isNotNull();
assertThat(embeddingResponse.getResults().get(0).getOutput()).hasSize(3072);
@@ -104,7 +104,7 @@ class EmbeddingIT extends AbstractIT {
void textEmbeddingAda002() {
EmbeddingResponse embeddingResponse = this.embeddingModel.call(new EmbeddingRequest(List.of("Hello World"),
OpenAiEmbeddingOptions.builder().withModel("text-embedding-3-small").build()));
OpenAiEmbeddingOptions.builder().model("text-embedding-3-small").build()));
assertThat(embeddingResponse.getResults()).hasSize(1);
assertThat(embeddingResponse.getResults().get(0)).isNotNull();
assertThat(embeddingResponse.getResults().get(0).getOutput()).hasSize(1536);

View File

@@ -61,9 +61,9 @@ public class OpenAiEmbeddingModelObservationIT {
@Test
void observationForEmbeddingOperation() {
var options = OpenAiEmbeddingOptions.builder()
.withModel(OpenAiApi.EmbeddingModel.TEXT_EMBEDDING_3_SMALL.getValue())
.withDimensions(1536)
.withEncodingFormat("float")
.model(OpenAiApi.EmbeddingModel.TEXT_EMBEDDING_3_SMALL.getValue())
.dimensions(1536)
.encodingFormat("float")
.build();
EmbeddingRequest embeddingRequest = new EmbeddingRequest(List.of("Here comes the sun"), options);

View File

@@ -57,11 +57,11 @@ public class OpenAiImageModelObservationIT {
@Test
void observationForImageOperation() {
var options = OpenAiImageOptions.builder()
.withModel(OpenAiImageApi.ImageModel.DALL_E_3.getValue())
.withHeight(1024)
.withWidth(1024)
.withResponseFormat("url")
.withStyle("natural")
.model(OpenAiImageApi.ImageModel.DALL_E_3.getValue())
.height(1024)
.width(1024)
.responseFormat("url")
.style("natural")
.build();
var instructions = "Here comes the sun";

View File

@@ -89,10 +89,10 @@ For example:
[source,java]
----
OpenAiAudioSpeechOptions speechOptions = OpenAiAudioSpeechOptions.builder()
.withModel("tts-1")
.withVoice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY)
.withResponseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3)
.withSpeed(1.0f)
.model("tts-1")
.voice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY)
.responseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3)
.speed(1.0f)
.build();
SpeechPrompt speechPrompt = new SpeechPrompt("Hello, this is a text-to-speech example.", this.speechOptions);
@@ -131,9 +131,9 @@ var openAiAudioApi = new OpenAiAudioApi(System.getenv("OPENAI_API_KEY"));
var openAiAudioSpeechModel = new OpenAiAudioSpeechModel(this.openAiAudioApi);
var speechOptions = OpenAiAudioSpeechOptions.builder()
.withResponseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3)
.withSpeed(1.0f)
.withModel(OpenAiAudioApi.TtsModel.TTS_1.value)
.responseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3)
.speed(1.0f)
.model(OpenAiAudioApi.TtsModel.TTS_1.value)
.build();
var speechPrompt = new SpeechPrompt("Hello, this is a text-to-speech example.", this.speechOptions);

View File

@@ -150,7 +150,7 @@ OpenAiChatModel chatModel = ...
UserMessage userMessage = new UserMessage("What's the weather like in San Francisco, Tokyo, and Paris?");
ChatResponse response = this.chatModel.call(new Prompt(this.userMessage,
OpenAiChatOptions.builder().withFunction("CurrentWeather").build())); // Enable the function
OpenAiChatOptions.builder().function("CurrentWeather").build())); // Enable the function
logger.info("Response: {}", response);
----
@@ -179,7 +179,7 @@ OpenAiChatModel chatModel = ...
UserMessage userMessage = new UserMessage("What's the weather like in San Francisco, Tokyo, and Paris?");
var promptOptions = OpenAiChatOptions.builder()
.withFunctionCallbacks(List.of(FunctionCallback.builder()
.functionCallbacks(List.of(FunctionCallback.builder()
.function("CurrentWeather", new MockWeatherService()) // (1) function name and instance
.description("Get the weather in location") // (2) function description
.inputType(MockWeatherService.Request.class) // (3) function input type
@@ -229,13 +229,13 @@ BiFunction<MockWeatherService.Request, ToolContext, MockWeatherService.Response>
};
OpenAiChatOptions options = OpenAiChatOptions.builder()
.withModel(OpenAiApi.ChatModel.GPT_4_O.getValue())
.withFunctionCallbacks(List.of(FunctionCallback.builder()
.model(OpenAiApi.ChatModel.GPT_4_O.getValue())
.functionCallbacks(List.of(FunctionCallback.builder()
.function("getCurrentWeather", this.weatherFunction)
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
.build()))
.withToolContext(Map.of("sessionId", "123", "userId", "user456"))
.toolContext(Map.of("sessionId", "123", "userId", "user456"))
.build();
----

View File

@@ -152,8 +152,8 @@ ChatResponse response = chatModel.call(
new Prompt(
"Generate the names of 5 famous pirates.",
OpenAiChatOptions.builder()
.withModel("gpt-4-o")
.withTemperature(0.4)
.model("gpt-4-o")
.temperature(0.4)
.build()
));
----
@@ -190,7 +190,7 @@ var userMessage = new UserMessage("Explain what do you see on this picture?",
new Media(MimeTypeUtils.IMAGE_PNG, this.imageResource));
ChatResponse response = chatModel.call(new Prompt(this.userMessage,
OpenAiChatOptions.builder().withModel(OpenAiApi.ChatModel.GPT_4_O.getValue()).build()));
OpenAiChatOptions.builder().model(OpenAiApi.ChatModel.GPT_4_O.getValue()).build()));
----
TIP: GPT_4_VISION_PREVIEW will continue to be available only to existing users of this model starting June 17, 2024. If you are not an existing user, please use the GPT_4_O or GPT_4_TURBO models. More details https://platform.openai.com/docs/deprecations/2024-06-06-gpt-4-32k-and-vision-preview-models[here]
@@ -204,7 +204,7 @@ var userMessage = new UserMessage("Explain what do you see on this picture?",
"https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png"));
ChatResponse response = chatModel.call(new Prompt(this.userMessage,
OpenAiChatOptions.builder().withModel(OpenAiApi.ChatModel.GPT_4_O.getValue()).build()));
OpenAiChatOptions.builder().model(OpenAiApi.ChatModel.GPT_4_O.getValue()).build()));
----
TIP: You can pass multiple images as well.
@@ -244,7 +244,7 @@ var userMessage = new UserMessage("What is this recording about?",
List.of(new Media(MimeTypeUtils.parseMimeType("audio/mp3"), audioResource)));
ChatResponse response = chatModel.call(new Prompt(List.of(userMessage),
OpenAiChatOptions.builder().withModel(OpenAiApi.ChatModel.GPT_4_O_AUDIO_PREVIEW).build()));
OpenAiChatOptions.builder().model(OpenAiApi.ChatModel.GPT_4_O_AUDIO_PREVIEW).build()));
----
TIP: You can pass multiple audio files as well.
@@ -267,9 +267,9 @@ var userMessage = new UserMessage("Tell me joke about Spring Framework");
ChatResponse response = chatModel.call(new Prompt(List.of(userMessage),
OpenAiChatOptions.builder()
.withModel(OpenAiApi.ChatModel.GPT_4_O_AUDIO_PREVIEW)
.withOutputModalities(List.of("text", "audio"))
.withOutputAudio(new AudioParameters(Voice.ALLOY, AudioResponseFormat.WAV))
.model(OpenAiApi.ChatModel.GPT_4_O_AUDIO_PREVIEW)
.outputModalities(List.of("text", "audio"))
.outputAudio(new AudioParameters(Voice.ALLOY, AudioResponseFormat.WAV))
.build()));
String text = response.getResult().getOutput().getContent(); // audio transcript
@@ -322,8 +322,8 @@ String jsonSchema = """
Prompt prompt = new Prompt("how can I solve 8x + 7 = -23",
OpenAiChatOptions.builder()
.withModel(ChatModel.GPT_4_O_MINI)
.withResponseFormat(new ResponseFormat(ResponseFormat.Type.JSON_SCHEMA, this.jsonSchema))
.model(ChatModel.GPT_4_O_MINI)
.responseFormat(new ResponseFormat(ResponseFormat.Type.JSON_SCHEMA, this.jsonSchema))
.build());
ChatResponse response = this.openAiChatModel.call(this.prompt);
@@ -362,8 +362,8 @@ var jsonSchema = this.outputConverter.getJsonSchema();
Prompt prompt = new Prompt("how can I solve 8x + 7 = -23",
OpenAiChatOptions.builder()
.withModel(ChatModel.GPT_4_O_MINI)
.withResponseFormat(new ResponseFormat(ResponseFormat.Type.JSON_SCHEMA, this.jsonSchema))
.model(ChatModel.GPT_4_O_MINI)
.responseFormat(new ResponseFormat(ResponseFormat.Type.JSON_SCHEMA, this.jsonSchema))
.build());
ChatResponse response = this.openAiChatModel.call(this.prompt);
@@ -393,8 +393,8 @@ val jsonSchema = outputConverter.jsonSchema;
val prompt = Prompt("how can I solve 8x + 7 = -23",
OpenAiChatOptions.builder()
.withModel(ChatModel.GPT_4_O_MINI)
.withResponseFormat(ResponseFormat(ResponseFormat.Type.JSON_SCHEMA, jsonSchema))
.model(ChatModel.GPT_4_O_MINI)
.responseFormat(ResponseFormat(ResponseFormat.Type.JSON_SCHEMA, jsonSchema))
.build())
val response = openAiChatModel.call(prompt)
@@ -498,9 +498,9 @@ Next, create an `OpenAiChatModel` and use it for text generations:
----
var openAiApi = new OpenAiApi(System.getenv("OPENAI_API_KEY"));
var openAiChatOptions = OpenAiChatOptions.builder()
.withModel("gpt-3.5-turbo")
.withTemperature(0.4)
.withMaxTokens(200)
.model("gpt-3.5-turbo")
.temperature(0.4)
.maxTokens(200)
.build();
var chatModel = new OpenAiChatModel(this.openAiApi, this.openAiChatOptions);

View File

@@ -128,7 +128,7 @@ For example to override the default model name for a specific request:
EmbeddingResponse embeddingResponse = embeddingModel.call(
new EmbeddingRequest(List.of("Hello World", "World is big and salvation is near"),
OpenAiEmbeddingOptions.builder()
.withModel("Different-Embedding-Model-Deployment-Name")
.model("Different-Embedding-Model-Deployment-Name")
.build()));
----
@@ -199,8 +199,8 @@ var embeddingModel = new OpenAiEmbeddingModel(
this.openAiApi,
MetadataMode.EMBED,
OpenAiEmbeddingOptions.builder()
.withModel("text-embedding-ada-002")
.withUser("user-6")
.model("text-embedding-ada-002")
.user("user-6")
.build(),
RetryUtils.DEFAULT_RETRY_TEMPLATE);

View File

@@ -118,10 +118,10 @@ For example to override the OpenAI specific options such as quality and the numb
ImageResponse response = openaiImageModel.call(
new ImagePrompt("A light cream colored mini golden doodle",
OpenAiImageOptions.builder()
.withQuality("hd")
.withN(4)
.withHeight(1024)
.withWidth(1024).build())
.quality("hd")
.N(4)
.height(1024)
.width(1024).build())
);
----

View File

@@ -78,7 +78,7 @@ For example:
[source,java]
----
OpenAiModerationOptions moderationOptions = OpenAiModerationOptions.builder()
.withModel("text-moderation-latest")
.model("text-moderation-latest")
.build();
ModerationPrompt moderationPrompt = new ModerationPrompt("Text to be moderated", this.moderationOptions);
@@ -161,7 +161,7 @@ OpenAiModerationApi openAiModerationApi = new OpenAiModerationApi(System.getenv(
OpenAiModerationModel openAiModerationModel = new OpenAiModerationModel(this.openAiModerationApi);
OpenAiModerationOptions moderationOptions = OpenAiModerationOptions.builder()
.withModel("text-moderation-latest")
.model("text-moderation-latest")
.build();
ModerationPrompt moderationPrompt = new ModerationPrompt("Text to be moderated", this.moderationOptions);

View File

@@ -50,10 +50,10 @@ public class OpenAiAudioSpeechProperties extends OpenAiParentProperties {
@NestedConfigurationProperty
private OpenAiAudioSpeechOptions options = OpenAiAudioSpeechOptions.builder()
.withModel(DEFAULT_SPEECH_MODEL)
.withResponseFormat(DEFAULT_RESPONSE_FORMAT)
.withVoice(VOICE)
.withSpeed(SPEED)
.model(DEFAULT_SPEECH_MODEL)
.responseFormat(DEFAULT_RESPONSE_FORMAT)
.voice(VOICE)
.speed(SPEED)
.build();
public OpenAiAudioSpeechOptions getOptions() {

View File

@@ -39,9 +39,9 @@ public class OpenAiAudioTranscriptionProperties extends OpenAiParentProperties {
@NestedConfigurationProperty
private OpenAiAudioTranscriptionOptions options = OpenAiAudioTranscriptionOptions.builder()
.withModel(DEFAULT_TRANSCRIPTION_MODEL)
.withTemperature(DEFAULT_TEMPERATURE.floatValue())
.withResponseFormat(DEFAULT_RESPONSE_FORMAT)
.model(DEFAULT_TRANSCRIPTION_MODEL)
.temperature(DEFAULT_TEMPERATURE.floatValue())
.responseFormat(DEFAULT_RESPONSE_FORMAT)
.build();
public OpenAiAudioTranscriptionOptions getOptions() {

View File

@@ -40,8 +40,8 @@ public class OpenAiChatProperties extends OpenAiParentProperties {
@NestedConfigurationProperty
private OpenAiChatOptions options = OpenAiChatOptions.builder()
.withModel(DEFAULT_CHAT_MODEL)
.withTemperature(DEFAULT_TEMPERATURE)
.model(DEFAULT_CHAT_MODEL)
.temperature(DEFAULT_TEMPERATURE)
.build();
public OpenAiChatOptions getOptions() {

View File

@@ -40,9 +40,7 @@ public class OpenAiEmbeddingProperties extends OpenAiParentProperties {
private String embeddingsPath = DEFAULT_EMBEDDINGS_PATH;
@NestedConfigurationProperty
private OpenAiEmbeddingOptions options = OpenAiEmbeddingOptions.builder()
.withModel(DEFAULT_EMBEDDING_MODEL)
.build();
private OpenAiEmbeddingOptions options = OpenAiEmbeddingOptions.builder().model(DEFAULT_EMBEDDING_MODEL).build();
public OpenAiEmbeddingOptions getOptions() {
return this.options;

View File

@@ -43,7 +43,7 @@ public class OpenAiImageProperties extends OpenAiParentProperties {
* Options for OpenAI Image API.
*/
@NestedConfigurationProperty
private OpenAiImageOptions options = OpenAiImageOptions.builder().withModel(DEFAULT_IMAGE_MODEL).build();
private OpenAiImageOptions options = OpenAiImageOptions.builder().model(DEFAULT_IMAGE_MODEL).build();
public OpenAiImageOptions getOptions() {
return this.options;

View File

@@ -75,8 +75,8 @@ class PaymentStatusBeanOpenAiIT {
ChatResponse response = chatModel
.call(new Prompt(List.of(new UserMessage("What's the status of my transaction with id T1001?")),
OpenAiChatOptions.builder()
.withFunction("retrievePaymentStatus")
.withFunction("retrievePaymentDate")
.function("retrievePaymentStatus")
.function("retrievePaymentDate")
.build()));
logger.info("Response: {}", response);

View File

@@ -62,7 +62,7 @@ public class FunctionCallbackInPromptIT {
"What's the weather like in San Francisco, Tokyo, and Paris?");
var promptOptions = OpenAiChatOptions.builder()
.withFunctionCallbacks(List.of(FunctionCallback.builder()
.functionCallbacks(List.of(FunctionCallback.builder()
.function("CurrentWeatherService", new MockWeatherService())
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
@@ -91,7 +91,7 @@ public class FunctionCallbackInPromptIT {
"What's the weather like in San Francisco, Tokyo, and Paris?");
var promptOptions = OpenAiChatOptions.builder()
.withFunctionCallbacks(List.of(FunctionCallback.builder()
.functionCallbacks(List.of(FunctionCallback.builder()
.function("CurrentWeatherService", new MockWeatherService())
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)

View File

@@ -81,7 +81,7 @@ class FunctionCallbackWithPlainFunctionBeanIT {
UserMessage userMessage = new UserMessage("Turn the light on in the living room");
ChatResponse response = chatModel.call(new Prompt(List.of(userMessage),
OpenAiChatOptions.builder().withFunction("turnLivingRoomLightOn").build()));
OpenAiChatOptions.builder().function("turnLivingRoomLightOn").build()));
logger.info("Response: {}", response);
assertThat(feedback).hasSize(1);
@@ -99,7 +99,7 @@ class FunctionCallbackWithPlainFunctionBeanIT {
UserMessage userMessage = new UserMessage("Turn the light on in the living room");
ChatResponse response = chatModel.call(new Prompt(List.of(userMessage),
OpenAiChatOptions.builder().withFunction("turnLivingRoomLightOnSupplier").build()));
OpenAiChatOptions.builder().function("turnLivingRoomLightOnSupplier").build()));
logger.info("Response: {}", response);
assertThat(feedback).hasSize(1);
@@ -117,7 +117,7 @@ class FunctionCallbackWithPlainFunctionBeanIT {
UserMessage userMessage = new UserMessage("Turn the light on in the kitchen and in the living room");
ChatResponse response = chatModel
.call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().withFunction("turnLight").build()));
.call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().function("turnLight").build()));
logger.info("Response: {}", response);
assertThat(feedback).hasSize(2);
@@ -136,7 +136,7 @@ class FunctionCallbackWithPlainFunctionBeanIT {
UserMessage userMessage = new UserMessage("Turn the light on in the kitchen and in the living room");
ChatResponse response = chatModel.call(new Prompt(List.of(userMessage),
OpenAiChatOptions.builder().withFunction("turnLightConsumer").build()));
OpenAiChatOptions.builder().function("turnLightConsumer").build()));
logger.info("Response: {}", response);
assertThat(feedback).hasSize(2);
@@ -187,8 +187,8 @@ class FunctionCallbackWithPlainFunctionBeanIT {
ChatResponse response = chatModel.call(new Prompt(List.of(userMessage),
OpenAiChatOptions.builder()
.withFunction("weatherFunctionWithContext")
.withToolContext(Map.of("sessionId", "123"))
.function("weatherFunctionWithContext")
.toolContext(Map.of("sessionId", "123"))
.build()));
logger.info("Response: {}", response);
@@ -219,8 +219,8 @@ class FunctionCallbackWithPlainFunctionBeanIT {
ChatResponse response = chatModel.call(new Prompt(List.of(userMessage),
OpenAiChatOptions.builder()
.withFunction("weatherFunctionWithClassBiFunction")
.withToolContext(Map.of("sessionId", "123"))
.function("weatherFunctionWithClassBiFunction")
.toolContext(Map.of("sessionId", "123"))
.build()));
logger.info("Response: {}", response);
@@ -240,8 +240,8 @@ class FunctionCallbackWithPlainFunctionBeanIT {
UserMessage userMessage = new UserMessage(
"What's the weather like in San Francisco, Tokyo, and Paris? You can call the following functions 'weatherFunction'");
ChatResponse response = chatModel.call(new Prompt(List.of(userMessage),
OpenAiChatOptions.builder().withFunction("weatherFunction").build()));
ChatResponse response = chatModel.call(
new Prompt(List.of(userMessage), OpenAiChatOptions.builder().function("weatherFunction").build()));
logger.info("Response: {}", response);
@@ -249,7 +249,7 @@ class FunctionCallbackWithPlainFunctionBeanIT {
// Test weatherFunctionTwo
response = chatModel.call(new Prompt(List.of(userMessage),
OpenAiChatOptions.builder().withFunction("weatherFunctionTwo").build()));
OpenAiChatOptions.builder().function("weatherFunctionTwo").build()));
logger.info("Response: {}", response);
@@ -289,8 +289,8 @@ class FunctionCallbackWithPlainFunctionBeanIT {
UserMessage userMessage = new UserMessage(
"What's the weather like in San Francisco, Tokyo, and Paris? You can call the following functions 'weatherFunction'");
Flux<ChatResponse> response = chatModel.stream(new Prompt(List.of(userMessage),
OpenAiChatOptions.builder().withFunction("weatherFunction").build()));
Flux<ChatResponse> response = chatModel.stream(
new Prompt(List.of(userMessage), OpenAiChatOptions.builder().function("weatherFunction").build()));
String content = response.collectList()
.block()
@@ -306,7 +306,7 @@ class FunctionCallbackWithPlainFunctionBeanIT {
// Test weatherFunctionTwo
response = chatModel.stream(new Prompt(List.of(userMessage),
OpenAiChatOptions.builder().withFunction("weatherFunctionTwo").build()));
OpenAiChatOptions.builder().function("weatherFunctionTwo").build()));
content = response.collectList()
.block()

View File

@@ -61,8 +61,8 @@ public class OpenAiFunctionCallbackIT {
UserMessage userMessage = new UserMessage("What's the weather like in San Francisco, Tokyo, and Paris?");
ChatResponse response = chatModel.call(
new Prompt(List.of(userMessage), OpenAiChatOptions.builder().withFunction("WeatherInfo").build()));
ChatResponse response = chatModel
.call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().function("WeatherInfo").build()));
logger.info("Response: {}", response);
@@ -80,8 +80,8 @@ public class OpenAiFunctionCallbackIT {
UserMessage userMessage = new UserMessage(
"What's the weather like in San Francisco, Tokyo, and Paris? You can call the following functions 'WeatherInfo'");
Flux<ChatResponse> response = chatModel.stream(
new Prompt(List.of(userMessage), OpenAiChatOptions.builder().withFunction("WeatherInfo").build()));
Flux<ChatResponse> response = chatModel
.stream(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().function("WeatherInfo").build()));
String content = response.collectList()
.block()