diff --git a/.fern/metadata.json b/.fern/metadata.json index 6620043..5e8f480 100644 --- a/.fern/metadata.json +++ b/.fern/metadata.json @@ -11,8 +11,8 @@ }, "enable-wire-tests": true }, - "originGitCommit": "335af96251466afae7a9f71badb65c630a48626e", + "originGitCommit": "14c0ca94fcd0279d99570389d7b688dc3a18ea41", "originGitCommitIsDirty": true, "invokedBy": "manual", - "sdkVersion": "0.6.0" + "sdkVersion": "0.6.1" } \ No newline at end of file diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1InjectAgentMessage.java b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1InjectAgentMessage.java index cb3a41c..88be5ed 100644 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1InjectAgentMessage.java +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1InjectAgentMessage.java @@ -57,6 +57,7 @@ public String getMessage() { *
default — The agent speaks only if neither the user nor the agent is mid-turn. If a turn is in progress, the server replies with InjectionRefused.queue — The message is appended after any already-queued ConversationText without interrupting the current agent turn or think response. If nothing is queued, the message plays immediately.interrupt — The agent immediately speaks. If the agent was already speaking, it interrupts the current speech and replaces it with the new message. If the user is speaking, the agent interrupts with the new message, but the user's continued speech triggers UserStartedSpeaking, which quickly interrupts the agent.default — The agent speaks only if neither the user nor the agent is mid-turn. If a turn is in progress, the server replies with InjectionRefused.queue — The message is appended after any already-queued ConversationText without interrupting the current agent turn or think response. If nothing is queued, the message plays immediately.interrupt — The agent immediately speaks. If the agent was already speaking, it interrupts the current speech and replaces it with the new message. If the user is speaking, the agent interrupts with the new message, but the user's continued speech triggers UserStartedSpeaking, which quickly interrupts the agent.default — The agent speaks only if neither the user nor the agent is mid-turn. If a turn is in progress, the server replies with InjectionRefused.queue — The message is appended after any already-queued ConversationText without interrupting the current agent turn or think response. If nothing is queued, the message plays immediately.interrupt — The agent immediately speaks. If the agent was already speaking, it interrupts the current speech and replaces it with the new message. If the user is speaking, the agent interrupts with the new message, but the user's continued speech triggers UserStartedSpeaking, which quickly interrupts the agent.default — The agent speaks only if neither the user nor the agent is mid-turn. If a turn is in progress, the server replies with InjectionRefused.queue — The message is appended after any already-queued ConversationText without interrupting the current agent turn or think response. If nothing is queued, the message plays immediately.interrupt — The agent immediately speaks. If the agent was already speaking, it interrupts the current speech and replaces it with the new message. If the user is speaking, the agent interrupts with the new message, but the user's continued speech triggers UserStartedSpeaking, which quickly interrupts the agent.Speech-to-text: time from audio received to transcript produced, in seconds
+ */ + @JsonSetter(value = "stt_latency", nulls = Nulls.SKIP) + public Builder sttLatency(OptionalTime to first token of any type (text, tool call, or thinking), in seconds
+ */ + @JsonSetter(value = "ttt_token_latency", nulls = Nulls.SKIP) + public Builder tttTokenLatency(OptionalTime to first text token from the LLM, in seconds
+ */ + @JsonSetter(value = "ttt_text_latency", nulls = Nulls.SKIP) + public Builder tttTextLatency(OptionalTime to first tool-call token from the LLM, in seconds
+ */ + @JsonSetter(value = "ttt_tool_latency", nulls = Nulls.SKIP) + public Builder tttToolLatency(OptionalTime to first thinking token from the LLM, in seconds
+ */ + @JsonSetter(value = "ttt_thinking_latency", nulls = Nulls.SKIP) + public Builder tttThinkingLatency(OptionalText-to-speech: time from first text token to first audio byte, in seconds
+ */ + @JsonSetter(value = "tts_latency", nulls = Nulls.SKIP) + public Builder ttsLatency(OptionalEnd-to-end: time from user utterance end to first audio byte, in seconds
+ */ + @JsonSetter(value = "total_latency", nulls = Nulls.SKIP) + public Builder totalLatency(Optionalflux-{voice}-{language} (for example, flux-alexis-en). Required; unlike the v1 (Aura) endpoint there is no default and only flux models are accepted. English-only at launch. The voice catalog is not yet finalized, so this is typed as a free-form string rather than a closed enum; it can be locked to an enum (matching STT Flux ListenV2Model) once the GA catalog is confirmed.
+ */
+ @JsonIgnore
+ public String getModel() {
+ return model;
+ }
+
+ /**
+ * @return Sample Rate specifies the sample rate for the output audio. Based on the encoding, different sample rates are supported. For some encodings, the sample rate is not configurable
+ */
+ @JsonIgnore
+ public OptionalFlux TTS model used to synthesize the submitted text, in the form flux-{voice}-{language} (for example, flux-alexis-en). Required; unlike the v1 (Aura) endpoint there is no default and only flux models are accepted. English-only at launch. The voice catalog is not yet finalized, so this is typed as a free-form string rather than a closed enum; it can be locked to an enum (matching STT Flux ListenV2Model) once the GA catalog is confirmed.
The text content to be converted to speech. The server normalizes and preprocesses the text (e.g. stripping inline controls) before synthesis.
+ */ + _FinalStage text(@NotNull String text); + } + + public interface _FinalStage { + SpeakV2Request build(); + + _FinalStage additionalProperty(String key, Object value); + + _FinalStage additionalProperties(MapLabel your requests for the purpose of identification during usage reporting
+ */ + _FinalStage tag(OptionalURL to which we'll make the callback request
+ */ + _FinalStage callback(OptionalHTTP method by which the callback request will be made
+ */ + _FinalStage callbackMethod(OptionalOpts out requests from the Deepgram Model Improvement Program. Refer to our Docs for pricing impacts before setting this to true. https://dpgr.am/deepgram-mip
+ */ + _FinalStage mipOptOut(OptionalThe bitrate of the audio in bits per second. Choose from predefined ranges or specific values based on the encoding type.
+ */ + _FinalStage bitRate(OptionalContainer specifies the file format wrapper for the output audio. The available options depend on the encoding type.
+ */ + _FinalStage container(OptionalEncoding allows you to specify the expected encoding of your audio output
+ */ + _FinalStage encoding(OptionalSample Rate specifies the sample rate for the output audio. Based on the encoding, different sample rates are supported. For some encodings, the sample rate is not configurable
+ */ + _FinalStage sampleRate(OptionalProcessing priority for asynchronous (callback) requests. The only supported value is low.
+ */ + _FinalStage priority(OptionalFlux TTS model used to synthesize the submitted text, in the form flux-{voice}-{language} (for example, flux-alexis-en). Required; unlike the v1 (Aura) endpoint there is no default and only flux models are accepted. English-only at launch. The voice catalog is not yet finalized, so this is typed as a free-form string rather than a closed enum; it can be locked to an enum (matching STT Flux ListenV2Model) once the GA catalog is confirmed.
Flux TTS model used to synthesize the submitted text, in the form flux-{voice}-{language} (for example, flux-alexis-en). Required; unlike the v1 (Aura) endpoint there is no default and only flux models are accepted. English-only at launch. The voice catalog is not yet finalized, so this is typed as a free-form string rather than a closed enum; it can be locked to an enum (matching STT Flux ListenV2Model) once the GA catalog is confirmed.
The text content to be converted to speech. The server normalizes and preprocesses the text (e.g. stripping inline controls) before synthesis.
+ *The text content to be converted to speech. The server normalizes and preprocesses the text (e.g. stripping inline controls) before synthesis.
+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + @JsonSetter("text") + public _FinalStage text(@NotNull String text) { + this.text = Objects.requireNonNull(text, "text must not be null"); + return this; + } + + /** + *Processing priority for asynchronous (callback) requests. The only supported value is low.
+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + public _FinalStage priority(String priority) { + this.priority = Optional.ofNullable(priority); + return this; + } + + /** + *Processing priority for asynchronous (callback) requests. The only supported value is low.
+ */ + @java.lang.Override + @JsonSetter(value = "priority", nulls = Nulls.SKIP) + public _FinalStage priority(OptionalSample Rate specifies the sample rate for the output audio. Based on the encoding, different sample rates are supported. For some encodings, the sample rate is not configurable
+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + public _FinalStage sampleRate(Integer sampleRate) { + this.sampleRate = Optional.ofNullable(sampleRate); + return this; + } + + /** + *Sample Rate specifies the sample rate for the output audio. Based on the encoding, different sample rates are supported. For some encodings, the sample rate is not configurable
+ */ + @java.lang.Override + @JsonSetter(value = "sample_rate", nulls = Nulls.SKIP) + public _FinalStage sampleRate(OptionalEncoding allows you to specify the expected encoding of your audio output
+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + public _FinalStage encoding(AudioGenerateRequestEncoding encoding) { + this.encoding = Optional.ofNullable(encoding); + return this; + } + + /** + *Encoding allows you to specify the expected encoding of your audio output
+ */ + @java.lang.Override + @JsonSetter(value = "encoding", nulls = Nulls.SKIP) + public _FinalStage encoding(OptionalContainer specifies the file format wrapper for the output audio. The available options depend on the encoding type.
+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + public _FinalStage container(AudioGenerateRequestContainer container) { + this.container = Optional.ofNullable(container); + return this; + } + + /** + *Container specifies the file format wrapper for the output audio. The available options depend on the encoding type.
+ */ + @java.lang.Override + @JsonSetter(value = "container", nulls = Nulls.SKIP) + public _FinalStage container(OptionalThe bitrate of the audio in bits per second. Choose from predefined ranges or specific values based on the encoding type.
+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + public _FinalStage bitRate(Integer bitRate) { + this.bitRate = Optional.ofNullable(bitRate); + return this; + } + + /** + *The bitrate of the audio in bits per second. Choose from predefined ranges or specific values based on the encoding type.
+ */ + @java.lang.Override + @JsonSetter(value = "bit_rate", nulls = Nulls.SKIP) + public _FinalStage bitRate(OptionalOpts out requests from the Deepgram Model Improvement Program. Refer to our Docs for pricing impacts before setting this to true. https://dpgr.am/deepgram-mip
+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + public _FinalStage mipOptOut(Boolean mipOptOut) { + this.mipOptOut = Optional.ofNullable(mipOptOut); + return this; + } + + /** + *Opts out requests from the Deepgram Model Improvement Program. Refer to our Docs for pricing impacts before setting this to true. https://dpgr.am/deepgram-mip
+ */ + @java.lang.Override + @JsonSetter(value = "mip_opt_out", nulls = Nulls.SKIP) + public _FinalStage mipOptOut(OptionalHTTP method by which the callback request will be made
+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + public _FinalStage callbackMethod(AudioGenerateRequestCallbackMethod callbackMethod) { + this.callbackMethod = Optional.ofNullable(callbackMethod); + return this; + } + + /** + *HTTP method by which the callback request will be made
+ */ + @java.lang.Override + @JsonSetter(value = "callback_method", nulls = Nulls.SKIP) + public _FinalStage callbackMethod(OptionalURL to which we'll make the callback request
+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + public _FinalStage callback(String callback) { + this.callback = Optional.ofNullable(callback); + return this; + } + + /** + *URL to which we'll make the callback request
+ */ + @java.lang.Override + @JsonSetter(value = "callback", nulls = Nulls.SKIP) + public _FinalStage callback(OptionalLabel your requests for the purpose of identification during usage reporting
+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + public _FinalStage tag(ListLabel your requests for the purpose of identification during usage reporting
+ */ + @java.lang.Override + @JsonSetter(value = "tag", nulls = Nulls.SKIP) + public _FinalStage tag(OptionalUnique identifier for tracking the asynchronous request
+ */ + _FinalStage requestId(@NotNull String requestId); + + Builder from(SpeakV2AcceptedResponse other); + } + + public interface _FinalStage { + SpeakV2AcceptedResponse build(); + + _FinalStage additionalProperty(String key, Object value); + + _FinalStage additionalProperties(MapUnique identifier for tracking the asynchronous request
+ *Unique identifier for tracking the asynchronous request
+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + @JsonSetter("request_id") + public _FinalStage requestId(@NotNull String requestId) { + this.requestId = Objects.requireNonNull(requestId, "requestId must not be null"); + return this; + } + + @java.lang.Override + public SpeakV2AcceptedResponse build() { + return new SpeakV2AcceptedResponse(requestId, additionalProperties); + } + + @java.lang.Override + public Builder additionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + return this; + } + + @java.lang.Override + public Builder additionalProperties(MapThe Fern generator did not emit a wire test for this endpoint, so this fills the gap. It asserts + * the outgoing request shape (POST /v2/speak, {@code model}/{@code encoding} in the query, {@code text} + * in the JSON body), that the binary audio response is returned as an {@link InputStream}, and that + * integer {@code sample_rate}/{@code bit_rate} serialize WITHOUT a decimal — stem parses these as a + * nonzero u32 and rejects {@code "24000.0"}, so this guards the spec's {@code type: integer} typing + * against a future regen. Frozen via {@code src/test/} in .fernignore. + */ +class SpeakV2BatchTest { + private static final byte[] AUDIO = new byte[] {(byte) 0xFF, (byte) 0xFB, (byte) 0x90, 0x00, 0x11, 0x22, 0x33, 0x44}; + + private MockWebServer server; + private DeepgramClient client; + + @BeforeEach + void setUp() throws Exception { + server = new MockWebServer(); + server.start(); + String base = server.url("/").toString().replaceAll("/$", ""); + Environment env = Environment.custom().base(base).production(base).agent(base).agentRest(base).build(); + client = DeepgramClient.builder().apiKey("test").environment(env).build(); + } + + @AfterEach + void tearDown() throws Exception { + server.shutdown(); + } + + private void enqueueAudio() { + server.enqueue(new MockResponse() + .setResponseCode(200) + .addHeader("Content-Type", "audio/mpeg") + .setBody(new Buffer().write(AUDIO))); + } + + @Test + @DisplayName("issues POST /v2/speak with model in query + text in body, and returns the audio bytes") + void batchRequestShape() throws Exception { + enqueueAudio(); + + InputStream response = client.speak() + .v2() + .audio() + .generate(SpeakV2Request.builder() + .model("flux-alexis-en") + .text("Hello from the batch endpoint.") + .encoding(AudioGenerateRequestEncoding.MP3) + .build()); + byte[] audio = response.readAllBytes(); + + RecordedRequest request = server.takeRequest(); + assertThat(request.getMethod()).isEqualTo("POST"); + HttpUrl url = request.getRequestUrl(); + assertThat(url.encodedPath()).isEqualTo("/v2/speak"); + assertThat(url.queryParameter("model")).isEqualTo("flux-alexis-en"); + assertThat(url.queryParameter("encoding")).isEqualTo("mp3"); + assertThat(request.getBody().readUtf8()).contains("\"text\":\"Hello from the batch endpoint.\""); + assertThat(audio).isEqualTo(AUDIO); + } + + @Test + @DisplayName("serializes integer sample_rate/bit_rate without a decimal (guards the type: integer fix)") + void integerSampleRateAndBitRate() throws Exception { + enqueueAudio(); + + client.speak() + .v2() + .audio() + .generate(SpeakV2Request.builder() + .model("flux-alexis-en") + .text("hi") + .encoding(AudioGenerateRequestEncoding.LINEAR16) + .sampleRate(24000) + .bitRate(48000) + .build()) + .readAllBytes(); + + HttpUrl url = server.takeRequest().getRequestUrl(); + assertThat(url.queryParameter("sample_rate")).isEqualTo("24000"); + assertThat(url.queryParameter("bit_rate")).isEqualTo("48000"); + // Must NOT be "24000.0" — stem rejects a non-integer with "expected a nonzero u32". + assertThat(url.queryParameter("sample_rate")).doesNotContain("."); + assertThat(url.queryParameter("bit_rate")).doesNotContain("."); + } +}