Add enabled property for OpenAI audio and transcription model

- Extend the audio speach/transcription properties to allow disabling autoconfiguration for the audio and transcription models.
   This makes the settings consistent across the different OpenAI client properties.
 - Add audio auto-conf activation tests

Co-authored-by: Christian Tzolov <ctzolov@vmware.com>
This commit is contained in:
Stefan Vassilev
2024-06-04 16:49:48 +03:00
committed by Christian Tzolov
parent dfabcc7f61
commit 91a0b2a272
4 changed files with 120 additions and 55 deletions

View File

@@ -28,6 +28,7 @@ import org.springframework.boot.context.properties.NestedConfigurationProperty;
* alloy, and speed = 1.
*
* @author Ahmed Yousri
* @author Stefan Vassilev
*/
@ConfigurationProperties(OpenAiAudioSpeechProperties.CONFIG_PREFIX)
public class OpenAiAudioSpeechProperties extends OpenAiParentProperties {
@@ -42,6 +43,11 @@ public class OpenAiAudioSpeechProperties extends OpenAiParentProperties {
private static final OpenAiAudioApi.SpeechRequest.AudioResponseFormat DEFAULT_RESPONSE_FORMAT = OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3;
/**
* Enable OpenAI audio speech model.
*/
private boolean enabled = true;
@NestedConfigurationProperty
private OpenAiAudioSpeechOptions options = OpenAiAudioSpeechOptions.builder()
.withModel(DEFAULT_SPEECH_MODEL)
@@ -58,4 +64,12 @@ public class OpenAiAudioSpeechProperties extends OpenAiParentProperties {
this.options = options;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}

View File

@@ -31,6 +31,11 @@ public class OpenAiAudioTranscriptionProperties extends OpenAiParentProperties {
private static final OpenAiAudioApi.TranscriptResponseFormat DEFAULT_RESPONSE_FORMAT = OpenAiAudioApi.TranscriptResponseFormat.TEXT;
/**
* Enable OpenAI audio transcription model.
*/
private boolean enabled = true;
@NestedConfigurationProperty
private OpenAiAudioTranscriptionOptions options = OpenAiAudioTranscriptionOptions.builder()
.withModel(DEFAULT_TRANSCRIPTION_MODEL)
@@ -46,4 +51,12 @@ public class OpenAiAudioTranscriptionProperties extends OpenAiParentProperties {
this.options = options;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}

View File

@@ -21,7 +21,6 @@ import org.springframework.ai.autoconfigure.retry.SpringAiRetryAutoConfiguration
import org.springframework.ai.model.function.FunctionCallback;
import org.springframework.ai.model.function.FunctionCallbackContext;
import org.springframework.ai.openai.*;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.ai.openai.api.OpenAiApi;
import org.springframework.ai.openai.api.OpenAiAudioApi;
import org.springframework.ai.openai.api.OpenAiImageApi;
@@ -45,6 +44,7 @@ import org.springframework.web.reactive.function.client.WebClient;
/**
* @author Christian Tzolov
* @author Stefan Vassilev
*/
@AutoConfiguration(after = { RestClientAutoConfiguration.class, WebClientAutoConfiguration.class,
SpringAiRetryAutoConfiguration.class })
@@ -132,6 +132,8 @@ public class OpenAiAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = OpenAiAudioTranscriptionProperties.CONFIG_PREFIX, name = "enabled",
havingValue = "true", matchIfMissing = true)
public OpenAiAudioTranscriptionModel openAiAudioTranscriptionModel(OpenAiConnectionProperties commonProperties,
OpenAiAudioTranscriptionProperties transcriptionProperties, RetryTemplate retryTemplate,
RestClient.Builder restClientBuilder, WebClient.Builder webClientBuilder,
@@ -157,6 +159,8 @@ public class OpenAiAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = OpenAiAudioSpeechProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
matchIfMissing = true)
public OpenAiAudioSpeechModel openAiAudioSpeechClient(OpenAiConnectionProperties commonProperties,
OpenAiAudioSpeechProperties speechProperties, RestClient.Builder restClientBuilder,
WebClient.Builder webClientBuilder, ResponseErrorHandler responseErrorHandler) {

View File

@@ -15,12 +15,14 @@
*/
package org.springframework.ai.autoconfigure.openai;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.Test;
import org.skyscreamer.jsonassert.JSONAssert;
import org.skyscreamer.jsonassert.JSONCompareMode;
import org.springframework.ai.autoconfigure.retry.SpringAiRetryAutoConfiguration;
import org.springframework.ai.model.ModelOptionsUtils;
import org.springframework.ai.openai.OpenAiAudioSpeechModel;
import org.springframework.ai.openai.OpenAiAudioTranscriptionModel;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.ai.openai.OpenAiEmbeddingModel;
import org.springframework.ai.openai.OpenAiImageModel;
@@ -29,12 +31,8 @@ import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionRequest.ToolCho
import org.springframework.ai.openai.api.OpenAiApi.FunctionTool.Type;
import org.springframework.ai.openai.api.OpenAiAudioApi;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration;
import org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Unit Tests for {@link OpenAiConnectionProperties}, {@link OpenAiChatProperties} and
* {@link OpenAiEmbeddingProperties}.
@@ -55,8 +53,7 @@ public class OpenAiPropertiesTests {
"spring.ai.openai.chat.options.model=MODEL_XYZ",
"spring.ai.openai.chat.options.temperature=0.55")
// @formatter:on
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class))
.run(context -> {
var chatProperties = context.getBean(OpenAiChatProperties.class);
var connectionProperties = context.getBean(OpenAiConnectionProperties.class);
@@ -82,8 +79,7 @@ public class OpenAiPropertiesTests {
"spring.ai.openai.audio.transcription.options.model=MODEL_XYZ",
"spring.ai.openai.audio.transcription.options.temperature=0.55")
// @formatter:on
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class))
.run(context -> {
var transcriptionProperties = context.getBean(OpenAiAudioTranscriptionProperties.class);
var connectionProperties = context.getBean(OpenAiConnectionProperties.class);
@@ -111,8 +107,7 @@ public class OpenAiPropertiesTests {
"spring.ai.openai.chat.options.model=MODEL_XYZ",
"spring.ai.openai.chat.options.temperature=0.55")
// @formatter:on
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class))
.run(context -> {
var chatProperties = context.getBean(OpenAiChatProperties.class);
var connectionProperties = context.getBean(OpenAiConnectionProperties.class);
@@ -140,8 +135,7 @@ public class OpenAiPropertiesTests {
"spring.ai.openai.audio.transcription.options.model=MODEL_XYZ",
"spring.ai.openai.audio.transcription.options.temperature=0.55")
// @formatter:on
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class))
.run(context -> {
var transcriptionProperties = context.getBean(OpenAiAudioTranscriptionProperties.class);
var connectionProperties = context.getBean(OpenAiConnectionProperties.class);
@@ -169,8 +163,7 @@ public class OpenAiPropertiesTests {
"spring.ai.openai.audio.speech.options.response-format=mp3",
"spring.ai.openai.audio.speech.options.speed=0.75")
// @formatter:on
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class))
.run(context -> {
var speechProperties = context.getBean(OpenAiAudioSpeechProperties.class);
var connectionProperties = context.getBean(OpenAiConnectionProperties.class);
@@ -201,8 +194,7 @@ public class OpenAiPropertiesTests {
"spring.ai.openai.audio.speech.options.response-format=mp3",
"spring.ai.openai.audio.speech.options.speed=0.75")
// @formatter:on
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class))
.run(context -> {
var speechProperties = context.getBean(OpenAiAudioSpeechProperties.class);
var connectionProperties = context.getBean(OpenAiConnectionProperties.class);
@@ -232,8 +224,7 @@ public class OpenAiPropertiesTests {
"spring.ai.openai.audio.speech.options.response-format=opus",
"spring.ai.openai.audio.speech.options.speed=0.5")
// @formatter:on
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class))
.run(context -> {
var speechProperties = context.getBean(OpenAiAudioSpeechProperties.class);
var connectionProperties = context.getBean(OpenAiConnectionProperties.class);
@@ -261,8 +252,7 @@ public class OpenAiPropertiesTests {
"spring.ai.openai.api-key=abc123",
"spring.ai.openai.embedding.options.model=MODEL_XYZ")
// @formatter:on
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class))
.run(context -> {
var embeddingProperties = context.getBean(OpenAiEmbeddingProperties.class);
var connectionProperties = context.getBean(OpenAiConnectionProperties.class);
@@ -288,8 +278,7 @@ public class OpenAiPropertiesTests {
"spring.ai.openai.embedding.api-key=456",
"spring.ai.openai.embedding.options.model=MODEL_XYZ")
// @formatter:on
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class))
.run(context -> {
var embeddingProperties = context.getBean(OpenAiEmbeddingProperties.class);
var connectionProperties = context.getBean(OpenAiConnectionProperties.class);
@@ -313,8 +302,7 @@ public class OpenAiPropertiesTests {
"spring.ai.openai.image.options.model=MODEL_XYZ",
"spring.ai.openai.image.options.n=3")
// @formatter:on
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class))
.run(context -> {
var imageProperties = context.getBean(OpenAiImageProperties.class);
var connectionProperties = context.getBean(OpenAiConnectionProperties.class);
@@ -341,8 +329,7 @@ public class OpenAiPropertiesTests {
"spring.ai.openai.image.options.model=MODEL_XYZ",
"spring.ai.openai.image.options.n=3")
// @formatter:on
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class))
.run(context -> {
var imageProperties = context.getBean(OpenAiImageProperties.class);
var connectionProperties = context.getBean(OpenAiConnectionProperties.class);
@@ -410,8 +397,7 @@ public class OpenAiPropertiesTests {
"spring.ai.openai.chat.options.user=userXYZ"
)
// @formatter:on
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class))
.run(context -> {
var chatProperties = context.getBean(OpenAiChatProperties.class);
var connectionProperties = context.getBean(OpenAiConnectionProperties.class);
@@ -464,8 +450,7 @@ public class OpenAiPropertiesTests {
"spring.ai.openai.audio.transcription.options.temperature=0.55"
)
// @formatter:on
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class))
.run(context -> {
var transcriptionProperties = context.getBean(OpenAiAudioTranscriptionProperties.class);
var connectionProperties = context.getBean(OpenAiConnectionProperties.class);
@@ -498,8 +483,7 @@ public class OpenAiPropertiesTests {
"spring.ai.openai.embedding.options.user=userXYZ"
)
// @formatter:on
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class))
.run(context -> {
var connectionProperties = context.getBean(OpenAiConnectionProperties.class);
var embeddingProperties = context.getBean(OpenAiEmbeddingProperties.class);
@@ -531,8 +515,7 @@ public class OpenAiPropertiesTests {
"spring.ai.openai.image.options.user=userXYZ"
)
// @formatter:on
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class))
.run(context -> {
var imageProperties = context.getBean(OpenAiImageProperties.class);
var connectionProperties = context.getBean(OpenAiConnectionProperties.class);
@@ -558,8 +541,7 @@ public class OpenAiPropertiesTests {
new ApplicationContextRunner()
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL",
"spring.ai.openai.embedding.enabled=false")
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class))
.run(context -> {
assertThat(context.getBeansOfType(OpenAiEmbeddingProperties.class)).isNotEmpty();
assertThat(context.getBeansOfType(OpenAiEmbeddingModel.class)).isEmpty();
@@ -567,8 +549,7 @@ public class OpenAiPropertiesTests {
new ApplicationContextRunner()
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL")
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class))
.run(context -> {
assertThat(context.getBeansOfType(OpenAiEmbeddingProperties.class)).isNotEmpty();
assertThat(context.getBeansOfType(OpenAiEmbeddingModel.class)).isNotEmpty();
@@ -577,8 +558,7 @@ public class OpenAiPropertiesTests {
new ApplicationContextRunner()
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL",
"spring.ai.openai.embedding.enabled=true")
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class))
.run(context -> {
assertThat(context.getBeansOfType(OpenAiEmbeddingProperties.class)).isNotEmpty();
assertThat(context.getBeansOfType(OpenAiEmbeddingModel.class)).isNotEmpty();
@@ -590,8 +570,7 @@ public class OpenAiPropertiesTests {
new ApplicationContextRunner()
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL",
"spring.ai.openai.chat.enabled=false")
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class))
.run(context -> {
assertThat(context.getBeansOfType(OpenAiChatProperties.class)).isNotEmpty();
assertThat(context.getBeansOfType(OpenAiChatModel.class)).isEmpty();
@@ -599,8 +578,7 @@ public class OpenAiPropertiesTests {
new ApplicationContextRunner()
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL")
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class))
.run(context -> {
assertThat(context.getBeansOfType(OpenAiChatProperties.class)).isNotEmpty();
assertThat(context.getBeansOfType(OpenAiChatModel.class)).isNotEmpty();
@@ -609,8 +587,7 @@ public class OpenAiPropertiesTests {
new ApplicationContextRunner()
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL",
"spring.ai.openai.chat.enabled=true")
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class))
.run(context -> {
assertThat(context.getBeansOfType(OpenAiChatProperties.class)).isNotEmpty();
assertThat(context.getBeansOfType(OpenAiChatModel.class)).isNotEmpty();
@@ -623,8 +600,7 @@ public class OpenAiPropertiesTests {
new ApplicationContextRunner()
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL",
"spring.ai.openai.image.enabled=false")
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class))
.run(context -> {
assertThat(context.getBeansOfType(OpenAiImageProperties.class)).isNotEmpty();
assertThat(context.getBeansOfType(OpenAiImageModel.class)).isEmpty();
@@ -632,8 +608,7 @@ public class OpenAiPropertiesTests {
new ApplicationContextRunner()
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL")
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class))
.run(context -> {
assertThat(context.getBeansOfType(OpenAiImageProperties.class)).isNotEmpty();
assertThat(context.getBeansOfType(OpenAiImageModel.class)).isNotEmpty();
@@ -642,8 +617,7 @@ public class OpenAiPropertiesTests {
new ApplicationContextRunner()
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL",
"spring.ai.openai.image.enabled=true")
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class))
.run(context -> {
assertThat(context.getBeansOfType(OpenAiImageProperties.class)).isNotEmpty();
assertThat(context.getBeansOfType(OpenAiImageModel.class)).isNotEmpty();
@@ -651,4 +625,64 @@ public class OpenAiPropertiesTests {
}
@Test
void audioSpeechActivation() {
new ApplicationContextRunner()
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL",
"spring.ai.openai.audio.speech.enabled=false")
.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class))
.run(context -> {
assertThat(context.getBeansOfType(OpenAiAudioSpeechProperties.class)).isNotEmpty();
assertThat(context.getBeansOfType(OpenAiAudioSpeechModel.class)).isEmpty();
});
new ApplicationContextRunner()
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL")
.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class))
.run(context -> {
assertThat(context.getBeansOfType(OpenAiAudioSpeechProperties.class)).isNotEmpty();
assertThat(context.getBeansOfType(OpenAiAudioSpeechModel.class)).isNotEmpty();
});
new ApplicationContextRunner()
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL",
"spring.ai.openai.audio.speech.enabled=true")
.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class))
.run(context -> {
assertThat(context.getBeansOfType(OpenAiAudioSpeechProperties.class)).isNotEmpty();
assertThat(context.getBeansOfType(OpenAiAudioSpeechModel.class)).isNotEmpty();
});
}
@Test
void audioTranscriptionActivation() {
new ApplicationContextRunner()
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL",
"spring.ai.openai.audio.transcription.enabled=false")
.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class))
.run(context -> {
assertThat(context.getBeansOfType(OpenAiAudioTranscriptionProperties.class)).isNotEmpty();
assertThat(context.getBeansOfType(OpenAiAudioTranscriptionModel.class)).isEmpty();
});
new ApplicationContextRunner()
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL")
.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class))
.run(context -> {
assertThat(context.getBeansOfType(OpenAiAudioTranscriptionProperties.class)).isNotEmpty();
assertThat(context.getBeansOfType(OpenAiAudioTranscriptionModel.class)).isNotEmpty();
});
new ApplicationContextRunner()
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL",
"spring.ai.openai.audio.transcription.enabled=true")
.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class))
.run(context -> {
assertThat(context.getBeansOfType(OpenAiAudioTranscriptionProperties.class)).isNotEmpty();
assertThat(context.getBeansOfType(OpenAiAudioTranscriptionModel.class)).isNotEmpty();
});
}
}