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:
committed by
Mark Pollack
parent
c14618fe9a
commit
58efee6d90
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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!",
|
||||
|
||||
@@ -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!",
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
----
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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())
|
||||
|
||||
);
|
||||
----
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user