diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/main/java/org/springframework/ai/model/openai/autoconfigure/OpenAiAudioSpeechProperties.java b/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/main/java/org/springframework/ai/model/openai/autoconfigure/OpenAiAudioSpeechProperties.java index 98a12d12b..d9c9c7a44 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/main/java/org/springframework/ai/model/openai/autoconfigure/OpenAiAudioSpeechProperties.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/main/java/org/springframework/ai/model/openai/autoconfigure/OpenAiAudioSpeechProperties.java @@ -29,6 +29,7 @@ import org.springframework.boot.context.properties.NestedConfigurationProperty; * * @author Ahmed Yousri * @author Stefan Vassilev + * @author Jonghoon Park */ @ConfigurationProperties(OpenAiAudioSpeechProperties.CONFIG_PREFIX) public class OpenAiAudioSpeechProperties extends OpenAiParentProperties { @@ -39,7 +40,7 @@ public class OpenAiAudioSpeechProperties extends OpenAiParentProperties { private static final Float SPEED = 1.0f; - private static final OpenAiAudioApi.SpeechRequest.Voice VOICE = OpenAiAudioApi.SpeechRequest.Voice.ALLOY; + private static final String VOICE = OpenAiAudioApi.SpeechRequest.Voice.ALLOY.getValue(); private static final OpenAiAudioApi.SpeechRequest.AudioResponseFormat DEFAULT_RESPONSE_FORMAT = OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/test/java/org/springframework/ai/model/openai/autoconfigure/OpenAiPropertiesTests.java b/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/test/java/org/springframework/ai/model/openai/autoconfigure/OpenAiPropertiesTests.java index 1e3098a7f..b1c547eec 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/test/java/org/springframework/ai/model/openai/autoconfigure/OpenAiPropertiesTests.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/test/java/org/springframework/ai/model/openai/autoconfigure/OpenAiPropertiesTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 the original author or authors. + * Copyright 2023-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,6 +40,7 @@ import static org.assertj.core.api.Assertions.assertThat; * * @author Christian Tzolov * @author Thomas Vitale + * @author Jonghoon Park * @since 0.8.0 */ public class OpenAiPropertiesTests { @@ -177,7 +178,7 @@ public class OpenAiPropertiesTests { assertThat(speechProperties.getOptions().getModel()).isEqualTo("TTS_1"); assertThat(speechProperties.getOptions().getVoice()) - .isEqualTo(OpenAiAudioApi.SpeechRequest.Voice.ALLOY); + .isEqualTo(OpenAiAudioApi.SpeechRequest.Voice.ALLOY.getValue()); assertThat(speechProperties.getOptions().getResponseFormat()) .isEqualTo(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3); assertThat(speechProperties.getOptions().getSpeed()).isEqualTo(0.75f); @@ -205,7 +206,7 @@ public class OpenAiPropertiesTests { assertThat(speechProperties.getOptions().getModel()).isEqualTo("TTS_1"); assertThat(speechProperties.getOptions().getVoice()) - .isEqualTo(OpenAiAudioApi.SpeechRequest.Voice.ALLOY); + .isEqualTo(OpenAiAudioApi.SpeechRequest.Voice.ALLOY.getValue()); assertThat(speechProperties.getOptions().getResponseFormat()) .isEqualTo(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3); assertThat(speechProperties.getOptions().getSpeed()).isEqualTo(0.75f); @@ -237,7 +238,8 @@ public class OpenAiPropertiesTests { assertThat(speechProperties.getBaseUrl()).isEqualTo("TEST_BASE_URL2"); assertThat(speechProperties.getOptions().getModel()).isEqualTo("TTS_2"); - assertThat(speechProperties.getOptions().getVoice()).isEqualTo(OpenAiAudioApi.SpeechRequest.Voice.ECHO); + assertThat(speechProperties.getOptions().getVoice()) + .isEqualTo(OpenAiAudioApi.SpeechRequest.Voice.ECHO.getValue()); assertThat(speechProperties.getOptions().getResponseFormat()) .isEqualTo(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.OPUS); assertThat(speechProperties.getOptions().getSpeed()).isEqualTo(0.5f); diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiAudioSpeechModel.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiAudioSpeechModel.java index baf772ed4..2ea526222 100644 --- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiAudioSpeechModel.java +++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiAudioSpeechModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 the original author or authors. + * Copyright 2023-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,6 +42,7 @@ import org.springframework.util.Assert; * @author Ahmed Yousri * @author Hyunjoon Choi * @author Thomas Vitale + * @author Jonghoon Park * @see OpenAiAudioApi * @since 1.0.0-M1 */ @@ -81,7 +82,7 @@ public class OpenAiAudioSpeechModel implements SpeechModel, StreamingSpeechModel OpenAiAudioSpeechOptions.builder() .model(OpenAiAudioApi.TtsModel.TTS_1.getValue()) .responseFormat(AudioResponseFormat.MP3) - .voice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY) + .voice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY.getValue()) .speed(SPEED) .build()); } diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiAudioSpeechOptions.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiAudioSpeechOptions.java index 6e9fcdb87..6e5d1a8ec 100644 --- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiAudioSpeechOptions.java +++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiAudioSpeechOptions.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 the original author or authors. + * Copyright 2023-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,14 +29,15 @@ import org.springframework.ai.openai.api.OpenAiAudioApi.SpeechRequest.Voice; * @author Ahmed Yousri * @author Hyunjoon Choi * @author Ilayaperumal Gopinathan + * @author Jonghoon Park * @since 1.0.0-M1 */ @JsonInclude(JsonInclude.Include.NON_NULL) public class OpenAiAudioSpeechOptions implements ModelOptions { /** - * ID of the model to use for generating the audio. One of the available TTS models: - * tts-1 or tts-1-hd. + * ID of the model to use for generating the audio. For OpenAI's TTS API, use one of + * the available models: tts-1 or tts-1-hd. */ @JsonProperty("model") private String model; @@ -48,11 +49,11 @@ public class OpenAiAudioSpeechOptions implements ModelOptions { private String input; /** - * The voice to use for synthesis. One of the available voices for the chosen model: - * 'alloy', 'echo', 'fable', 'onyx', 'nova', and 'shimmer'. + * The voice to use for synthesis. For OpenAI's TTS API, One of the available voices + * for the chosen model: 'alloy', 'echo', 'fable', 'onyx', 'nova', and 'shimmer'. */ @JsonProperty("voice") - private Voice voice; + private String voice; /** * The format of the audio output. Supported formats are mp3, opus, aac, and flac. @@ -88,14 +89,18 @@ public class OpenAiAudioSpeechOptions implements ModelOptions { this.input = input; } - public Voice getVoice() { + public String getVoice() { return this.voice; } - public void setVoice(Voice voice) { + public void setVoice(String voice) { this.voice = voice; } + public void setVoice(Voice voice) { + this.voice = voice.getValue(); + } + public AudioResponseFormat getResponseFormat() { return this.responseFormat; } @@ -197,11 +202,16 @@ public class OpenAiAudioSpeechOptions implements ModelOptions { return this; } - public Builder voice(Voice voice) { + public Builder voice(String voice) { this.options.voice = voice; return this; } + public Builder voice(Voice voice) { + this.options.voice = voice.getValue(); + return this; + } + public Builder responseFormat(AudioResponseFormat responseFormat) { this.options.responseFormat = responseFormat; return this; diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiAudioApi.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiAudioApi.java index 83eb491c0..8974081b2 100644 --- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiAudioApi.java +++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiAudioApi.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 the original author or authors. + * Copyright 2023-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,6 +47,7 @@ import org.springframework.web.reactive.function.client.WebClient; * * @author Christian Tzolov * @author Ilayaperumal Gopinathan + * @author Jonghoon Park * @since 0.8.1 */ public class OpenAiAudioApi { @@ -330,7 +331,7 @@ public class OpenAiAudioApi { // @formatter:off @JsonProperty("model") String model, @JsonProperty("input") String input, - @JsonProperty("voice") Voice voice, + @JsonProperty("voice") String voice, @JsonProperty("response_format") AudioResponseFormat responseFormat, @JsonProperty("speed") Float speed) { // @formatter:on @@ -419,7 +420,7 @@ public class OpenAiAudioApi { private String input; - private Voice voice; + private String voice; private AudioResponseFormat responseFormat = AudioResponseFormat.MP3; @@ -435,11 +436,16 @@ public class OpenAiAudioApi { return this; } - public Builder voice(Voice voice) { + public Builder voice(String voice) { this.voice = voice; return this; } + public Builder voice(Voice voice) { + this.voice = voice.getValue(); + return this; + } + public Builder responseFormat(AudioResponseFormat responseFormat) { this.responseFormat = responseFormat; return this; diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/api/OpenAiAudioApiIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/api/OpenAiAudioApiIT.java index 4b4fd9d24..6c933dec2 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/api/OpenAiAudioApiIT.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/api/OpenAiAudioApiIT.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 the original author or authors. + * Copyright 2023-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,6 +37,7 @@ import static org.assertj.core.api.Assertions.assertThat; /** * @author Christian Tzolov + * @author Jonghoon Park */ @EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+") public class OpenAiAudioApiIT { @@ -53,7 +54,7 @@ public class OpenAiAudioApiIT { .createSpeech(SpeechRequest.builder() .model(TtsModel.TTS_1_HD.getValue()) .input("Hello, my name is Chris and I love Spring A.I.") - .voice(Voice.ONYX) + .voice(Voice.ONYX.getValue()) .build()) .getBody(); diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/api/OpenAiAudioModelNoOpApiKeysIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/api/OpenAiAudioModelNoOpApiKeysIT.java index 2f0e09888..247dd76d4 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/api/OpenAiAudioModelNoOpApiKeysIT.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/api/OpenAiAudioModelNoOpApiKeysIT.java @@ -31,6 +31,7 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; /** * @author Ilayaperumal Gopinathan + * @author Jonghoon Park */ @SpringBootTest(classes = OpenAiAudioModelNoOpApiKeysIT.Config.class) @EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+") @@ -46,7 +47,7 @@ public class OpenAiAudioModelNoOpApiKeysIT { .createSpeech(OpenAiAudioApi.SpeechRequest.builder() .model(OpenAiAudioApi.TtsModel.TTS_1_HD.getValue()) .input("Hello, my name is Chris and I love Spring A.I.") - .voice(OpenAiAudioApi.SpeechRequest.Voice.ONYX) + .voice(OpenAiAudioApi.SpeechRequest.Voice.ONYX.getValue()) .build()) .getBody(); }).isInstanceOf(NonTransientAiException.class); diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/speech/OpenAiSpeechModelIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/speech/OpenAiSpeechModelIT.java index 8bfa2f90e..7f4a81d3e 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/speech/OpenAiSpeechModelIT.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/speech/OpenAiSpeechModelIT.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 the original author or authors. + * Copyright 2023-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,6 +33,10 @@ import org.springframework.boot.test.context.SpringBootTest; import static org.assertj.core.api.Assertions.assertThat; +/** + * @author Ahmed Yousri + * @author Jonghoon Park + */ @SpringBootTest(classes = OpenAiTestConfiguration.class) @EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+") class OpenAiSpeechModelIT extends AbstractIT { @@ -57,7 +61,7 @@ class OpenAiSpeechModelIT extends AbstractIT { @Test void shouldGenerateNonEmptyMp3AudioFromSpeechPrompt() { OpenAiAudioSpeechOptions speechOptions = OpenAiAudioSpeechOptions.builder() - .voice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY) + .voice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY.getValue()) .speed(SPEED) .responseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3) .model(OpenAiAudioApi.TtsModel.TTS_1.value) @@ -93,7 +97,7 @@ class OpenAiSpeechModelIT extends AbstractIT { @Test void speechRateLimitTest() { OpenAiAudioSpeechOptions speechOptions = OpenAiAudioSpeechOptions.builder() - .voice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY) + .voice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY.getValue()) .speed(SPEED) .responseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3) .model(OpenAiAudioApi.TtsModel.TTS_1.value) @@ -113,7 +117,7 @@ class OpenAiSpeechModelIT extends AbstractIT { void shouldStreamNonEmptyResponsesForValidSpeechPrompts() { OpenAiAudioSpeechOptions speechOptions = OpenAiAudioSpeechOptions.builder() - .voice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY) + .voice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY.getValue()) .speed(SPEED) .responseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3) .model(OpenAiAudioApi.TtsModel.TTS_1.value) @@ -135,7 +139,7 @@ class OpenAiSpeechModelIT extends AbstractIT { @ValueSource(strings = { "alloy", "echo", "fable", "onyx", "nova", "shimmer", "sage", "coral", "ash" }) void speechVoicesTest(String voice) { OpenAiAudioSpeechOptions speechOptions = OpenAiAudioSpeechOptions.builder() - .voice(OpenAiAudioApi.SpeechRequest.Voice.valueOf(voice.toUpperCase())) + .voice(voice) .speed(SPEED) .responseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3) .model(OpenAiAudioApi.TtsModel.TTS_1.value) diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/speech/OpenAiSpeechModelWithSpeechResponseMetadataTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/speech/OpenAiSpeechModelWithSpeechResponseMetadataTests.java index 3a6c4b2d1..9d98b5d9b 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/speech/OpenAiSpeechModelWithSpeechResponseMetadataTests.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/speech/OpenAiSpeechModelWithSpeechResponseMetadataTests.java @@ -46,6 +46,7 @@ import static org.springframework.test.web.client.response.MockRestResponseCreat /** * @author Ahmed Yousri + * @author Jonghoon Park */ @RestClientTest(OpenAiSpeechModelWithSpeechResponseMetadataTests.Config.class) public class OpenAiSpeechModelWithSpeechResponseMetadataTests { @@ -71,7 +72,7 @@ public class OpenAiSpeechModelWithSpeechResponseMetadataTests { prepareMock(); OpenAiAudioSpeechOptions speechOptions = OpenAiAudioSpeechOptions.builder() - .voice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY) + .voice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY.getValue()) .speed(SPEED) .responseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3) .model(OpenAiAudioApi.TtsModel.TTS_1.value) diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/audio/speech/openai-speech.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/audio/speech/openai-speech.adoc index 4f5a13a88..6b6060c8f 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/audio/speech/openai-speech.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/audio/speech/openai-speech.adoc @@ -85,8 +85,8 @@ The prefix `spring.ai.openai.audio.speech` is used as the property prefix that l | spring.ai.openai.audio.speech.api-key | The API Key | - | spring.ai.openai.audio.speech.organization-id | Optionally you can specify which organization used for an API request. | - | spring.ai.openai.audio.speech.project-id | Optionally, you can specify which project is used for an API request. | - -| spring.ai.openai.audio.speech.options.model | ID of the model to use. Only tts-1 is currently available. | tts-1 -| spring.ai.openai.audio.speech.options.voice | The voice to use for the TTS output. Available options are: alloy, echo, fable, onyx, nova, and shimmer. | alloy +| spring.ai.openai.audio.speech.options.model | ID of the model to use for generating the audio. For OpenAI's TTS API, use one of the available models: tts-1 or tts-1-hd. | tts-1 +| spring.ai.openai.audio.speech.options.voice | The voice to use for synthesis. For OpenAI's TTS API, One of the available voices for the chosen model: alloy, echo, fable, onyx, nova, and shimmer. | alloy | spring.ai.openai.audio.speech.options.response-format | The format of the audio output. Supported formats are mp3, opus, aac, flac, wav, and pcm. | mp3 | spring.ai.openai.audio.speech.options.speed | The speed of the voice synthesis. The acceptable range is from 0.25 (slowest) to 4.0 (fastest). | 1.0 |==== @@ -113,8 +113,8 @@ OpenAiAudioSpeechOptions speechOptions = OpenAiAudioSpeechOptions.builder() .speed(1.0f) .build(); -SpeechPrompt speechPrompt = new SpeechPrompt("Hello, this is a text-to-speech example.", this.speechOptions); -SpeechResponse response = openAiAudioSpeechModel.call(this.speechPrompt); +SpeechPrompt speechPrompt = new SpeechPrompt("Hello, this is a text-to-speech example.", speechOptions); +SpeechResponse response = openAiAudioSpeechModel.call(speechPrompt); ---- == Manual Configuration @@ -144,9 +144,11 @@ Next, create an `OpenAiAudioSpeechModel`: [source,java] ---- -var openAiAudioApi = new OpenAiAudioApi(System.getenv("OPENAI_API_KEY")); +var openAiAudioApi = new OpenAiAudioApi() + .apiKey(System.getenv("OPENAI_API_KEY")) + .build(); -var openAiAudioSpeechModel = new OpenAiAudioSpeechModel(this.openAiAudioApi); +var openAiAudioSpeechModel = new OpenAiAudioSpeechModel(openAiAudioApi); var speechOptions = OpenAiAudioSpeechOptions.builder() .responseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3) @@ -154,13 +156,13 @@ var speechOptions = OpenAiAudioSpeechOptions.builder() .model(OpenAiAudioApi.TtsModel.TTS_1.value) .build(); -var speechPrompt = new SpeechPrompt("Hello, this is a text-to-speech example.", this.speechOptions); -SpeechResponse response = this.openAiAudioSpeechModel.call(this.speechPrompt); +var speechPrompt = new SpeechPrompt("Hello, this is a text-to-speech example.", speechOptions); +SpeechResponse response = openAiAudioSpeechModel.call(speechPrompt); // Accessing metadata (rate limit info) -OpenAiAudioSpeechResponseMetadata metadata = this.response.getMetadata(); +OpenAiAudioSpeechResponseMetadata metadata = response.getMetadata(); -byte[] responseAsBytes = this.response.getResult().getOutput(); +byte[] responseAsBytes = response.getResult().getOutput(); ---- == Streaming Real-time Audio @@ -169,9 +171,11 @@ The Speech API provides support for real-time audio streaming using chunk transf [source,java] ---- -var openAiAudioApi = new OpenAiAudioApi(System.getenv("OPENAI_API_KEY")); +var openAiAudioApi = new OpenAiAudioApi() + .apiKey(System.getenv("OPENAI_API_KEY")) + .build(); -var openAiAudioSpeechModel = new OpenAiAudioSpeechModel(this.openAiAudioApi); +var openAiAudioSpeechModel = new OpenAiAudioSpeechModel(openAiAudioApi); OpenAiAudioSpeechOptions speechOptions = OpenAiAudioSpeechOptions.builder() .voice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY) @@ -180,9 +184,9 @@ OpenAiAudioSpeechOptions speechOptions = OpenAiAudioSpeechOptions.builder() .model(OpenAiAudioApi.TtsModel.TTS_1.value) .build(); -SpeechPrompt speechPrompt = new SpeechPrompt("Today is a wonderful day to build something people love!", this.speechOptions); +SpeechPrompt speechPrompt = new SpeechPrompt("Today is a wonderful day to build something people love!", speechOptions); -Flux responseStream = this.openAiAudioSpeechModel.stream(this.speechPrompt); +Flux responseStream = openAiAudioSpeechModel.stream(speechPrompt); ---- == Example Code