From e730ffd712db4ed1cc531390a9a8dfd6cf618dcd Mon Sep 17 00:00:00 2001 From: Greg Holmes Date: Wed, 14 Oct 2026 09:39:25 +0100 Subject: [PATCH 1/8] chore: initialize SDK regeneration branch From e6026b5cdad89ef6487ea34df6262a97942525c9 Mon Sep 17 00:00:00 2001 From: Greg Holmes Date: Wed, 14 Oct 2026 09:39:58 +0100 Subject: [PATCH 2/8] chore: unfreeze files pending regen --- .fernignore | 46 +- .../com/deepgram/core/ClientOptions.java.bak | 408 +++++++ .../ReconnectingWebSocketListener.java.bak | 622 ++++++++++ .../v1/types/AgentV1AgentAudioDone.java.bak | 83 ++ .../v1/types/AgentV1ForceEndTurn.java.bak | 83 ++ .../agent/v1/types/AgentV1KeepAlive.java.bak | 83 ++ .../v1/types/AgentV1ListenUpdated.java.bak | 83 ++ .../v1/types/AgentV1PromptUpdated.java.bak | 83 ++ ...ettingsAgentContextListenProvider.java.bak | 224 ++++ ...gentV1SettingsAgentListenProvider.java.bak | 224 ++++ .../v1/types/AgentV1SettingsApplied.java.bak | 83 ++ .../v1/types/AgentV1SpeakUpdated.java.bak | 83 ++ .../v1/types/AgentV1ThinkUpdated.java.bak | 83 ++ ...AgentV1UpdateListenListenProvider.java.bak | 224 ++++ .../types/AgentV1UserStartedSpeaking.java.bak | 83 ++ .../v1/websocket/V1WebSocketClient.java.bak | 592 +++++++++ .../v2/types/ListenV2CloseStream.java.bak | 83 ++ .../v2/types/ListenV2ForceEndTurn.java.bak | 83 ++ .../v2/websocket/V2WebSocketClient.java.bak | 563 +++++++++ .../v1/websocket/V1WebSocketClient.java.bak | 467 +++++++ .../speak/v2/types/SpeakV2Close.java.bak | 83 ++ .../speak/v2/types/SpeakV2Flush.java.bak | 83 ++ .../v2/websocket/V2WebSocketClient.java.bak | 630 ++++++++++ .../com/deepgram/types/DeepgramModel.java.bak | 1071 +++++++++++++++++ 24 files changed, 6127 insertions(+), 23 deletions(-) create mode 100644 src/main/java/com/deepgram/core/ClientOptions.java.bak create mode 100644 src/main/java/com/deepgram/core/ReconnectingWebSocketListener.java.bak create mode 100644 src/main/java/com/deepgram/resources/agent/v1/types/AgentV1AgentAudioDone.java.bak create mode 100644 src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ForceEndTurn.java.bak create mode 100644 src/main/java/com/deepgram/resources/agent/v1/types/AgentV1KeepAlive.java.bak create mode 100644 src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ListenUpdated.java.bak create mode 100644 src/main/java/com/deepgram/resources/agent/v1/types/AgentV1PromptUpdated.java.bak create mode 100644 src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentContextListenProvider.java.bak create mode 100644 src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentListenProvider.java.bak create mode 100644 src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsApplied.java.bak create mode 100644 src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SpeakUpdated.java.bak create mode 100644 src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ThinkUpdated.java.bak create mode 100644 src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UpdateListenListenProvider.java.bak create mode 100644 src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UserStartedSpeaking.java.bak create mode 100644 src/main/java/com/deepgram/resources/listen/v1/websocket/V1WebSocketClient.java.bak create mode 100644 src/main/java/com/deepgram/resources/listen/v2/types/ListenV2CloseStream.java.bak create mode 100644 src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ForceEndTurn.java.bak create mode 100644 src/main/java/com/deepgram/resources/listen/v2/websocket/V2WebSocketClient.java.bak create mode 100644 src/main/java/com/deepgram/resources/speak/v1/websocket/V1WebSocketClient.java.bak create mode 100644 src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Close.java.bak create mode 100644 src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Flush.java.bak create mode 100644 src/main/java/com/deepgram/resources/speak/v2/websocket/V2WebSocketClient.java.bak create mode 100644 src/main/java/com/deepgram/types/DeepgramModel.java.bak diff --git a/.fernignore b/.fernignore index aacb4e3..e8b7713 100644 --- a/.fernignore +++ b/.fernignore @@ -16,7 +16,7 @@ src/main/java/com/deepgram/AsyncDeepgramClientBuilder.java # Fern regen overwrites these with incorrect SDK names and strips the markers. # Fern 4.22.1 closes tracked WebSockets before SDK-owned OkHttp resources; retain that lifecycle behavior while # reapplying only these headers. -src/main/java/com/deepgram/core/ClientOptions.java +src/main/java/com/deepgram/core/ClientOptions.java.bak # Transport abstraction (pluggable transport for SageMaker, etc.) src/main/java/com/deepgram/core/transport/ @@ -29,7 +29,7 @@ src/main/java/com/deepgram/resources/listen/v1/websocket/ListenV1ErrorException. # Bug fixes for maxRetries(0) semantics ("connect once, don't retry") and a # configurable connectionTimeoutMs on ReconnectOptions (was hardcoded 4000ms). # Pull this back out once the fixes are upstreamed into the Fern generator. -src/main/java/com/deepgram/core/ReconnectingWebSocketListener.java +src/main/java/com/deepgram/core/ReconnectingWebSocketListener.java.bak # Forward-compat patch: Fern's generated dispatcher routes any unrecognized message # type to the error handler ("Update your SDK version..."), which makes benign new @@ -39,8 +39,8 @@ src/main/java/com/deepgram/core/ReconnectingWebSocketListener.java # NOTE: the listen v2 and speak v2 clients below also carry the streaming query-param patches # (multi-value serialization + the additionalProperties escape hatch) documented lower down — # keep them frozen until those fixes are upstreamed too. -src/main/java/com/deepgram/resources/speak/v2/websocket/V2WebSocketClient.java -src/main/java/com/deepgram/resources/listen/v2/websocket/V2WebSocketClient.java +src/main/java/com/deepgram/resources/speak/v2/websocket/V2WebSocketClient.java.bak +src/main/java/com/deepgram/resources/listen/v2/websocket/V2WebSocketClient.java.bak # Streaming query-param patches on the generated WS connect() builders. Two fixes: # (1) Multi-value serialization: array-valued params (listen: keyterm, keywords, replace, search, @@ -54,8 +54,8 @@ src/main/java/com/deepgram/resources/listen/v2/websocket/V2WebSocketClient.java # listen v2 and speak v2 clients are frozen above; freeze the listen v1 and speak v1 clients here too # so the fixes survive regen. Re-apply after regen; unfreeze once the generator emits array params as # repeats and serializes additionalProperties on the WS connect path (tracked as an upstream Fern request). -src/main/java/com/deepgram/resources/listen/v1/websocket/V1WebSocketClient.java -src/main/java/com/deepgram/resources/speak/v1/websocket/V1WebSocketClient.java +src/main/java/com/deepgram/resources/listen/v1/websocket/V1WebSocketClient.java.bak +src/main/java/com/deepgram/resources/speak/v1/websocket/V1WebSocketClient.java.bak # Restores the FLUX_RENEE_EN constant that generator 4.18.0 dropped. The voice is live: # POST /v2/speak?model=flux-renee-en returns 200 with valid audio, and the name resolves in the @@ -67,25 +67,25 @@ src/main/java/com/deepgram/resources/speak/v1/websocket/V1WebSocketClient.java # changes -- 4.18.0 alone added 25 constants. On the next regen do NOT restore the .bak wholesale: # diff it against the newly generated file, carry forward every new voice, and re-apply only the # FLUX_RENEE_EN touchpoints (constant, Value enum, visit() case, valueOf() case, Visitor method). -src/main/java/com/deepgram/types/DeepgramModel.java +src/main/java/com/deepgram/types/DeepgramModel.java.bak # Manual equals/hashCode contract fix: Fern generates equals() (all instances equal) but no # hashCode() for fields-less message types, violating the Object contract. We add a consistent # hashCode() to each. Unfreeze and drop these patches once the generator emits a matching # equals/hashCode pair for fields-less types (tracked as an upstream Fern request). -src/main/java/com/deepgram/resources/listen/v2/types/ListenV2CloseStream.java -src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ForceEndTurn.java -src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Close.java -src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Flush.java -src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ListenUpdated.java -src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SpeakUpdated.java -src/main/java/com/deepgram/resources/agent/v1/types/AgentV1AgentAudioDone.java -src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsApplied.java -src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UserStartedSpeaking.java -src/main/java/com/deepgram/resources/agent/v1/types/AgentV1KeepAlive.java -src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ThinkUpdated.java -src/main/java/com/deepgram/resources/agent/v1/types/AgentV1PromptUpdated.java -src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ForceEndTurn.java +src/main/java/com/deepgram/resources/listen/v2/types/ListenV2CloseStream.java.bak +src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ForceEndTurn.java.bak +src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Close.java.bak +src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Flush.java.bak +src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ListenUpdated.java.bak +src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SpeakUpdated.java.bak +src/main/java/com/deepgram/resources/agent/v1/types/AgentV1AgentAudioDone.java.bak +src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsApplied.java.bak +src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UserStartedSpeaking.java.bak +src/main/java/com/deepgram/resources/agent/v1/types/AgentV1KeepAlive.java.bak +src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ThinkUpdated.java.bak +src/main/java/com/deepgram/resources/agent/v1/types/AgentV1PromptUpdated.java.bak +src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ForceEndTurn.java.bak # Union default-variant fix (STOPGAP). The agent listen-provider unions declare `version` as an # optional discriminator, so a provider payload without it is valid (and is what 0.7.x emits). Fern @@ -94,9 +94,9 @@ src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ForceEndTurn.java # {"provider":null}, silently dropping the caller's provider on the wire. Patched to # defaultImpl = V2Value on each. Guarded by AgentSettingsProviderDefaultTest. Unfreeze and drop once # the generator stops defaulting unions to the empty _UnknownValue (tracked as an upstream Fern request). -src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UpdateListenListenProvider.java -src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentListenProvider.java -src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentContextListenProvider.java +src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UpdateListenListenProvider.java.bak +src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentListenProvider.java.bak +src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentContextListenProvider.java.bak # Build and project configuration build.gradle diff --git a/src/main/java/com/deepgram/core/ClientOptions.java.bak b/src/main/java/com/deepgram/core/ClientOptions.java.bak new file mode 100644 index 0000000..b2c87ee --- /dev/null +++ b/src/main/java/com/deepgram/core/ClientOptions.java.bak @@ -0,0 +1,408 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.core; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Supplier; +import okhttp3.OkHttpClient; + +public final class ClientOptions { + private final Environment environment; + + private final Map headers; + + private final Map> headerSuppliers; + + private final OkHttpClient httpClient; + + private final boolean ownsHttpClient; + + private final AtomicBoolean closed; + + private final Set openWebSockets; + + private final int timeout; + + private final int maxRetries; + + private final Optional initialRetryDelayMillis; + + private final Optional maxRetryDelayMillis; + + private final Optional retryJitterFactor; + + private final Optional webSocketFactory; + + private final Optional logging; + + private ClientOptions( + Environment environment, + Map headers, + Map> headerSuppliers, + OkHttpClient httpClient, + boolean ownsHttpClient, + AtomicBoolean closed, + Set openWebSockets, + int timeout, + int maxRetries, + Optional initialRetryDelayMillis, + Optional maxRetryDelayMillis, + Optional retryJitterFactor, + Optional webSocketFactory, + Optional logging) { + this.environment = environment; + this.headers = new HashMap<>(); + this.headers.putAll(headers); + this.headers.putAll(new HashMap() { + { + put("User-Agent", "com.deepgram:deepgram-java-sdk/0.11.1"); // x-release-please-version + put("X-Fern-Language", "JAVA"); + put("X-Fern-SDK-Name", "com.deepgram:deepgram-java-sdk"); + put("X-Fern-SDK-Version", "0.11.1"); // x-release-please-version + } + }); + this.headerSuppliers = headerSuppliers; + this.httpClient = httpClient; + this.ownsHttpClient = ownsHttpClient; + this.closed = closed; + this.openWebSockets = openWebSockets; + this.timeout = timeout; + this.maxRetries = maxRetries; + this.initialRetryDelayMillis = initialRetryDelayMillis; + this.maxRetryDelayMillis = maxRetryDelayMillis; + this.retryJitterFactor = retryJitterFactor; + this.webSocketFactory = webSocketFactory; + this.logging = logging; + } + + public Environment environment() { + return this.environment; + } + + public Map headers(RequestOptions requestOptions) { + Map values = new HashMap<>(this.headers); + headerSuppliers.forEach((key, supplier) -> { + values.put(key, supplier.get()); + }); + if (requestOptions != null) { + values.putAll(requestOptions.getHeaders()); + } + return values; + } + + public int timeout(RequestOptions requestOptions) { + if (requestOptions == null) { + return this.timeout; + } + return requestOptions.getTimeout().orElse(this.timeout); + } + + public OkHttpClient httpClient() { + return this.httpClient; + } + + public OkHttpClient httpClientWithTimeout(RequestOptions requestOptions) { + if (requestOptions == null) { + return this.httpClient; + } + return this.httpClient + .newBuilder() + .callTimeout(requestOptions.getTimeout().get(), requestOptions.getTimeoutTimeUnit()) + .connectTimeout(0, TimeUnit.SECONDS) + .writeTimeout(0, TimeUnit.SECONDS) + .readTimeout(0, TimeUnit.SECONDS) + .build(); + } + + public int maxRetries() { + return this.maxRetries; + } + + public Optional initialRetryDelayMillis() { + return this.initialRetryDelayMillis; + } + + public Optional maxRetryDelayMillis() { + return this.maxRetryDelayMillis; + } + + public Optional retryJitterFactor() { + return this.retryJitterFactor; + } + + /** + * Releases resources owned by this client. Only shuts down the underlying OkHttpClient's + * dispatcher executor and evicts its connection pool when this client created that + * OkHttpClient itself; an OkHttpClient supplied via httpClient is left running, since the + * caller owns its lifecycle. + *

+ * In-flight calls are not cancelled or awaited. When this client owns its OkHttpClient, later + * asynchronous HTTP requests can fail when the dispatcher rejects work, while synchronous + * requests may still run. An OkHttpClient supplied through {@code httpClient(...)} remains + * caller-owned and running. Options derived via {@code Builder.from(...)} share lifecycle + * state; calling this method more than once has no further effect. + *

+ * WebSocket clients created from this client that are still connected are disconnected + * first (whether or not the OkHttpClient is owned), so they stop reconnecting before the + * dispatcher goes away. Any WebSocket connect or reconnect attempted afterwards fails with + * an {@code IllegalStateException} explaining that the client has been closed. + */ + public void close() { + if (!this.closed.compareAndSet(false, true)) { + return; + } + for (AutoCloseable webSocket : new ArrayList<>(this.openWebSockets)) { + try { + webSocket.close(); + } catch (Exception e) { + // best effort; keep closing the remaining sockets and the HTTP client + } + } + this.openWebSockets.clear(); + if (!this.ownsHttpClient) { + return; + } + this.httpClient.dispatcher().executorService().shutdown(); + this.httpClient.connectionPool().evictAll(); + } + + /** + * Returns whether {@link #close()} has been called on this client. + */ + public boolean isClosed() { + return this.closed.get(); + } + + /** + * Tracks a connected WebSocket client so that {@link #close()} disconnects it. + * + * @throws IllegalStateException if this client has already been closed + */ + public void registerWebSocket(AutoCloseable webSocket) { + this.openWebSockets.add(webSocket); + if (this.closed.get()) { + this.openWebSockets.remove(webSocket); + throw new IllegalStateException("root client has been closed"); + } + } + + /** + * Stops tracking a WebSocket client that has been disconnected. + */ + public void unregisterWebSocket(AutoCloseable webSocket) { + this.openWebSockets.remove(webSocket); + } + + public Optional webSocketFactory() { + return this.webSocketFactory; + } + + public Optional logging() { + return this.logging; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private Environment environment; + + private final Map headers = new HashMap<>(); + + private final Map> headerSuppliers = new HashMap<>(); + + private int maxRetries = 2; + + private Optional initialRetryDelayMillis = Optional.empty(); + + private Optional maxRetryDelayMillis = Optional.empty(); + + private Optional retryJitterFactor = Optional.empty(); + + private Optional timeout = Optional.empty(); + + private OkHttpClient httpClient = null; + + private boolean ownsHttpClient = true; + + private AtomicBoolean closed; + + private Set openWebSockets; + + private Optional logging = Optional.empty(); + + private Optional webSocketFactory = Optional.empty(); + + public Builder environment(Environment environment) { + this.environment = environment; + return this; + } + + public Builder addHeader(String key, String value) { + if (value != null) { + this.headers.put(key, value); + } + return this; + } + + public Builder addHeader(String key, Supplier value) { + this.headerSuppliers.put(key, value); + return this; + } + + /** + * Override the timeout in seconds. Defaults to 60 seconds. + */ + public Builder timeout(int timeout) { + this.timeout = Optional.of(timeout); + return this; + } + + /** + * Override the timeout in seconds. Defaults to 60 seconds. + */ + public Builder timeout(Optional timeout) { + this.timeout = timeout; + return this; + } + + /** + * Override the maximum number of retries. Defaults to 2 retries. + */ + public Builder maxRetries(int maxRetries) { + this.maxRetries = maxRetries; + return this; + } + + /** + * Override the initial delay (in milliseconds) used for exponential backoff between retries. Defaults to 1000 milliseconds. + */ + public Builder initialRetryDelayMillis(long initialRetryDelayMillis) { + this.initialRetryDelayMillis = Optional.of(initialRetryDelayMillis); + return this; + } + + /** + * Override the maximum delay (in milliseconds) between retries. Defaults to 60000 milliseconds. + */ + public Builder maxRetryDelayMillis(long maxRetryDelayMillis) { + this.maxRetryDelayMillis = Optional.of(maxRetryDelayMillis); + return this; + } + + /** + * Override the jitter factor (between 0 and 1) applied to retry delays. Defaults to 0.2. + */ + public Builder retryJitterFactor(double retryJitterFactor) { + this.retryJitterFactor = Optional.of(retryJitterFactor); + return this; + } + + /** + * Sets the underlying OkHttp client. The caller retains ownership of its lifecycle: + * close() will not shut down its dispatcher executor or evict its connection pool. + */ + public Builder httpClient(OkHttpClient httpClient) { + this.httpClient = httpClient; + this.ownsHttpClient = httpClient == null; + return this; + } + + /** + * Set a custom WebSocketFactory for creating WebSocket connections. + */ + public Builder webSocketFactory(WebSocketFactory webSocketFactory) { + this.webSocketFactory = Optional.of(webSocketFactory); + return this; + } + + /** + * Configure logging for the SDK. Silent by default — no log output unless explicitly configured. + */ + public Builder logging(LogConfig logging) { + this.logging = Optional.of(logging); + return this; + } + + public ClientOptions build() { + OkHttpClient.Builder httpClientBuilder = + this.httpClient != null ? this.httpClient.newBuilder() : new OkHttpClient.Builder(); + + if (this.httpClient != null) { + timeout.ifPresent(timeout -> httpClientBuilder + .callTimeout(timeout, TimeUnit.SECONDS) + .connectTimeout(0, TimeUnit.SECONDS) + .writeTimeout(0, TimeUnit.SECONDS) + .readTimeout(0, TimeUnit.SECONDS)); + } else { + httpClientBuilder + .callTimeout(this.timeout.orElse(60), TimeUnit.SECONDS) + .connectTimeout(0, TimeUnit.SECONDS) + .writeTimeout(0, TimeUnit.SECONDS) + .readTimeout(0, TimeUnit.SECONDS) + .addInterceptor(new RetryInterceptor( + this.maxRetries, + this.initialRetryDelayMillis, + this.maxRetryDelayMillis, + this.retryJitterFactor)); + } + + Logger logger = Logger.from(this.logging); + httpClientBuilder.addInterceptor(new LoggingInterceptor(logger)); + httpClientBuilder.addInterceptor(new ResponseDecompressionInterceptor()); + + this.httpClient = httpClientBuilder.build(); + this.timeout = Optional.of(httpClient.callTimeoutMillis() / 1000); + + AtomicBoolean closedToUse = this.closed != null ? this.closed : new AtomicBoolean(false); + Set openWebSocketsToUse = + this.openWebSockets != null ? this.openWebSockets : ConcurrentHashMap.newKeySet(); + + return new ClientOptions( + environment, + headers, + headerSuppliers, + httpClient, + this.ownsHttpClient, + closedToUse, + openWebSocketsToUse, + this.timeout.get(), + this.maxRetries, + this.initialRetryDelayMillis, + this.maxRetryDelayMillis, + this.retryJitterFactor, + this.webSocketFactory, + this.logging); + } + + /** + * Create a new Builder initialized with values from an existing ClientOptions + */ + public static Builder from(ClientOptions clientOptions) { + Builder builder = new Builder(); + builder.environment = clientOptions.environment(); + builder.timeout = Optional.of(clientOptions.timeout(null)); + builder.httpClient = clientOptions.httpClient(); + builder.ownsHttpClient = clientOptions.ownsHttpClient; + builder.closed = clientOptions.closed; + builder.openWebSockets = clientOptions.openWebSockets; + builder.headers.putAll(clientOptions.headers); + builder.headerSuppliers.putAll(clientOptions.headerSuppliers); + builder.maxRetries = clientOptions.maxRetries(); + builder.initialRetryDelayMillis = clientOptions.initialRetryDelayMillis(); + builder.maxRetryDelayMillis = clientOptions.maxRetryDelayMillis(); + builder.retryJitterFactor = clientOptions.retryJitterFactor(); + builder.logging = clientOptions.logging(); + return builder; + } + } +} diff --git a/src/main/java/com/deepgram/core/ReconnectingWebSocketListener.java.bak b/src/main/java/com/deepgram/core/ReconnectingWebSocketListener.java.bak new file mode 100644 index 0000000..b51aacc --- /dev/null +++ b/src/main/java/com/deepgram/core/ReconnectingWebSocketListener.java.bak @@ -0,0 +1,622 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.core; + +import static java.util.concurrent.TimeUnit.*; + +import java.util.ArrayList; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.BooleanSupplier; +import java.util.function.Consumer; +import java.util.function.Supplier; +import okhttp3.Response; +import okhttp3.WebSocket; +import okhttp3.WebSocketListener; +import okio.ByteString; + +/** + * WebSocketListener with automatic reconnection, exponential backoff, and message queuing. + * Provides production-ready resilience for WebSocket connections. + */ +public abstract class ReconnectingWebSocketListener extends WebSocketListener { + private volatile ReconnectOptions activeOptions; + + private final int maxEnqueuedMessages; + + private final AtomicInteger retryCount = new AtomicInteger(0); + + private final AtomicBoolean connectLock = new AtomicBoolean(false); + + private final AtomicBoolean shouldReconnect = new AtomicBoolean(true); + + protected volatile WebSocket webSocket; + + private volatile long connectionEstablishedTime = 0L; + + private final ConcurrentLinkedQueue messageQueue = new ConcurrentLinkedQueue<>(); + + private final ConcurrentLinkedQueue binaryMessageQueue = new ConcurrentLinkedQueue<>(); + + private final ScheduledExecutorService reconnectExecutor = Executors.newSingleThreadScheduledExecutor(); + + private final Supplier connectionSupplier; + + private final BooleanSupplier closedCheck; + + /** + * Creates a new reconnecting WebSocket listener. + * + * @param options Reconnection configuration options + * @param connectionSupplier Supplier that creates new WebSocket connections + */ + public ReconnectingWebSocketListener( + ReconnectingWebSocketListener.ReconnectOptions options, Supplier connectionSupplier) { + this(options, connectionSupplier, () -> false); + } + + /** + * Creates a new reconnecting WebSocket listener. + * + * @param options Reconnection configuration options + * @param connectionSupplier Supplier that creates new WebSocket connections + * @param closedCheck Returns true once the owning client has been closed; connect and + * reconnect attempts made after that point fail with an {@link IllegalStateException} + * instead of being retried + */ + public ReconnectingWebSocketListener( + ReconnectingWebSocketListener.ReconnectOptions options, + Supplier connectionSupplier, + BooleanSupplier closedCheck) { + this.activeOptions = options; + this.maxEnqueuedMessages = options.maxEnqueuedMessages; + this.connectionSupplier = connectionSupplier; + this.closedCheck = closedCheck; + } + + /** + * Replaces option-derived reconnect settings without rebuilding generated clients. + * + * @param options replacement options; {@code null} is a no-op + */ + public void applyOptionsOverride(ReconnectOptions options) { + if (options != null) { + this.activeOptions = options; + } + } + + /** + * Initiates a WebSocket connection with automatic reconnection enabled. + * + * Connection behavior: + * - Times out after {@code ReconnectOptions.connectionTimeoutMs} (default 4000ms) + * - Thread-safe via atomic lock (returns immediately if connection in progress) + * - {@code maxRetries} counts retries only; {@code maxRetries(0)} means connect once, do not retry + * + * Error handling: + * - TimeoutException: Includes retry attempt context + * - InterruptedException: Preserves thread interruption status + * - ExecutionException: Extracts actual cause and adds context + * - Owning client closed: reports an IllegalStateException once and stops reconnecting + */ + public void connect() { + if (!connectLock.compareAndSet(false, true)) { + return; + } + if (closedCheck.getAsBoolean()) { + shouldReconnect.set(false); + connectLock.set(false); + onWebSocketFailure(null, new IllegalStateException("root client has been closed"), null); + return; + } + ReconnectOptions options = this.activeOptions; + if (retryCount.get() > options.maxRetries) { + connectLock.set(false); + return; + } + try { + CompletableFuture connectionFuture = CompletableFuture.supplyAsync(connectionSupplier); + try { + webSocket = connectionFuture.get(options.connectionTimeoutMs, MILLISECONDS); + } catch (TimeoutException e) { + connectionFuture.cancel(true); + TimeoutException timeoutError = + new TimeoutException("WebSocket connection timeout after " + options.connectionTimeoutMs + + " milliseconds" + + (retryCount.get() > 0 + ? " (retry attempt #" + retryCount.get() + ")" + : " (initial connection attempt)")); + onWebSocketFailure(null, timeoutError, null); + if (shouldReconnect.get()) { + scheduleReconnect(); + } + } catch (InterruptedException e) { + connectionFuture.cancel(true); + Thread.currentThread().interrupt(); + InterruptedException interruptError = new InterruptedException("WebSocket connection interrupted" + + (retryCount.get() > 0 + ? " during retry attempt #" + retryCount.get() + : " during initial connection")); + interruptError.initCause(e); + onWebSocketFailure(null, interruptError, null); + } catch (ExecutionException e) { + Throwable cause = e.getCause() != null ? e.getCause() : e; + String context = retryCount.get() > 0 + ? "WebSocket connection failed during retry attempt #" + retryCount.get() + : "WebSocket connection failed during initial attempt"; + RuntimeException wrappedException = new RuntimeException( + context + ": " + cause.getClass().getSimpleName() + ": " + cause.getMessage()); + wrappedException.initCause(cause); + onWebSocketFailure(null, wrappedException, null); + if (shouldReconnect.get()) { + scheduleReconnect(); + } + } + } finally { + connectLock.set(false); + } + } + + /** + * Disconnects the WebSocket and disables automatic reconnection. + * + * This method: + * - Disables automatic reconnection + * - Clears queued messages to prevent stale data + * - Closes the WebSocket with standard close code 1000 + * - Properly shuts down the reconnect executor to prevent thread leaks + * - Waits up to 5 seconds for executor termination + */ + public void disconnect() { + shouldReconnect.set(false); + messageQueue.clear(); + binaryMessageQueue.clear(); + if (webSocket != null) { + webSocket.close(1000, "Client disconnecting"); + } + reconnectExecutor.shutdown(); + try { + if (!reconnectExecutor.awaitTermination(5, SECONDS)) { + reconnectExecutor.shutdownNow(); + } + } catch (InterruptedException e) { + reconnectExecutor.shutdownNow(); + Thread.currentThread().interrupt(); + } + } + + /** + * Sends a message or queues it if not connected. + * + * Thread-safe: Synchronized to prevent race conditions with flushMessageQueue(). + * + * Behavior: + * - If connected: Attempts direct send, queues if buffer full + * - If disconnected: Queues message up to maxEnqueuedMessages limit + * - If queue full: Message is dropped + * + * @param message The message to send + * @return true if sent immediately, false if queued or dropped + */ + public synchronized boolean send(String message) { + return send(message, null); + } + + /** + * Sends a message or queues it if not connected, exposing the accepting socket. + * + * Behaves like {@link #send(String)}, but additionally invokes {@code onSent} with the + * WebSocket that accepted the message. The callback is only invoked when the message was + * sent directly, never when it was queued or dropped. This lets callers associate a + * protocol-level message with the specific connection it was delivered on, e.g. to decide + * in {@link #shouldReconnectAfterClose(WebSocket, int, String)} whether a later close of that same + * connection was expected. + * + * @param message The message to send + * @param onSent Callback receiving the WebSocket that accepted the message, or null + * @return true if sent immediately, false if queued or dropped + */ + public synchronized boolean send(String message, Consumer onSent) { + WebSocket ws = webSocket; + if (ws != null) { + boolean sent = ws.send(message); + if (sent && onSent != null) { + onSent.accept(ws); + } + if (!sent && messageQueue.size() < maxEnqueuedMessages) { + messageQueue.offer(message); + return false; + } + return sent; + } else { + if (messageQueue.size() < maxEnqueuedMessages) { + messageQueue.offer(message); + return false; + } + return false; + } + } + + /** + * Sends binary data or queues it if not connected. + * + * Thread-safe: Synchronized to prevent race conditions with flushMessageQueue(). + * + * Behavior: + * - If connected: Attempts direct send, queues if buffer full + * - If disconnected: Queues data up to maxEnqueuedMessages limit + * - If queue full: Data is dropped + * + * @param data The binary data to send + * @return true if sent immediately, false if queued or dropped + */ + public synchronized boolean sendBinary(ByteString data) { + return sendBinary(data, null); + } + + /** + * Sends binary data or queues it if not connected, exposing the accepting socket. + * + * Behaves like {@link #sendBinary(ByteString)}, but additionally invokes {@code onSent} with + * the WebSocket that accepted the data. The callback is only invoked when the data was sent + * directly, never when it was queued or dropped. + * + * @param data The binary data to send + * @param onSent Callback receiving the WebSocket that accepted the data, or null + * @return true if sent immediately, false if queued or dropped + */ + public synchronized boolean sendBinary(ByteString data, Consumer onSent) { + WebSocket ws = webSocket; + if (ws != null) { + boolean sent = ws.send(data); + if (sent && onSent != null) { + onSent.accept(ws); + } + if (!sent && binaryMessageQueue.size() < maxEnqueuedMessages) { + binaryMessageQueue.offer(data); + return false; + } + return sent; + } else { + if (binaryMessageQueue.size() < maxEnqueuedMessages) { + binaryMessageQueue.offer(data); + return false; + } + return false; + } + } + + /** + * Gets the current WebSocket instance. + * Thread-safe method to access the WebSocket connection. + * @return the WebSocket or null if not connected + */ + public WebSocket getWebSocket() { + return webSocket; + } + + /** + * @hidden + */ + @Override + public void onOpen(WebSocket webSocket, Response response) { + this.webSocket = webSocket; + connectionEstablishedTime = System.currentTimeMillis(); + retryCount.set(0); + flushMessageQueue(); + onWebSocketOpen(webSocket, response); + } + + @Override + public void onMessage(WebSocket webSocket, String text) { + onWebSocketMessage(webSocket, text); + } + + @Override + public void onMessage(WebSocket webSocket, ByteString bytes) { + onWebSocketBinaryMessage(webSocket, bytes); + } + + /** + * @hidden + */ + @Override + public void onFailure(WebSocket webSocket, Throwable t, Response response) { + this.webSocket = null; + long uptime = 0L; + if (connectionEstablishedTime > 0) { + uptime = System.currentTimeMillis() - connectionEstablishedTime; + if (uptime >= 5000) { + retryCount.set(0); + } + } + connectionEstablishedTime = 0L; + Throwable enhancedError = t; + if (t != null) { + String errorContext = "WebSocket connection failed"; + if (uptime > 0) { + errorContext += " after " + (uptime / 1000) + " seconds"; + } + if (response != null) { + errorContext += " with HTTP " + response.code() + " " + response.message(); + } + enhancedError = + new RuntimeException(errorContext + ": " + t.getClass().getSimpleName() + ": " + t.getMessage()); + enhancedError.initCause(t); + } + onWebSocketFailure(webSocket, enhancedError, response); + if (shouldReconnect.get()) { + scheduleReconnect(); + } + } + + /** + * Acknowledges a peer-initiated close so OkHttp can complete the close handshake and + * invoke {@link #onClosed(WebSocket, int, String)}. + * + * Code 1005 is a local "no status received" sentinel reported when the peer sent an empty + * close frame. It is not a valid code to put on the wire, so it is acknowledged with + * the normal closure code 1000 instead. + * + * @hidden + */ + @Override + public void onClosing(WebSocket webSocket, int code, String reason) { + webSocket.close(code == 1005 ? 1000 : code, reason); + } + + /** + * @hidden + */ + @Override + public void onClosed(WebSocket webSocket, int code, String reason) { + this.webSocket = null; + if (connectionEstablishedTime > 0) { + long uptime = System.currentTimeMillis() - connectionEstablishedTime; + if (uptime >= 5000) { + retryCount.set(0); + } + } + connectionEstablishedTime = 0L; + onWebSocketClosed(webSocket, code, reason); + if (shouldReconnect.get() && shouldReconnectAfterClose(webSocket, code, reason)) { + scheduleReconnect(); + } + } + + /** + * Decides whether a completed close handshake should trigger a reconnect. + * + * Only consulted when reconnection has not been disabled via {@link #disconnect()}. + * The default treats normal closure (1000) as terminal and reconnects on any + * other code. Subclasses can override this when protocol context establishes that a + * particular close is terminal, for example a no-status close following a message that + * ends the stream. + * + * @param webSocket The WebSocket that was closed + * @param code The close status code reported by OkHttp + * @param reason The close reason sent by the peer, or an empty string + * @return true to schedule a reconnect, false to stay disconnected + */ + protected boolean shouldReconnectAfterClose(WebSocket webSocket, int code, String reason) { + return code != 1000; + } + + /** + * Calculates the next reconnection delay using exponential backoff. + * + * Uses 0-based retry count where: + * - 0 = initial connection (not used by this method) + * - 1 = first retry (returns minReconnectionDelayMs) + * - 2+ = exponential backoff up to maxReconnectionDelayMs + */ + private long getNextDelay() { + if (retryCount.get() == 1) { + return activeOptions.minReconnectionDelayMs; + } + ReconnectOptions options = this.activeOptions; + long delay = (long) + (options.minReconnectionDelayMs * Math.pow(options.reconnectionDelayGrowFactor, retryCount.get() - 1)); + return Math.min(delay, options.maxReconnectionDelayMs); + } + + /** + * Schedules a reconnection attempt with appropriate delay. + * Increments retry count and uses exponential backoff. + * Does nothing once the owning client has been closed. + */ + private void scheduleReconnect() { + if (closedCheck.getAsBoolean()) { + shouldReconnect.set(false); + return; + } + retryCount.incrementAndGet(); + long delay = getNextDelay(); + reconnectExecutor.schedule(this::connect, delay, MILLISECONDS); + } + + /** + * Sends all queued messages after reconnection. + * + * Thread-safe: Synchronized to prevent race conditions with send() method. + * + * Algorithm: + * 1. Drains queue into temporary list to avoid holding lock during sends + * 2. Attempts to send each message in order + * 3. If any send fails, re-queues that message and all subsequent messages + * 4. Preserves message ordering during re-queueing + * 5. Repeats for binary message queue + */ + private synchronized void flushMessageQueue() { + WebSocket ws = webSocket; + if (ws != null) { + ArrayList tempQueue = new ArrayList<>(); + String message; + while ((message = messageQueue.poll()) != null) { + tempQueue.add(message); + } + for (int i = 0; i < tempQueue.size(); i++) { + if (!ws.send(tempQueue.get(i))) { + for (int j = i; j < tempQueue.size(); j++) { + messageQueue.offer(tempQueue.get(j)); + } + break; + } + } + ArrayList tempBinaryQueue = new ArrayList<>(); + ByteString binaryMsg; + while ((binaryMsg = binaryMessageQueue.poll()) != null) { + tempBinaryQueue.add(binaryMsg); + } + for (int i = 0; i < tempBinaryQueue.size(); i++) { + if (!ws.send(tempBinaryQueue.get(i))) { + for (int j = i; j < tempBinaryQueue.size(); j++) { + binaryMessageQueue.offer(tempBinaryQueue.get(j)); + } + break; + } + } + } + } + + protected abstract void onWebSocketOpen(WebSocket webSocket, Response response); + + protected abstract void onWebSocketMessage(WebSocket webSocket, String text); + + protected abstract void onWebSocketBinaryMessage(WebSocket webSocket, ByteString bytes); + + protected abstract void onWebSocketFailure(WebSocket webSocket, Throwable t, Response response); + + protected abstract void onWebSocketClosed(WebSocket webSocket, int code, String reason); + + /** + * Configuration options for automatic reconnection. + */ + public static final class ReconnectOptions { + public final long minReconnectionDelayMs; + + public final long maxReconnectionDelayMs; + + public final double reconnectionDelayGrowFactor; + + public final int maxRetries; + + public final int maxEnqueuedMessages; + + public final long connectionTimeoutMs; + + private ReconnectOptions(Builder builder) { + this.minReconnectionDelayMs = builder.minReconnectionDelayMs; + this.maxReconnectionDelayMs = builder.maxReconnectionDelayMs; + this.reconnectionDelayGrowFactor = builder.reconnectionDelayGrowFactor; + this.maxRetries = builder.maxRetries; + this.maxEnqueuedMessages = builder.maxEnqueuedMessages; + this.connectionTimeoutMs = builder.connectionTimeoutMs; + } + + public static Builder builder() { + return new Builder(); + } + + public static final class Builder { + private long minReconnectionDelayMs; + + private long maxReconnectionDelayMs; + + private double reconnectionDelayGrowFactor; + + private int maxRetries; + + private int maxEnqueuedMessages; + + private long connectionTimeoutMs; + + public Builder() { + this.minReconnectionDelayMs = 1000; + this.maxReconnectionDelayMs = 10000; + this.reconnectionDelayGrowFactor = 1.3; + this.maxRetries = 2147483647; + this.maxEnqueuedMessages = 1000; + this.connectionTimeoutMs = 4000; + } + + public Builder minReconnectionDelayMs(long minReconnectionDelayMs) { + this.minReconnectionDelayMs = minReconnectionDelayMs; + return this; + } + + public Builder maxReconnectionDelayMs(long maxReconnectionDelayMs) { + this.maxReconnectionDelayMs = maxReconnectionDelayMs; + return this; + } + + public Builder reconnectionDelayGrowFactor(double reconnectionDelayGrowFactor) { + this.reconnectionDelayGrowFactor = reconnectionDelayGrowFactor; + return this; + } + + public Builder maxRetries(int maxRetries) { + this.maxRetries = maxRetries; + return this; + } + + public Builder maxEnqueuedMessages(int maxEnqueuedMessages) { + this.maxEnqueuedMessages = maxEnqueuedMessages; + return this; + } + + /** + * Sets the per-attempt connection timeout in milliseconds. Defaults to {@code 4000}. + */ + public Builder connectionTimeoutMs(long connectionTimeoutMs) { + this.connectionTimeoutMs = connectionTimeoutMs; + return this; + } + + /** + * Builds the ReconnectOptions with validation. + * + * Validates that: + * - All delay values are positive + * - minReconnectionDelayMs <= maxReconnectionDelayMs + * - reconnectionDelayGrowFactor >= 1.0 + * - maxRetries and maxEnqueuedMessages are non-negative + * + * @return The validated ReconnectOptions instance + * @throws IllegalArgumentException if configuration is invalid + */ + public ReconnectOptions build() { + if (minReconnectionDelayMs <= 0) { + throw new IllegalArgumentException("minReconnectionDelayMs must be positive"); + } + if (maxReconnectionDelayMs <= 0) { + throw new IllegalArgumentException("maxReconnectionDelayMs must be positive"); + } + if (minReconnectionDelayMs > maxReconnectionDelayMs) { + throw new IllegalArgumentException("minReconnectionDelayMs (" + minReconnectionDelayMs + + ") must not exceed maxReconnectionDelayMs (" + maxReconnectionDelayMs + ")"); + } + if (reconnectionDelayGrowFactor < 1.0) { + throw new IllegalArgumentException("reconnectionDelayGrowFactor must be >= 1.0"); + } + if (maxRetries < 0) { + throw new IllegalArgumentException("maxRetries must be non-negative"); + } + if (maxEnqueuedMessages < 0) { + throw new IllegalArgumentException("maxEnqueuedMessages must be non-negative"); + } + if (connectionTimeoutMs <= 0) { + throw new IllegalArgumentException("connectionTimeoutMs must be positive"); + } + return new ReconnectOptions(this); + } + } + } +} diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1AgentAudioDone.java.bak b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1AgentAudioDone.java.bak new file mode 100644 index 0000000..5962f4b --- /dev/null +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1AgentAudioDone.java.bak @@ -0,0 +1,83 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.resources.agent.v1.types; + +import com.deepgram.core.ObjectMappers; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.util.HashMap; +import java.util.Map; + +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonDeserialize(builder = AgentV1AgentAudioDone.Builder.class) +public final class AgentV1AgentAudioDone { + private final Map additionalProperties; + + private AgentV1AgentAudioDone(Map additionalProperties) { + this.additionalProperties = additionalProperties; + } + + /** + * @return Message type identifier indicating the agent has finished sending audio + */ + @JsonProperty("type") + public String getType() { + return "AgentAudioDone"; + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof AgentV1AgentAudioDone; + } + + @java.lang.Override + public int hashCode() { + return getClass().hashCode(); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + @java.lang.Override + public String toString() { + return ObjectMappers.stringify(this); + } + + public static Builder builder() { + return new Builder(); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static final class Builder { + @JsonAnySetter + private Map additionalProperties = new HashMap<>(); + + private Builder() {} + + public Builder from(AgentV1AgentAudioDone other) { + return this; + } + + public AgentV1AgentAudioDone build() { + return new AgentV1AgentAudioDone(additionalProperties); + } + + public Builder additionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + return this; + } + + public Builder additionalProperties(Map additionalProperties) { + this.additionalProperties.putAll(additionalProperties); + return this; + } + } +} diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ForceEndTurn.java.bak b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ForceEndTurn.java.bak new file mode 100644 index 0000000..9bd5f76 --- /dev/null +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ForceEndTurn.java.bak @@ -0,0 +1,83 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.resources.agent.v1.types; + +import com.deepgram.core.ObjectMappers; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.util.HashMap; +import java.util.Map; + +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonDeserialize(builder = AgentV1ForceEndTurn.Builder.class) +public final class AgentV1ForceEndTurn { + private final Map additionalProperties; + + private AgentV1ForceEndTurn(Map additionalProperties) { + this.additionalProperties = additionalProperties; + } + + /** + * @return Message type identifier for forcing the end of the current turn + */ + @JsonProperty("type") + public String getType() { + return "ForceEndTurn"; + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof AgentV1ForceEndTurn; + } + + @java.lang.Override + public int hashCode() { + return getClass().hashCode(); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + @java.lang.Override + public String toString() { + return ObjectMappers.stringify(this); + } + + public static Builder builder() { + return new Builder(); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static final class Builder { + @JsonAnySetter + private Map additionalProperties = new HashMap<>(); + + private Builder() {} + + public Builder from(AgentV1ForceEndTurn other) { + return this; + } + + public AgentV1ForceEndTurn build() { + return new AgentV1ForceEndTurn(additionalProperties); + } + + public Builder additionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + return this; + } + + public Builder additionalProperties(Map additionalProperties) { + this.additionalProperties.putAll(additionalProperties); + return this; + } + } +} diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1KeepAlive.java.bak b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1KeepAlive.java.bak new file mode 100644 index 0000000..f82f59e --- /dev/null +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1KeepAlive.java.bak @@ -0,0 +1,83 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.resources.agent.v1.types; + +import com.deepgram.core.ObjectMappers; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.util.HashMap; +import java.util.Map; + +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonDeserialize(builder = AgentV1KeepAlive.Builder.class) +public final class AgentV1KeepAlive { + private final Map additionalProperties; + + private AgentV1KeepAlive(Map additionalProperties) { + this.additionalProperties = additionalProperties; + } + + /** + * @return Message type identifier + */ + @JsonProperty("type") + public String getType() { + return "KeepAlive"; + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof AgentV1KeepAlive; + } + + @java.lang.Override + public int hashCode() { + return getClass().hashCode(); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + @java.lang.Override + public String toString() { + return ObjectMappers.stringify(this); + } + + public static Builder builder() { + return new Builder(); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static final class Builder { + @JsonAnySetter + private Map additionalProperties = new HashMap<>(); + + private Builder() {} + + public Builder from(AgentV1KeepAlive other) { + return this; + } + + public AgentV1KeepAlive build() { + return new AgentV1KeepAlive(additionalProperties); + } + + public Builder additionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + return this; + } + + public Builder additionalProperties(Map additionalProperties) { + this.additionalProperties.putAll(additionalProperties); + return this; + } + } +} diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ListenUpdated.java.bak b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ListenUpdated.java.bak new file mode 100644 index 0000000..43b8628 --- /dev/null +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ListenUpdated.java.bak @@ -0,0 +1,83 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.resources.agent.v1.types; + +import com.deepgram.core.ObjectMappers; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.util.HashMap; +import java.util.Map; + +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonDeserialize(builder = AgentV1ListenUpdated.Builder.class) +public final class AgentV1ListenUpdated { + private final Map additionalProperties; + + private AgentV1ListenUpdated(Map additionalProperties) { + this.additionalProperties = additionalProperties; + } + + /** + * @return Message type identifier for listen update confirmation + */ + @JsonProperty("type") + public String getType() { + return "ListenUpdated"; + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof AgentV1ListenUpdated; + } + + @java.lang.Override + public int hashCode() { + return getClass().hashCode(); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + @java.lang.Override + public String toString() { + return ObjectMappers.stringify(this); + } + + public static Builder builder() { + return new Builder(); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static final class Builder { + @JsonAnySetter + private Map additionalProperties = new HashMap<>(); + + private Builder() {} + + public Builder from(AgentV1ListenUpdated other) { + return this; + } + + public AgentV1ListenUpdated build() { + return new AgentV1ListenUpdated(additionalProperties); + } + + public Builder additionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + return this; + } + + public Builder additionalProperties(Map additionalProperties) { + this.additionalProperties.putAll(additionalProperties); + return this; + } + } +} diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1PromptUpdated.java.bak b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1PromptUpdated.java.bak new file mode 100644 index 0000000..e6efced --- /dev/null +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1PromptUpdated.java.bak @@ -0,0 +1,83 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.resources.agent.v1.types; + +import com.deepgram.core.ObjectMappers; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.util.HashMap; +import java.util.Map; + +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonDeserialize(builder = AgentV1PromptUpdated.Builder.class) +public final class AgentV1PromptUpdated { + private final Map additionalProperties; + + private AgentV1PromptUpdated(Map additionalProperties) { + this.additionalProperties = additionalProperties; + } + + /** + * @return Message type identifier for prompt update confirmation + */ + @JsonProperty("type") + public String getType() { + return "PromptUpdated"; + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof AgentV1PromptUpdated; + } + + @java.lang.Override + public int hashCode() { + return getClass().hashCode(); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + @java.lang.Override + public String toString() { + return ObjectMappers.stringify(this); + } + + public static Builder builder() { + return new Builder(); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static final class Builder { + @JsonAnySetter + private Map additionalProperties = new HashMap<>(); + + private Builder() {} + + public Builder from(AgentV1PromptUpdated other) { + return this; + } + + public AgentV1PromptUpdated build() { + return new AgentV1PromptUpdated(additionalProperties); + } + + public Builder additionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + return this; + } + + public Builder additionalProperties(Map additionalProperties) { + this.additionalProperties.putAll(additionalProperties); + return this; + } + } +} diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentContextListenProvider.java.bak b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentContextListenProvider.java.bak new file mode 100644 index 0000000..393f1f9 --- /dev/null +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentContextListenProvider.java.bak @@ -0,0 +1,224 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.resources.agent.v1.types; + +import com.deepgram.types.DeepgramListenProviderV1; +import com.deepgram.types.DeepgramListenProviderV2; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonUnwrapped; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Objects; +import java.util.Optional; + +public final class AgentV1SettingsAgentContextListenProvider { + private final Value value; + + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) + private AgentV1SettingsAgentContextListenProvider(Value value) { + this.value = value; + } + + public T visit(Visitor visitor) { + return value.visit(visitor); + } + + public static AgentV1SettingsAgentContextListenProvider v1(DeepgramListenProviderV1 value) { + return new AgentV1SettingsAgentContextListenProvider(new V1Value(value)); + } + + public static AgentV1SettingsAgentContextListenProvider v2(DeepgramListenProviderV2 value) { + return new AgentV1SettingsAgentContextListenProvider(new V2Value(value)); + } + + public boolean isV1() { + return value instanceof V1Value; + } + + public boolean isV2() { + return value instanceof V2Value; + } + + public boolean _isUnknown() { + return value instanceof _UnknownValue; + } + + public Optional getV1() { + if (isV1()) { + return Optional.of(((V1Value) value).value); + } + return Optional.empty(); + } + + public Optional getV2() { + if (isV2()) { + return Optional.of(((V2Value) value).value); + } + return Optional.empty(); + } + + public Optional _getUnknown() { + if (_isUnknown()) { + return Optional.of(((_UnknownValue) value).value); + } + return Optional.empty(); + } + + @Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof AgentV1SettingsAgentContextListenProvider + && value.equals(((AgentV1SettingsAgentContextListenProvider) other).value); + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + + @Override + public String toString() { + return value.toString(); + } + + @JsonValue + private Value getValue() { + return this.value; + } + + public interface Visitor { + T visitV1(DeepgramListenProviderV1 v1); + + T visitV2(DeepgramListenProviderV2 v2); + + T _visitUnknown(Object unknownType); + } + + @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "version", visible = true, defaultImpl = V2Value.class) + @JsonSubTypes({@JsonSubTypes.Type(V1Value.class), @JsonSubTypes.Type(V2Value.class)}) + @JsonIgnoreProperties(ignoreUnknown = true) + private interface Value { + T visit(Visitor visitor); + } + + @JsonTypeName("v1") + @JsonIgnoreProperties("version") + private static final class V1Value implements Value { + @JsonUnwrapped + @JsonIgnoreProperties(value = "version", allowSetters = true) + private DeepgramListenProviderV1 value; + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + private V1Value() {} + + private V1Value(DeepgramListenProviderV1 value) { + this.value = value; + } + + @java.lang.Override + public T visit(Visitor visitor) { + return visitor.visitV1(value); + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof V1Value && equalTo((V1Value) other); + } + + private boolean equalTo(V1Value other) { + return value.equals(other.value); + } + + @java.lang.Override + public int hashCode() { + return Objects.hash(this.value); + } + + @java.lang.Override + public String toString() { + return "AgentV1SettingsAgentContextListenProvider{" + "value: " + value + "}"; + } + } + + @JsonTypeName("v2") + @JsonIgnoreProperties("version") + private static final class V2Value implements Value { + @JsonUnwrapped + @JsonIgnoreProperties(value = "version", allowSetters = true) + private DeepgramListenProviderV2 value; + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + private V2Value() {} + + private V2Value(DeepgramListenProviderV2 value) { + this.value = value; + } + + @java.lang.Override + public T visit(Visitor visitor) { + return visitor.visitV2(value); + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof V2Value && equalTo((V2Value) other); + } + + private boolean equalTo(V2Value other) { + return value.equals(other.value); + } + + @java.lang.Override + public int hashCode() { + return Objects.hash(this.value); + } + + @java.lang.Override + public String toString() { + return "AgentV1SettingsAgentContextListenProvider{" + "value: " + value + "}"; + } + } + + @JsonIgnoreProperties("version") + private static final class _UnknownValue implements Value { + private String type; + + @JsonValue + private Object value; + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + private _UnknownValue(@JsonProperty("value") Object value) {} + + @java.lang.Override + public T visit(Visitor visitor) { + return visitor._visitUnknown(value); + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof _UnknownValue && equalTo((_UnknownValue) other); + } + + private boolean equalTo(_UnknownValue other) { + return type.equals(other.type) && value.equals(other.value); + } + + @java.lang.Override + public int hashCode() { + return Objects.hash(this.type, this.value); + } + + @java.lang.Override + public String toString() { + return "AgentV1SettingsAgentContextListenProvider{" + "type: " + type + ", value: " + value + "}"; + } + } +} diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentListenProvider.java.bak b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentListenProvider.java.bak new file mode 100644 index 0000000..345ba2f --- /dev/null +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentListenProvider.java.bak @@ -0,0 +1,224 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.resources.agent.v1.types; + +import com.deepgram.types.DeepgramListenProviderV1; +import com.deepgram.types.DeepgramListenProviderV2; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonUnwrapped; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Objects; +import java.util.Optional; + +public final class AgentV1SettingsAgentListenProvider { + private final Value value; + + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) + private AgentV1SettingsAgentListenProvider(Value value) { + this.value = value; + } + + public T visit(Visitor visitor) { + return value.visit(visitor); + } + + public static AgentV1SettingsAgentListenProvider v1(DeepgramListenProviderV1 value) { + return new AgentV1SettingsAgentListenProvider(new V1Value(value)); + } + + public static AgentV1SettingsAgentListenProvider v2(DeepgramListenProviderV2 value) { + return new AgentV1SettingsAgentListenProvider(new V2Value(value)); + } + + public boolean isV1() { + return value instanceof V1Value; + } + + public boolean isV2() { + return value instanceof V2Value; + } + + public boolean _isUnknown() { + return value instanceof _UnknownValue; + } + + public Optional getV1() { + if (isV1()) { + return Optional.of(((V1Value) value).value); + } + return Optional.empty(); + } + + public Optional getV2() { + if (isV2()) { + return Optional.of(((V2Value) value).value); + } + return Optional.empty(); + } + + public Optional _getUnknown() { + if (_isUnknown()) { + return Optional.of(((_UnknownValue) value).value); + } + return Optional.empty(); + } + + @Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof AgentV1SettingsAgentListenProvider + && value.equals(((AgentV1SettingsAgentListenProvider) other).value); + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + + @Override + public String toString() { + return value.toString(); + } + + @JsonValue + private Value getValue() { + return this.value; + } + + public interface Visitor { + T visitV1(DeepgramListenProviderV1 v1); + + T visitV2(DeepgramListenProviderV2 v2); + + T _visitUnknown(Object unknownType); + } + + @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "version", visible = true, defaultImpl = V2Value.class) + @JsonSubTypes({@JsonSubTypes.Type(V1Value.class), @JsonSubTypes.Type(V2Value.class)}) + @JsonIgnoreProperties(ignoreUnknown = true) + private interface Value { + T visit(Visitor visitor); + } + + @JsonTypeName("v1") + @JsonIgnoreProperties("version") + private static final class V1Value implements Value { + @JsonUnwrapped + @JsonIgnoreProperties(value = "version", allowSetters = true) + private DeepgramListenProviderV1 value; + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + private V1Value() {} + + private V1Value(DeepgramListenProviderV1 value) { + this.value = value; + } + + @java.lang.Override + public T visit(Visitor visitor) { + return visitor.visitV1(value); + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof V1Value && equalTo((V1Value) other); + } + + private boolean equalTo(V1Value other) { + return value.equals(other.value); + } + + @java.lang.Override + public int hashCode() { + return Objects.hash(this.value); + } + + @java.lang.Override + public String toString() { + return "AgentV1SettingsAgentListenProvider{" + "value: " + value + "}"; + } + } + + @JsonTypeName("v2") + @JsonIgnoreProperties("version") + private static final class V2Value implements Value { + @JsonUnwrapped + @JsonIgnoreProperties(value = "version", allowSetters = true) + private DeepgramListenProviderV2 value; + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + private V2Value() {} + + private V2Value(DeepgramListenProviderV2 value) { + this.value = value; + } + + @java.lang.Override + public T visit(Visitor visitor) { + return visitor.visitV2(value); + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof V2Value && equalTo((V2Value) other); + } + + private boolean equalTo(V2Value other) { + return value.equals(other.value); + } + + @java.lang.Override + public int hashCode() { + return Objects.hash(this.value); + } + + @java.lang.Override + public String toString() { + return "AgentV1SettingsAgentListenProvider{" + "value: " + value + "}"; + } + } + + @JsonIgnoreProperties("version") + private static final class _UnknownValue implements Value { + private String type; + + @JsonValue + private Object value; + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + private _UnknownValue(@JsonProperty("value") Object value) {} + + @java.lang.Override + public T visit(Visitor visitor) { + return visitor._visitUnknown(value); + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof _UnknownValue && equalTo((_UnknownValue) other); + } + + private boolean equalTo(_UnknownValue other) { + return type.equals(other.type) && value.equals(other.value); + } + + @java.lang.Override + public int hashCode() { + return Objects.hash(this.type, this.value); + } + + @java.lang.Override + public String toString() { + return "AgentV1SettingsAgentListenProvider{" + "type: " + type + ", value: " + value + "}"; + } + } +} diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsApplied.java.bak b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsApplied.java.bak new file mode 100644 index 0000000..ad1fdb2 --- /dev/null +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsApplied.java.bak @@ -0,0 +1,83 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.resources.agent.v1.types; + +import com.deepgram.core.ObjectMappers; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.util.HashMap; +import java.util.Map; + +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonDeserialize(builder = AgentV1SettingsApplied.Builder.class) +public final class AgentV1SettingsApplied { + private final Map additionalProperties; + + private AgentV1SettingsApplied(Map additionalProperties) { + this.additionalProperties = additionalProperties; + } + + /** + * @return Message type identifier for settings applied confirmation + */ + @JsonProperty("type") + public String getType() { + return "SettingsApplied"; + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof AgentV1SettingsApplied; + } + + @java.lang.Override + public int hashCode() { + return getClass().hashCode(); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + @java.lang.Override + public String toString() { + return ObjectMappers.stringify(this); + } + + public static Builder builder() { + return new Builder(); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static final class Builder { + @JsonAnySetter + private Map additionalProperties = new HashMap<>(); + + private Builder() {} + + public Builder from(AgentV1SettingsApplied other) { + return this; + } + + public AgentV1SettingsApplied build() { + return new AgentV1SettingsApplied(additionalProperties); + } + + public Builder additionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + return this; + } + + public Builder additionalProperties(Map additionalProperties) { + this.additionalProperties.putAll(additionalProperties); + return this; + } + } +} diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SpeakUpdated.java.bak b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SpeakUpdated.java.bak new file mode 100644 index 0000000..8b134b5 --- /dev/null +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SpeakUpdated.java.bak @@ -0,0 +1,83 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.resources.agent.v1.types; + +import com.deepgram.core.ObjectMappers; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.util.HashMap; +import java.util.Map; + +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonDeserialize(builder = AgentV1SpeakUpdated.Builder.class) +public final class AgentV1SpeakUpdated { + private final Map additionalProperties; + + private AgentV1SpeakUpdated(Map additionalProperties) { + this.additionalProperties = additionalProperties; + } + + /** + * @return Message type identifier for speak update confirmation + */ + @JsonProperty("type") + public String getType() { + return "SpeakUpdated"; + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof AgentV1SpeakUpdated; + } + + @java.lang.Override + public int hashCode() { + return getClass().hashCode(); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + @java.lang.Override + public String toString() { + return ObjectMappers.stringify(this); + } + + public static Builder builder() { + return new Builder(); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static final class Builder { + @JsonAnySetter + private Map additionalProperties = new HashMap<>(); + + private Builder() {} + + public Builder from(AgentV1SpeakUpdated other) { + return this; + } + + public AgentV1SpeakUpdated build() { + return new AgentV1SpeakUpdated(additionalProperties); + } + + public Builder additionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + return this; + } + + public Builder additionalProperties(Map additionalProperties) { + this.additionalProperties.putAll(additionalProperties); + return this; + } + } +} diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ThinkUpdated.java.bak b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ThinkUpdated.java.bak new file mode 100644 index 0000000..2d67cad --- /dev/null +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ThinkUpdated.java.bak @@ -0,0 +1,83 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.resources.agent.v1.types; + +import com.deepgram.core.ObjectMappers; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.util.HashMap; +import java.util.Map; + +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonDeserialize(builder = AgentV1ThinkUpdated.Builder.class) +public final class AgentV1ThinkUpdated { + private final Map additionalProperties; + + private AgentV1ThinkUpdated(Map additionalProperties) { + this.additionalProperties = additionalProperties; + } + + /** + * @return Message type identifier for think update confirmation + */ + @JsonProperty("type") + public String getType() { + return "ThinkUpdated"; + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof AgentV1ThinkUpdated; + } + + @java.lang.Override + public int hashCode() { + return getClass().hashCode(); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + @java.lang.Override + public String toString() { + return ObjectMappers.stringify(this); + } + + public static Builder builder() { + return new Builder(); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static final class Builder { + @JsonAnySetter + private Map additionalProperties = new HashMap<>(); + + private Builder() {} + + public Builder from(AgentV1ThinkUpdated other) { + return this; + } + + public AgentV1ThinkUpdated build() { + return new AgentV1ThinkUpdated(additionalProperties); + } + + public Builder additionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + return this; + } + + public Builder additionalProperties(Map additionalProperties) { + this.additionalProperties.putAll(additionalProperties); + return this; + } + } +} diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UpdateListenListenProvider.java.bak b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UpdateListenListenProvider.java.bak new file mode 100644 index 0000000..e739aec --- /dev/null +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UpdateListenListenProvider.java.bak @@ -0,0 +1,224 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.resources.agent.v1.types; + +import com.deepgram.types.DeepgramListenProviderV1; +import com.deepgram.types.DeepgramListenProviderV2; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonUnwrapped; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Objects; +import java.util.Optional; + +public final class AgentV1UpdateListenListenProvider { + private final Value value; + + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) + private AgentV1UpdateListenListenProvider(Value value) { + this.value = value; + } + + public T visit(Visitor visitor) { + return value.visit(visitor); + } + + public static AgentV1UpdateListenListenProvider v1(DeepgramListenProviderV1 value) { + return new AgentV1UpdateListenListenProvider(new V1Value(value)); + } + + public static AgentV1UpdateListenListenProvider v2(DeepgramListenProviderV2 value) { + return new AgentV1UpdateListenListenProvider(new V2Value(value)); + } + + public boolean isV1() { + return value instanceof V1Value; + } + + public boolean isV2() { + return value instanceof V2Value; + } + + public boolean _isUnknown() { + return value instanceof _UnknownValue; + } + + public Optional getV1() { + if (isV1()) { + return Optional.of(((V1Value) value).value); + } + return Optional.empty(); + } + + public Optional getV2() { + if (isV2()) { + return Optional.of(((V2Value) value).value); + } + return Optional.empty(); + } + + public Optional _getUnknown() { + if (_isUnknown()) { + return Optional.of(((_UnknownValue) value).value); + } + return Optional.empty(); + } + + @Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof AgentV1UpdateListenListenProvider + && value.equals(((AgentV1UpdateListenListenProvider) other).value); + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + + @Override + public String toString() { + return value.toString(); + } + + @JsonValue + private Value getValue() { + return this.value; + } + + public interface Visitor { + T visitV1(DeepgramListenProviderV1 v1); + + T visitV2(DeepgramListenProviderV2 v2); + + T _visitUnknown(Object unknownType); + } + + @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "version", visible = true, defaultImpl = V2Value.class) + @JsonSubTypes({@JsonSubTypes.Type(V1Value.class), @JsonSubTypes.Type(V2Value.class)}) + @JsonIgnoreProperties(ignoreUnknown = true) + private interface Value { + T visit(Visitor visitor); + } + + @JsonTypeName("v1") + @JsonIgnoreProperties("version") + private static final class V1Value implements Value { + @JsonUnwrapped + @JsonIgnoreProperties(value = "version", allowSetters = true) + private DeepgramListenProviderV1 value; + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + private V1Value() {} + + private V1Value(DeepgramListenProviderV1 value) { + this.value = value; + } + + @java.lang.Override + public T visit(Visitor visitor) { + return visitor.visitV1(value); + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof V1Value && equalTo((V1Value) other); + } + + private boolean equalTo(V1Value other) { + return value.equals(other.value); + } + + @java.lang.Override + public int hashCode() { + return Objects.hash(this.value); + } + + @java.lang.Override + public String toString() { + return "AgentV1UpdateListenListenProvider{" + "value: " + value + "}"; + } + } + + @JsonTypeName("v2") + @JsonIgnoreProperties("version") + private static final class V2Value implements Value { + @JsonUnwrapped + @JsonIgnoreProperties(value = "version", allowSetters = true) + private DeepgramListenProviderV2 value; + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + private V2Value() {} + + private V2Value(DeepgramListenProviderV2 value) { + this.value = value; + } + + @java.lang.Override + public T visit(Visitor visitor) { + return visitor.visitV2(value); + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof V2Value && equalTo((V2Value) other); + } + + private boolean equalTo(V2Value other) { + return value.equals(other.value); + } + + @java.lang.Override + public int hashCode() { + return Objects.hash(this.value); + } + + @java.lang.Override + public String toString() { + return "AgentV1UpdateListenListenProvider{" + "value: " + value + "}"; + } + } + + @JsonIgnoreProperties("version") + private static final class _UnknownValue implements Value { + private String type; + + @JsonValue + private Object value; + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + private _UnknownValue(@JsonProperty("value") Object value) {} + + @java.lang.Override + public T visit(Visitor visitor) { + return visitor._visitUnknown(value); + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof _UnknownValue && equalTo((_UnknownValue) other); + } + + private boolean equalTo(_UnknownValue other) { + return type.equals(other.type) && value.equals(other.value); + } + + @java.lang.Override + public int hashCode() { + return Objects.hash(this.type, this.value); + } + + @java.lang.Override + public String toString() { + return "AgentV1UpdateListenListenProvider{" + "type: " + type + ", value: " + value + "}"; + } + } +} diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UserStartedSpeaking.java.bak b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UserStartedSpeaking.java.bak new file mode 100644 index 0000000..3556d31 --- /dev/null +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UserStartedSpeaking.java.bak @@ -0,0 +1,83 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.resources.agent.v1.types; + +import com.deepgram.core.ObjectMappers; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.util.HashMap; +import java.util.Map; + +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonDeserialize(builder = AgentV1UserStartedSpeaking.Builder.class) +public final class AgentV1UserStartedSpeaking { + private final Map additionalProperties; + + private AgentV1UserStartedSpeaking(Map additionalProperties) { + this.additionalProperties = additionalProperties; + } + + /** + * @return Message type identifier indicating that the user has begun speaking + */ + @JsonProperty("type") + public String getType() { + return "UserStartedSpeaking"; + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof AgentV1UserStartedSpeaking; + } + + @java.lang.Override + public int hashCode() { + return getClass().hashCode(); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + @java.lang.Override + public String toString() { + return ObjectMappers.stringify(this); + } + + public static Builder builder() { + return new Builder(); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static final class Builder { + @JsonAnySetter + private Map additionalProperties = new HashMap<>(); + + private Builder() {} + + public Builder from(AgentV1UserStartedSpeaking other) { + return this; + } + + public AgentV1UserStartedSpeaking build() { + return new AgentV1UserStartedSpeaking(additionalProperties); + } + + public Builder additionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + return this; + } + + public Builder additionalProperties(Map additionalProperties) { + this.additionalProperties.putAll(additionalProperties); + return this; + } + } +} diff --git a/src/main/java/com/deepgram/resources/listen/v1/websocket/V1WebSocketClient.java.bak b/src/main/java/com/deepgram/resources/listen/v1/websocket/V1WebSocketClient.java.bak new file mode 100644 index 0000000..e7cd50c --- /dev/null +++ b/src/main/java/com/deepgram/resources/listen/v1/websocket/V1WebSocketClient.java.bak @@ -0,0 +1,592 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.resources.listen.v1.websocket; + +import com.deepgram.core.ClientOptions; +import com.deepgram.core.DisconnectReason; +import com.deepgram.core.ObjectMappers; +import com.deepgram.core.QueryStringMapper; +import com.deepgram.core.ReconnectingWebSocketListener; +import com.deepgram.core.RequestOptions; +import com.deepgram.core.WebSocketReadyState; +import com.deepgram.resources.listen.v1.types.ListenV1CloseStream; +import com.deepgram.resources.listen.v1.types.ListenV1Configure; +import com.deepgram.resources.listen.v1.types.ListenV1Error; +import com.deepgram.resources.listen.v1.types.ListenV1Finalize; +import com.deepgram.resources.listen.v1.types.ListenV1KeepAlive; +import com.deepgram.resources.listen.v1.types.ListenV1Metadata; +import com.deepgram.resources.listen.v1.types.ListenV1Results; +import com.deepgram.resources.listen.v1.types.ListenV1SpeechStarted; +import com.deepgram.resources.listen.v1.types.ListenV1UtteranceEnd; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ScheduledExecutorService; +import java.util.function.Consumer; +import okhttp3.HttpUrl; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.WebSocket; +import okio.ByteString; + +/** + * WebSocket client for the v1 channel. + * Provides real-time bidirectional communication with strongly-typed messages. + */ +public class V1WebSocketClient implements AutoCloseable { + protected final ClientOptions clientOptions; + + private final ObjectMapper objectMapper; + + private final OkHttpClient okHttpClient; + + private ScheduledExecutorService timeoutExecutor; + + private volatile WebSocketReadyState readyState = WebSocketReadyState.CLOSED; + + private volatile Runnable onConnectedHandler; + + private volatile Consumer onDisconnectedHandler; + + private volatile Consumer onErrorHandler; + + private volatile Consumer onMessageHandler; + + private volatile ReconnectingWebSocketListener.ReconnectOptions reconnectOptions; + + private CompletableFuture connectionFuture; + + private ReconnectingWebSocketListener reconnectingListener; + + private volatile Consumer resultsHandler; + + private volatile Consumer metadataHandler; + + private volatile Consumer utteranceEndHandler; + + private volatile Consumer speechStartedHandler; + + private volatile Consumer errorHandler; + + /** + * Creates a new async WebSocket client for the v1 channel. + */ + public V1WebSocketClient(ClientOptions clientOptions) { + this.clientOptions = clientOptions; + this.objectMapper = ObjectMappers.JSON_MAPPER; + this.okHttpClient = clientOptions.httpClient(); + } + + /** + * Establishes the WebSocket connection asynchronously with automatic reconnection. + * @return a CompletableFuture that completes when the connection is established + * @param options connection options including query parameters + */ + public CompletableFuture connect(V1ConnectOptions options) { + connectionFuture = new CompletableFuture<>(); + String baseUrl = clientOptions.environment().getProductionURL(); + String fullPath = "/v1/listen"; + if (baseUrl.endsWith("/") && fullPath.startsWith("/")) { + fullPath = fullPath.substring(1); + } else if (!baseUrl.endsWith("/") && !fullPath.startsWith("/")) { + fullPath = "/" + fullPath; + } + // OkHttp's HttpUrl only supports http/https schemes; convert wss/ws for URL parsing + if (baseUrl.startsWith("wss://")) { + baseUrl = "https://" + baseUrl.substring(6); + } else if (baseUrl.startsWith("ws://")) { + baseUrl = "http://" + baseUrl.substring(5); + } + HttpUrl parsedUrl = HttpUrl.parse(baseUrl + fullPath); + if (parsedUrl == null) { + throw new IllegalArgumentException("Invalid WebSocket URL: " + baseUrl + fullPath); + } + HttpUrl.Builder urlBuilder = parsedUrl.newBuilder(); + if (options.getCallback() != null && options.getCallback().isPresent()) { + urlBuilder.addQueryParameter( + "callback", String.valueOf(options.getCallback().get())); + } + if (options.getCallbackMethod() != null && options.getCallbackMethod().isPresent()) { + urlBuilder.addQueryParameter( + "callback_method", + String.valueOf(options.getCallbackMethod().get())); + } + if (options.getChannels() != null && options.getChannels().isPresent()) { + urlBuilder.addQueryParameter( + "channels", String.valueOf(options.getChannels().get())); + } + if (options.getDetectEntities() != null && options.getDetectEntities().isPresent()) { + urlBuilder.addQueryParameter( + "detect_entities", + String.valueOf(options.getDetectEntities().get())); + } + if (options.getDiarize() != null && options.getDiarize().isPresent()) { + urlBuilder.addQueryParameter( + "diarize", String.valueOf(options.getDiarize().get())); + } + if (options.getDiarizeModel() != null && options.getDiarizeModel().isPresent()) { + urlBuilder.addQueryParameter( + "diarize_model", String.valueOf(options.getDiarizeModel().get())); + } + if (options.getDictation() != null && options.getDictation().isPresent()) { + urlBuilder.addQueryParameter( + "dictation", String.valueOf(options.getDictation().get())); + } + if (options.getEncoding() != null && options.getEncoding().isPresent()) { + urlBuilder.addQueryParameter( + "encoding", String.valueOf(options.getEncoding().get())); + } + if (options.getEndpointing() != null && options.getEndpointing().isPresent()) { + urlBuilder.addQueryParameter( + "endpointing", String.valueOf(options.getEndpointing().get())); + } + if (options.getExtra() != null && options.getExtra().isPresent()) { + QueryStringMapper.addQueryParameter(urlBuilder, "extra", options.getExtra().get().get(), true); + } + if (options.getInterimResults() != null && options.getInterimResults().isPresent()) { + urlBuilder.addQueryParameter( + "interim_results", + String.valueOf(options.getInterimResults().get())); + } + if (options.getKeyterm() != null && options.getKeyterm().isPresent()) { + QueryStringMapper.addQueryParameter(urlBuilder, "keyterm", options.getKeyterm().get().get(), true); + } + if (options.getKeywords() != null && options.getKeywords().isPresent()) { + QueryStringMapper.addQueryParameter(urlBuilder, "keywords", options.getKeywords().get().get(), true); + } + if (options.getLanguage() != null && options.getLanguage().isPresent()) { + urlBuilder.addQueryParameter( + "language", String.valueOf(options.getLanguage().get())); + } + if (options.getMipOptOut() != null && options.getMipOptOut().isPresent()) { + urlBuilder.addQueryParameter( + "mip_opt_out", String.valueOf(options.getMipOptOut().get())); + } + urlBuilder.addQueryParameter("model", String.valueOf(options.getModel())); + if (options.getMultichannel() != null && options.getMultichannel().isPresent()) { + urlBuilder.addQueryParameter( + "multichannel", String.valueOf(options.getMultichannel().get())); + } + if (options.getNumerals() != null && options.getNumerals().isPresent()) { + urlBuilder.addQueryParameter( + "numerals", String.valueOf(options.getNumerals().get())); + } + if (options.getProfanityFilter() != null && options.getProfanityFilter().isPresent()) { + urlBuilder.addQueryParameter( + "profanity_filter", + String.valueOf(options.getProfanityFilter().get())); + } + if (options.getPunctuate() != null && options.getPunctuate().isPresent()) { + urlBuilder.addQueryParameter( + "punctuate", String.valueOf(options.getPunctuate().get())); + } + if (options.getRedact() != null && options.getRedact().isPresent()) { + urlBuilder.addQueryParameter( + "redact", String.valueOf(options.getRedact().get())); + } + if (options.getReplace() != null && options.getReplace().isPresent()) { + QueryStringMapper.addQueryParameter(urlBuilder, "replace", options.getReplace().get().get(), true); + } + if (options.getSampleRate() != null && options.getSampleRate().isPresent()) { + urlBuilder.addQueryParameter( + "sample_rate", String.valueOf(options.getSampleRate().get())); + } + if (options.getSearch() != null && options.getSearch().isPresent()) { + QueryStringMapper.addQueryParameter(urlBuilder, "search", options.getSearch().get().get(), true); + } + if (options.getSmartFormat() != null && options.getSmartFormat().isPresent()) { + urlBuilder.addQueryParameter( + "smart_format", String.valueOf(options.getSmartFormat().get())); + } + if (options.getTag() != null && options.getTag().isPresent()) { + QueryStringMapper.addQueryParameter(urlBuilder, "tag", options.getTag().get().get(), true); + } + if (options.getUtteranceEndMs() != null && options.getUtteranceEndMs().isPresent()) { + urlBuilder.addQueryParameter( + "utterance_end_ms", + String.valueOf(options.getUtteranceEndMs().get())); + } + if (options.getVadEvents() != null && options.getVadEvents().isPresent()) { + urlBuilder.addQueryParameter( + "vad_events", String.valueOf(options.getVadEvents().get())); + } + if (options.getVersion() != null && options.getVersion().isPresent()) { + urlBuilder.addQueryParameter( + "version", String.valueOf(options.getVersion().get())); + } + if (options.getAdditionalProperties() != null) { + options.getAdditionalProperties().forEach((key, value) -> { + if (value != null) { + QueryStringMapper.addQueryParameter(urlBuilder, key, value, true); + } + }); + } + Request.Builder requestBuilder = new Request.Builder().url(urlBuilder.build()); + clientOptions.headers((RequestOptions) null).forEach(requestBuilder::addHeader); + final Request request = requestBuilder.build(); + this.readyState = WebSocketReadyState.CONNECTING; + ReconnectingWebSocketListener.ReconnectOptions reconnectOpts = this.reconnectOptions != null + ? this.reconnectOptions + : ReconnectingWebSocketListener.ReconnectOptions.builder().build(); + this.reconnectingListener = + new ReconnectingWebSocketListener( + reconnectOpts, + () -> { + if (clientOptions.isClosed()) { + throw new IllegalStateException("root client has been closed"); + } + if (clientOptions.webSocketFactory().isPresent()) { + return clientOptions + .webSocketFactory() + .get() + .create(request, this.reconnectingListener); + } else { + return okHttpClient.newWebSocket(request, this.reconnectingListener); + } + }, + clientOptions::isClosed) { + @Override + protected void onWebSocketOpen(WebSocket webSocket, Response response) { + readyState = WebSocketReadyState.OPEN; + if (onConnectedHandler != null) { + onConnectedHandler.run(); + } + connectionFuture.complete(null); + } + + @Override + protected void onWebSocketMessage(WebSocket webSocket, String text) { + handleIncomingMessage(text); + } + + @Override + protected void onWebSocketBinaryMessage(WebSocket webSocket, ByteString bytes) {} + + @Override + protected void onWebSocketFailure(WebSocket webSocket, Throwable t, Response response) { + readyState = WebSocketReadyState.CLOSED; + if (onErrorHandler != null) { + onErrorHandler.accept(new RuntimeException(t)); + } + connectionFuture.completeExceptionally(t); + } + + @Override + protected void onWebSocketClosed(WebSocket webSocket, int code, String reason) { + readyState = WebSocketReadyState.CLOSED; + if (onDisconnectedHandler != null) { + onDisconnectedHandler.accept(new DisconnectReason(code, reason)); + } + } + }; + clientOptions.registerWebSocket(this); + reconnectingListener.connect(); + return connectionFuture; + } + + /** + * Disconnects the WebSocket connection and releases resources. + */ + public void disconnect() { + clientOptions.unregisterWebSocket(this); + if (reconnectingListener != null) { + reconnectingListener.disconnect(); + } + if (timeoutExecutor != null) { + timeoutExecutor.shutdownNow(); + timeoutExecutor = null; + } + } + + /** + * Gets the current state of the WebSocket connection. + * + * This provides the actual connection state, similar to the W3C WebSocket API. + * + * @return the current WebSocket ready state + */ + public WebSocketReadyState getReadyState() { + return readyState; + } + + /** + * Sends a ListenV1Media message to the server asynchronously. + * @param message the message to send + * @return a CompletableFuture that completes when the message is sent + */ + public CompletableFuture sendMedia(ByteString message) { + CompletableFuture future = new CompletableFuture<>(); + try { + assertSocketIsOpen(); + // Use reconnecting listener's sendBinary method which handles queuing + reconnectingListener.sendBinary(message); + future.complete(null); + } catch (Exception e) { + future.completeExceptionally(new RuntimeException("Failed to send binary data", e)); + } + return future; + } + + /** + * Sends a ListenV1Finalize message to the server asynchronously. + * @param message the message to send + * @return a CompletableFuture that completes when the message is sent + */ + public CompletableFuture sendFinalize(ListenV1Finalize message) { + return sendMessage(message); + } + + /** + * Sends a ListenV1CloseStream message to the server asynchronously. + * @param message the message to send + * @return a CompletableFuture that completes when the message is sent + */ + public CompletableFuture sendCloseStream(ListenV1CloseStream message) { + return sendMessage(message); + } + + /** + * Sends a ListenV1KeepAlive message to the server asynchronously. + * @param message the message to send + * @return a CompletableFuture that completes when the message is sent + */ + public CompletableFuture sendKeepAlive(ListenV1KeepAlive message) { + return sendMessage(message); + } + + /** + * Sends a ListenV1Configure message to the server asynchronously. + * @param message the message to send + * @return a CompletableFuture that completes when the message is sent + */ + public CompletableFuture sendConfigure(ListenV1Configure message) { + return sendMessage(message); + } + + /** + * Registers a handler for ListenV1Results messages from the server. + * @param handler the handler to invoke when a message is received + */ + public void onResults(Consumer handler) { + this.resultsHandler = handler; + } + + /** + * Registers a handler for ListenV1Metadata messages from the server. + * @param handler the handler to invoke when a message is received + */ + public void onMetadata(Consumer handler) { + this.metadataHandler = handler; + } + + /** + * Registers a handler for ListenV1UtteranceEnd messages from the server. + * @param handler the handler to invoke when a message is received + */ + public void onUtteranceEnd(Consumer handler) { + this.utteranceEndHandler = handler; + } + + /** + * Registers a handler for ListenV1SpeechStarted messages from the server. + * @param handler the handler to invoke when a message is received + */ + public void onSpeechStarted(Consumer handler) { + this.speechStartedHandler = handler; + } + + /** + * Registers a handler for ListenV1Error messages from the server. + * @param handler the handler to invoke when a message is received + */ + public void onErrorMessage(Consumer handler) { + this.errorHandler = handler; + } + + /** + * Registers a handler called when the connection is established. + * @param handler the handler to invoke when connected + */ + public void onConnected(Runnable handler) { + this.onConnectedHandler = handler; + } + + /** + * Registers a handler called when the connection is closed. + * @param handler the handler to invoke when disconnected + */ + public void onDisconnected(Consumer handler) { + this.onDisconnectedHandler = handler; + } + + /** + * Registers a handler called when an error occurs. + * @param handler the handler to invoke on error + */ + public void onError(Consumer handler) { + this.onErrorHandler = handler; + } + + /** + * Registers a handler called for every incoming text message. + * The handler receives the raw JSON string before type-specific dispatch. + * @param handler the handler to invoke with the raw message JSON + */ + public void onMessage(Consumer handler) { + this.onMessageHandler = handler; + } + + /** + * Configures reconnection behavior. Must be called before {@link #connect}. + * + * @param options the reconnection options (backoff, retries, queue size) + */ + public void reconnectOptions(ReconnectingWebSocketListener.ReconnectOptions options) { + this.reconnectOptions = options; + } + + /** + * Closes this WebSocket client, releasing all resources. + * Equivalent to calling {@link #disconnect()}. + */ + @Override + public void close() { + disconnect(); + } + + /** + * Ensures the WebSocket is connected and ready to send messages. + * @throws IllegalStateException if the socket is not connected or not open + */ + private void assertSocketIsOpen() { + if (reconnectingListener.getWebSocket() == null) { + throw new IllegalStateException("WebSocket is not connected. Call connect() first."); + } + if (readyState != WebSocketReadyState.OPEN) { + throw new IllegalStateException("WebSocket is not open. Current state: " + readyState); + } + } + + private CompletableFuture sendMessage(Object body) { + CompletableFuture future = new CompletableFuture<>(); + try { + assertSocketIsOpen(); + String json = objectMapper.writeValueAsString(body); + // Use reconnecting listener's send method which handles queuing + reconnectingListener.send(json); + future.complete(null); + } catch (IllegalStateException e) { + future.completeExceptionally(e); + } catch (Exception e) { + future.completeExceptionally(new RuntimeException("Failed to send message", e)); + } + return future; + } + + private void handleIncomingMessage(String json) { + try { + if (onMessageHandler != null) { + onMessageHandler.accept(json); + } + JsonNode node = objectMapper.readTree(json); + if (node == null || node.isNull()) { + throw new IllegalArgumentException("Received null or invalid JSON message"); + } + if (node.has("transaction_key") + && node.has("request_id") + && node.has("sha256") + && node.has("created") + && node.has("duration") + && node.has("channels") + && "Metadata".equals(node.path("type").asText())) { + ListenV1Metadata metadataHandlerEvent = null; + try { + metadataHandlerEvent = objectMapper.treeToValue(node, ListenV1Metadata.class); + } catch (Exception e) { + } + if (metadataHandlerEvent != null) { + if (metadataHandler != null) { + metadataHandler.accept(metadataHandlerEvent); + } + return; + } + } + if (node.has("channel_index") + && node.has("duration") + && node.has("start") + && node.has("channel") + && node.has("metadata") + && "Results".equals(node.path("type").asText())) { + ListenV1Results resultsHandlerEvent = null; + try { + resultsHandlerEvent = objectMapper.treeToValue(node, ListenV1Results.class); + } catch (Exception e) { + } + if (resultsHandlerEvent != null) { + if (resultsHandler != null) { + resultsHandler.accept(resultsHandlerEvent); + } + return; + } + } + if (node.has("channel") + && node.has("last_word_end") + && "UtteranceEnd".equals(node.path("type").asText())) { + ListenV1UtteranceEnd utteranceEndHandlerEvent = null; + try { + utteranceEndHandlerEvent = objectMapper.treeToValue(node, ListenV1UtteranceEnd.class); + } catch (Exception e) { + } + if (utteranceEndHandlerEvent != null) { + if (utteranceEndHandler != null) { + utteranceEndHandler.accept(utteranceEndHandlerEvent); + } + return; + } + } + if (node.has("channel") + && node.has("timestamp") + && "SpeechStarted".equals(node.path("type").asText())) { + ListenV1SpeechStarted speechStartedHandlerEvent = null; + try { + speechStartedHandlerEvent = objectMapper.treeToValue(node, ListenV1SpeechStarted.class); + } catch (Exception e) { + } + if (speechStartedHandlerEvent != null) { + if (speechStartedHandler != null) { + speechStartedHandler.accept(speechStartedHandlerEvent); + } + return; + } + } + if (node.has("variant") + && node.has("description") + && "Error".equals(node.path("type").asText())) { + ListenV1Error errorHandlerEvent = null; + try { + errorHandlerEvent = objectMapper.treeToValue(node, ListenV1Error.class); + } catch (Exception e) { + } + if (errorHandlerEvent != null) { + if (errorHandler != null) { + errorHandler.accept(errorHandlerEvent); + } else if (onErrorHandler != null) { + onErrorHandler.accept(new ListenV1ErrorException(errorHandlerEvent)); + } + return; + } + } + if (onErrorHandler != null) { + onErrorHandler.accept(new RuntimeException( + "Unrecognized WebSocket message: " + json.substring(0, Math.min(200, json.length())) + + "... Update your SDK version to support new message types.")); + } + } catch (Exception e) { + if (onErrorHandler != null) { + onErrorHandler.accept(e); + } + } + } +} diff --git a/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2CloseStream.java.bak b/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2CloseStream.java.bak new file mode 100644 index 0000000..c9f2f35 --- /dev/null +++ b/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2CloseStream.java.bak @@ -0,0 +1,83 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.resources.listen.v2.types; + +import com.deepgram.core.ObjectMappers; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.util.HashMap; +import java.util.Map; + +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonDeserialize(builder = ListenV2CloseStream.Builder.class) +public final class ListenV2CloseStream { + private final Map additionalProperties; + + private ListenV2CloseStream(Map additionalProperties) { + this.additionalProperties = additionalProperties; + } + + /** + * @return Message type identifier + */ + @JsonProperty("type") + public String getType() { + return "CloseStream"; + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof ListenV2CloseStream; + } + + @java.lang.Override + public int hashCode() { + return getClass().hashCode(); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + @java.lang.Override + public String toString() { + return ObjectMappers.stringify(this); + } + + public static Builder builder() { + return new Builder(); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static final class Builder { + @JsonAnySetter + private Map additionalProperties = new HashMap<>(); + + private Builder() {} + + public Builder from(ListenV2CloseStream other) { + return this; + } + + public ListenV2CloseStream build() { + return new ListenV2CloseStream(additionalProperties); + } + + public Builder additionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + return this; + } + + public Builder additionalProperties(Map additionalProperties) { + this.additionalProperties.putAll(additionalProperties); + return this; + } + } +} diff --git a/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ForceEndTurn.java.bak b/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ForceEndTurn.java.bak new file mode 100644 index 0000000..894bd3c --- /dev/null +++ b/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ForceEndTurn.java.bak @@ -0,0 +1,83 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.resources.listen.v2.types; + +import com.deepgram.core.ObjectMappers; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.util.HashMap; +import java.util.Map; + +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonDeserialize(builder = ListenV2ForceEndTurn.Builder.class) +public final class ListenV2ForceEndTurn { + private final Map additionalProperties; + + private ListenV2ForceEndTurn(Map additionalProperties) { + this.additionalProperties = additionalProperties; + } + + /** + * @return Message type identifier + */ + @JsonProperty("type") + public String getType() { + return "ForceEndTurn"; + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof ListenV2ForceEndTurn; + } + + @java.lang.Override + public int hashCode() { + return getClass().hashCode(); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + @java.lang.Override + public String toString() { + return ObjectMappers.stringify(this); + } + + public static Builder builder() { + return new Builder(); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static final class Builder { + @JsonAnySetter + private Map additionalProperties = new HashMap<>(); + + private Builder() {} + + public Builder from(ListenV2ForceEndTurn other) { + return this; + } + + public ListenV2ForceEndTurn build() { + return new ListenV2ForceEndTurn(additionalProperties); + } + + public Builder additionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + return this; + } + + public Builder additionalProperties(Map additionalProperties) { + this.additionalProperties.putAll(additionalProperties); + return this; + } + } +} diff --git a/src/main/java/com/deepgram/resources/listen/v2/websocket/V2WebSocketClient.java.bak b/src/main/java/com/deepgram/resources/listen/v2/websocket/V2WebSocketClient.java.bak new file mode 100644 index 0000000..5f55fea --- /dev/null +++ b/src/main/java/com/deepgram/resources/listen/v2/websocket/V2WebSocketClient.java.bak @@ -0,0 +1,563 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.resources.listen.v2.websocket; + +import com.deepgram.core.ClientOptions; +import com.deepgram.core.DisconnectReason; +import com.deepgram.core.ObjectMappers; +import com.deepgram.core.QueryStringMapper; +import com.deepgram.core.ReconnectingWebSocketListener; +import com.deepgram.core.RequestOptions; +import com.deepgram.core.WebSocketReadyState; +import com.deepgram.resources.listen.v2.types.ListenV2CloseStream; +import com.deepgram.resources.listen.v2.types.ListenV2Configure; +import com.deepgram.resources.listen.v2.types.ListenV2ConfigureFailure; +import com.deepgram.resources.listen.v2.types.ListenV2ConfigureSuccess; +import com.deepgram.resources.listen.v2.types.ListenV2Connected; +import com.deepgram.resources.listen.v2.types.ListenV2FatalError; +import com.deepgram.resources.listen.v2.types.ListenV2ForceEndTurn; +import com.deepgram.resources.listen.v2.types.ListenV2TurnInfo; +import com.deepgram.resources.listen.v2.types.ListenV2Warning; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; +import okhttp3.HttpUrl; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.WebSocket; +import okio.ByteString; + +/** + * WebSocket client for the v2 channel. + * Provides real-time bidirectional communication with strongly-typed messages. + */ +public class V2WebSocketClient implements AutoCloseable { + protected final ClientOptions clientOptions; + + private final ObjectMapper objectMapper; + + private final OkHttpClient okHttpClient; + + private ScheduledExecutorService timeoutExecutor; + + private volatile WebSocketReadyState readyState = WebSocketReadyState.CLOSED; + + private volatile Runnable onConnectedHandler; + + private volatile Consumer onDisconnectedHandler; + + private volatile Consumer onErrorHandler; + + private volatile Consumer onMessageHandler; + + private volatile ReconnectingWebSocketListener.ReconnectOptions reconnectOptions; + + private CompletableFuture connectionFuture; + + private ReconnectingWebSocketListener reconnectingListener; + + private final AtomicReference closeStreamSocket = new AtomicReference<>(); + + private volatile Consumer connectedHandler; + + private volatile Consumer turnInfoHandler; + + private volatile Consumer configureSuccessHandler; + + private volatile Consumer configureFailureHandler; + + private volatile Consumer warningHandler; + + private volatile Consumer errorHandler; + + /** + * Creates a new async WebSocket client for the v2 channel. + */ + public V2WebSocketClient(ClientOptions clientOptions) { + this.clientOptions = clientOptions; + this.objectMapper = ObjectMappers.JSON_MAPPER; + this.okHttpClient = clientOptions.httpClient(); + } + + /** + * Establishes the WebSocket connection asynchronously with automatic reconnection. + * @return a CompletableFuture that completes when the connection is established + * @param options connection options including query parameters + */ + public CompletableFuture connect(V2ConnectOptions options) { + connectionFuture = new CompletableFuture<>(); + closeStreamSocket.set(null); + String baseUrl = clientOptions.environment().getProductionURL(); + String fullPath = "/v2/listen"; + if (baseUrl.endsWith("/") && fullPath.startsWith("/")) { + fullPath = fullPath.substring(1); + } else if (!baseUrl.endsWith("/") && !fullPath.startsWith("/")) { + fullPath = "/" + fullPath; + } + // OkHttp's HttpUrl only supports http/https schemes; convert wss/ws for URL parsing + if (baseUrl.startsWith("wss://")) { + baseUrl = "https://" + baseUrl.substring(6); + } else if (baseUrl.startsWith("ws://")) { + baseUrl = "http://" + baseUrl.substring(5); + } + HttpUrl parsedUrl = HttpUrl.parse(baseUrl + fullPath); + if (parsedUrl == null) { + throw new IllegalArgumentException("Invalid WebSocket URL: " + baseUrl + fullPath); + } + HttpUrl.Builder urlBuilder = parsedUrl.newBuilder(); + urlBuilder.addQueryParameter("model", String.valueOf(options.getModel())); + if (options.getEncoding() != null && options.getEncoding().isPresent()) { + urlBuilder.addQueryParameter( + "encoding", String.valueOf(options.getEncoding().get())); + } + if (options.getSampleRate() != null && options.getSampleRate().isPresent()) { + urlBuilder.addQueryParameter( + "sample_rate", String.valueOf(options.getSampleRate().get())); + } + if (options.getEagerEotThreshold() != null + && options.getEagerEotThreshold().isPresent()) { + urlBuilder.addQueryParameter( + "eager_eot_threshold", + String.valueOf(options.getEagerEotThreshold().get())); + } + if (options.getEotThreshold() != null && options.getEotThreshold().isPresent()) { + urlBuilder.addQueryParameter( + "eot_threshold", String.valueOf(options.getEotThreshold().get())); + } + if (options.getEotTimeoutMs() != null && options.getEotTimeoutMs().isPresent()) { + urlBuilder.addQueryParameter( + "eot_timeout_ms", String.valueOf(options.getEotTimeoutMs().get())); + } + if (options.getKeyterm() != null && options.getKeyterm().isPresent()) { + QueryStringMapper.addQueryParameter( + urlBuilder, "keyterm", options.getKeyterm().get().get(), true); + } + if (options.getLanguageHint() != null && options.getLanguageHint().isPresent()) { + QueryStringMapper.addQueryParameter( + urlBuilder, "language_hint", options.getLanguageHint().get().get(), true); + } + if (options.getProfanityFilter() != null && options.getProfanityFilter().isPresent()) { + urlBuilder.addQueryParameter( + "profanity_filter", + String.valueOf(options.getProfanityFilter().get())); + } + if (options.getNumerals() != null && options.getNumerals().isPresent()) { + urlBuilder.addQueryParameter( + "numerals", String.valueOf(options.getNumerals().get())); + } + if (options.getRedact() != null && options.getRedact().isPresent()) { + urlBuilder.addQueryParameter( + "redact", String.valueOf(options.getRedact().get())); + } + if (options.getMipOptOut() != null && options.getMipOptOut().isPresent()) { + urlBuilder.addQueryParameter( + "mip_opt_out", String.valueOf(options.getMipOptOut().get())); + } + if (options.getTag() != null && options.getTag().isPresent()) { + QueryStringMapper.addQueryParameter(urlBuilder, "tag", options.getTag().get().get(), true); + } + if (options.getAdditionalProperties() != null) { + options.getAdditionalProperties().forEach((key, value) -> { + if (value != null) { + QueryStringMapper.addQueryParameter(urlBuilder, key, value, true); + } + }); + } + Request.Builder requestBuilder = new Request.Builder().url(urlBuilder.build()); + clientOptions.headers((RequestOptions) null).forEach(requestBuilder::addHeader); + final Request request = requestBuilder.build(); + this.readyState = WebSocketReadyState.CONNECTING; + ReconnectingWebSocketListener.ReconnectOptions reconnectOpts = this.reconnectOptions != null + ? this.reconnectOptions + : ReconnectingWebSocketListener.ReconnectOptions.builder().build(); + this.reconnectingListener = + new ReconnectingWebSocketListener( + reconnectOpts, + () -> { + if (clientOptions.isClosed()) { + throw new IllegalStateException("root client has been closed"); + } + if (clientOptions.webSocketFactory().isPresent()) { + return clientOptions + .webSocketFactory() + .get() + .create(request, this.reconnectingListener); + } else { + return okHttpClient.newWebSocket(request, this.reconnectingListener); + } + }, + clientOptions::isClosed) { + @Override + protected void onWebSocketOpen(WebSocket webSocket, Response response) { + closeStreamSocket.set(null); + readyState = WebSocketReadyState.OPEN; + if (onConnectedHandler != null) { + onConnectedHandler.run(); + } + connectionFuture.complete(null); + } + + @Override + protected void onWebSocketMessage(WebSocket webSocket, String text) { + handleIncomingMessage(text); + } + + @Override + protected void onWebSocketBinaryMessage(WebSocket webSocket, ByteString bytes) {} + + @Override + protected void onWebSocketFailure(WebSocket webSocket, Throwable t, Response response) { + readyState = WebSocketReadyState.CLOSED; + if (onErrorHandler != null) { + onErrorHandler.accept(new RuntimeException(t)); + } + connectionFuture.completeExceptionally(t); + } + + @Override + protected void onWebSocketClosed(WebSocket webSocket, int code, String reason) { + readyState = WebSocketReadyState.CLOSED; + if (onDisconnectedHandler != null) { + onDisconnectedHandler.accept(new DisconnectReason(code, reason)); + } + } + + @Override + protected boolean shouldReconnectAfterClose(WebSocket webSocket, int code, String reason) { + return super.shouldReconnectAfterClose(webSocket, code, reason) + && (code != 1005 || closeStreamSocket.get() != webSocket); + } + }; + clientOptions.registerWebSocket(this); + reconnectingListener.connect(); + return connectionFuture; + } + + /** + * Disconnects the WebSocket connection and releases resources. + */ + public void disconnect() { + clientOptions.unregisterWebSocket(this); + if (reconnectingListener != null) { + reconnectingListener.disconnect(); + } + if (timeoutExecutor != null) { + timeoutExecutor.shutdownNow(); + timeoutExecutor = null; + } + } + + /** + * Gets the current state of the WebSocket connection. + * + * This provides the actual connection state, similar to the W3C WebSocket API. + * + * @return the current WebSocket ready state + */ + public WebSocketReadyState getReadyState() { + return readyState; + } + + /** + * Sends a ListenV2Media message to the server asynchronously. + * @param message the message to send + * @return a CompletableFuture that completes when the message is sent + */ + public CompletableFuture sendMedia(ByteString message) { + CompletableFuture future = new CompletableFuture<>(); + try { + assertSocketIsOpen(); + // Use reconnecting listener's sendBinary method which handles queuing + reconnectingListener.sendBinary(message); + future.complete(null); + } catch (Exception e) { + future.completeExceptionally(new RuntimeException("Failed to send binary data", e)); + } + return future; + } + + /** + * Sends a ListenV2CloseStream message to the server asynchronously. A queued CloseStream does + * not suppress reconnects because it might never reach the server. + * @param message the message to send + * @return a CompletableFuture that completes when the message is sent + */ + public CompletableFuture sendCloseStream(ListenV2CloseStream message) { + return sendMessage(message, closeStreamSocket::set); + } + + /** + * Sends a ListenV2ForceEndTurn message to the server asynchronously. + * @param message the message to send + * @return a CompletableFuture that completes when the message is sent + */ + public CompletableFuture sendForceEndTurn(ListenV2ForceEndTurn message) { + return sendMessage(message); + } + + /** + * Sends a ListenV2Configure message to the server asynchronously. + * @param message the message to send + * @return a CompletableFuture that completes when the message is sent + */ + public CompletableFuture sendConfigure(ListenV2Configure message) { + return sendMessage(message); + } + + /** + * Registers a handler for ListenV2Connected messages from the server. + * @param handler the handler to invoke when a message is received + */ + public void onConnected(Consumer handler) { + this.connectedHandler = handler; + } + + /** + * Registers a handler for ListenV2TurnInfo messages from the server. + * @param handler the handler to invoke when a message is received + */ + public void onTurnInfo(Consumer handler) { + this.turnInfoHandler = handler; + } + + /** + * Registers a handler for ListenV2ConfigureSuccess messages from the server. + * @param handler the handler to invoke when a message is received + */ + public void onConfigureSuccess(Consumer handler) { + this.configureSuccessHandler = handler; + } + + /** + * Registers a handler for ListenV2ConfigureFailure messages from the server. + * @param handler the handler to invoke when a message is received + */ + public void onConfigureFailure(Consumer handler) { + this.configureFailureHandler = handler; + } + + /** + * Registers a handler for ListenV2Warning messages from the server. + * @param handler the handler to invoke when a message is received + */ + public void onWarning(Consumer handler) { + this.warningHandler = handler; + } + + /** + * Registers a handler for ListenV2FatalError messages from the server. + * @param handler the handler to invoke when a message is received + */ + public void onErrorMessage(Consumer handler) { + this.errorHandler = handler; + } + + /** + * Registers a handler called when the connection is established. + * @param handler the handler to invoke when connected + */ + public void onConnected(Runnable handler) { + this.onConnectedHandler = handler; + } + + /** + * Registers a handler called when the connection is closed. + * @param handler the handler to invoke when disconnected + */ + public void onDisconnected(Consumer handler) { + this.onDisconnectedHandler = handler; + } + + /** + * Registers a handler called when an error occurs. + * @param handler the handler to invoke on error + */ + public void onError(Consumer handler) { + this.onErrorHandler = handler; + } + + /** + * Registers a handler called for every incoming text message. + * The handler receives the raw JSON string before type-specific dispatch. + * @param handler the handler to invoke with the raw message JSON + */ + public void onMessage(Consumer handler) { + this.onMessageHandler = handler; + } + + /** + * Configures reconnection behavior. Must be called before {@link #connect}. + * + * @param options the reconnection options (backoff, retries, queue size) + */ + public void reconnectOptions(ReconnectingWebSocketListener.ReconnectOptions options) { + this.reconnectOptions = options; + } + + /** + * Closes this WebSocket client, releasing all resources. + * Equivalent to calling {@link #disconnect()}. + */ + @Override + public void close() { + disconnect(); + } + + /** + * Ensures the WebSocket is connected and ready to send messages. + * @throws IllegalStateException if the socket is not connected or not open + */ + private void assertSocketIsOpen() { + if (reconnectingListener.getWebSocket() == null) { + throw new IllegalStateException("WebSocket is not connected. Call connect() first."); + } + if (readyState != WebSocketReadyState.OPEN) { + throw new IllegalStateException("WebSocket is not open. Current state: " + readyState); + } + } + + private CompletableFuture sendMessage(Object body) { + return sendMessage(body, null); + } + + private CompletableFuture sendMessage(Object body, Consumer onSent) { + CompletableFuture future = new CompletableFuture<>(); + try { + assertSocketIsOpen(); + String json = objectMapper.writeValueAsString(body); + // Use reconnecting listener's send method which handles queuing + reconnectingListener.send(json, onSent); + future.complete(null); + } catch (IllegalStateException e) { + future.completeExceptionally(e); + } catch (Exception e) { + future.completeExceptionally(new RuntimeException("Failed to send message", e)); + } + return future; + } + + private void handleIncomingMessage(String json) { + try { + if (onMessageHandler != null) { + onMessageHandler.accept(json); + } + JsonNode node = objectMapper.readTree(json); + if (node == null || node.isNull()) { + throw new IllegalArgumentException("Received null or invalid JSON message"); + } + if (node.has("request_id") + && node.has("sequence_id") + && node.has("event") + && node.has("turn_index") + && node.has("audio_window_start") + && node.has("audio_window_end") + && node.has("transcript") + && node.has("words") + && node.has("end_of_turn_confidence") + && "TurnInfo".equals(node.path("type").asText())) { + ListenV2TurnInfo turnInfoHandlerEvent = null; + try { + turnInfoHandlerEvent = objectMapper.treeToValue(node, ListenV2TurnInfo.class); + } catch (Exception e) { + } + if (turnInfoHandlerEvent != null) { + if (turnInfoHandler != null) { + turnInfoHandler.accept(turnInfoHandlerEvent); + } + return; + } + } + if (node.has("request_id") + && node.has("thresholds") + && node.has("keyterms") + && node.has("sequence_id") + && "ConfigureSuccess".equals(node.path("type").asText())) { + ListenV2ConfigureSuccess configureSuccessHandlerEvent = null; + try { + configureSuccessHandlerEvent = objectMapper.treeToValue(node, ListenV2ConfigureSuccess.class); + } catch (Exception e) { + } + if (configureSuccessHandlerEvent != null) { + if (configureSuccessHandler != null) { + configureSuccessHandler.accept(configureSuccessHandlerEvent); + } + return; + } + } + if (node.has("request_id") + && node.has("sequence_id") + && node.has("code") + && node.has("description") + && "Warning".equals(node.path("type").asText())) { + ListenV2Warning warningHandlerEvent = null; + try { + warningHandlerEvent = objectMapper.treeToValue(node, ListenV2Warning.class); + } catch (Exception e) { + } + if (warningHandlerEvent != null) { + if (warningHandler != null) { + warningHandler.accept(warningHandlerEvent); + } + return; + } + } + if (node.has("sequence_id") + && node.has("code") + && node.has("description") + && "Error".equals(node.path("type").asText())) { + ListenV2FatalError errorHandlerEvent = null; + try { + errorHandlerEvent = objectMapper.treeToValue(node, ListenV2FatalError.class); + } catch (Exception e) { + } + if (errorHandlerEvent != null) { + if (errorHandler != null) { + errorHandler.accept(errorHandlerEvent); + } + return; + } + } + if (node.has("request_id") + && node.has("sequence_id") + && "Connected".equals(node.path("type").asText())) { + ListenV2Connected connectedHandlerEvent = null; + try { + connectedHandlerEvent = objectMapper.treeToValue(node, ListenV2Connected.class); + } catch (Exception e) { + } + if (connectedHandlerEvent != null) { + if (connectedHandler != null) { + connectedHandler.accept(connectedHandlerEvent); + } + return; + } + } + if (node.has("request_id") + && node.has("sequence_id") + && "ConfigureFailure".equals(node.path("type").asText())) { + ListenV2ConfigureFailure configureFailureHandlerEvent = null; + try { + configureFailureHandlerEvent = objectMapper.treeToValue(node, ListenV2ConfigureFailure.class); + } catch (Exception e) { + } + if (configureFailureHandlerEvent != null) { + if (configureFailureHandler != null) { + configureFailureHandler.accept(configureFailureHandlerEvent); + } + return; + } + } + // The raw frame is already delivered to onMessage(String), so ignore unknown typed + // frames for forward compatibility with newly added server control messages. + } catch (Exception e) { + if (onErrorHandler != null) { + onErrorHandler.accept(e); + } + } + } +} diff --git a/src/main/java/com/deepgram/resources/speak/v1/websocket/V1WebSocketClient.java.bak b/src/main/java/com/deepgram/resources/speak/v1/websocket/V1WebSocketClient.java.bak new file mode 100644 index 0000000..e6824a3 --- /dev/null +++ b/src/main/java/com/deepgram/resources/speak/v1/websocket/V1WebSocketClient.java.bak @@ -0,0 +1,467 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.resources.speak.v1.websocket; + +import com.deepgram.core.ClientOptions; +import com.deepgram.core.DisconnectReason; +import com.deepgram.core.ObjectMappers; +import com.deepgram.core.QueryStringMapper; +import com.deepgram.core.ReconnectingWebSocketListener; +import com.deepgram.core.RequestOptions; +import com.deepgram.core.WebSocketReadyState; +import com.deepgram.resources.speak.v1.types.SpeakV1Clear; +import com.deepgram.resources.speak.v1.types.SpeakV1Cleared; +import com.deepgram.resources.speak.v1.types.SpeakV1Close; +import com.deepgram.resources.speak.v1.types.SpeakV1Flush; +import com.deepgram.resources.speak.v1.types.SpeakV1Flushed; +import com.deepgram.resources.speak.v1.types.SpeakV1Metadata; +import com.deepgram.resources.speak.v1.types.SpeakV1Text; +import com.deepgram.resources.speak.v1.types.SpeakV1Warning; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ScheduledExecutorService; +import java.util.function.Consumer; +import okhttp3.HttpUrl; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.WebSocket; +import okio.ByteString; + +/** + * WebSocket client for the v1 channel. + * Provides real-time bidirectional communication with strongly-typed messages. + */ +public class V1WebSocketClient implements AutoCloseable { + protected final ClientOptions clientOptions; + + private final ObjectMapper objectMapper; + + private final OkHttpClient okHttpClient; + + private ScheduledExecutorService timeoutExecutor; + + private volatile WebSocketReadyState readyState = WebSocketReadyState.CLOSED; + + private volatile Runnable onConnectedHandler; + + private volatile Consumer onDisconnectedHandler; + + private volatile Consumer onErrorHandler; + + private volatile Consumer onMessageHandler; + + private volatile ReconnectingWebSocketListener.ReconnectOptions reconnectOptions; + + private CompletableFuture connectionFuture; + + private ReconnectingWebSocketListener reconnectingListener; + + private volatile Consumer speakV1AudioHandler; + + private volatile Consumer metadataHandler; + + private volatile Consumer flushedHandler; + + private volatile Consumer clearedHandler; + + private volatile Consumer warningHandler; + + /** + * Creates a new async WebSocket client for the v1 channel. + */ + public V1WebSocketClient(ClientOptions clientOptions) { + this.clientOptions = clientOptions; + this.objectMapper = ObjectMappers.JSON_MAPPER; + this.okHttpClient = clientOptions.httpClient(); + } + + /** + * Establishes the WebSocket connection asynchronously with automatic reconnection. + * @return a CompletableFuture that completes when the connection is established + * @param options connection options including query parameters + */ + public CompletableFuture connect(V1ConnectOptions options) { + connectionFuture = new CompletableFuture<>(); + String baseUrl = clientOptions.environment().getProductionURL(); + String fullPath = "/v1/speak"; + if (baseUrl.endsWith("/") && fullPath.startsWith("/")) { + fullPath = fullPath.substring(1); + } else if (!baseUrl.endsWith("/") && !fullPath.startsWith("/")) { + fullPath = "/" + fullPath; + } + // OkHttp's HttpUrl only supports http/https schemes; convert wss/ws for URL parsing + if (baseUrl.startsWith("wss://")) { + baseUrl = "https://" + baseUrl.substring(6); + } else if (baseUrl.startsWith("ws://")) { + baseUrl = "http://" + baseUrl.substring(5); + } + HttpUrl parsedUrl = HttpUrl.parse(baseUrl + fullPath); + if (parsedUrl == null) { + throw new IllegalArgumentException("Invalid WebSocket URL: " + baseUrl + fullPath); + } + HttpUrl.Builder urlBuilder = parsedUrl.newBuilder(); + if (options.getEncoding() != null && options.getEncoding().isPresent()) { + urlBuilder.addQueryParameter( + "encoding", String.valueOf(options.getEncoding().get())); + } + if (options.getMipOptOut() != null && options.getMipOptOut().isPresent()) { + urlBuilder.addQueryParameter( + "mip_opt_out", String.valueOf(options.getMipOptOut().get())); + } + if (options.getModel() != null && options.getModel().isPresent()) { + urlBuilder.addQueryParameter( + "model", String.valueOf(options.getModel().get())); + } + if (options.getSampleRate() != null && options.getSampleRate().isPresent()) { + urlBuilder.addQueryParameter( + "sample_rate", String.valueOf(options.getSampleRate().get())); + } + if (options.getSpeed() != null && options.getSpeed().isPresent()) { + urlBuilder.addQueryParameter( + "speed", String.valueOf(options.getSpeed().get())); + } + if (options.getAdditionalProperties() != null) { + options.getAdditionalProperties().forEach((key, value) -> { + if (value != null) { + QueryStringMapper.addQueryParameter(urlBuilder, key, value, true); + } + }); + } + Request.Builder requestBuilder = new Request.Builder().url(urlBuilder.build()); + clientOptions.headers((RequestOptions) null).forEach(requestBuilder::addHeader); + final Request request = requestBuilder.build(); + this.readyState = WebSocketReadyState.CONNECTING; + ReconnectingWebSocketListener.ReconnectOptions reconnectOpts = this.reconnectOptions != null + ? this.reconnectOptions + : ReconnectingWebSocketListener.ReconnectOptions.builder().build(); + this.reconnectingListener = + new ReconnectingWebSocketListener( + reconnectOpts, + () -> { + if (clientOptions.isClosed()) { + throw new IllegalStateException("root client has been closed"); + } + if (clientOptions.webSocketFactory().isPresent()) { + return clientOptions + .webSocketFactory() + .get() + .create(request, this.reconnectingListener); + } else { + return okHttpClient.newWebSocket(request, this.reconnectingListener); + } + }, + clientOptions::isClosed) { + @Override + protected void onWebSocketOpen(WebSocket webSocket, Response response) { + readyState = WebSocketReadyState.OPEN; + if (onConnectedHandler != null) { + onConnectedHandler.run(); + } + connectionFuture.complete(null); + } + + @Override + protected void onWebSocketMessage(WebSocket webSocket, String text) { + handleIncomingMessage(text); + } + + @Override + protected void onWebSocketBinaryMessage(WebSocket webSocket, ByteString bytes) { + if (speakV1AudioHandler != null) { + speakV1AudioHandler.accept(bytes); + } + } + + @Override + protected void onWebSocketFailure(WebSocket webSocket, Throwable t, Response response) { + readyState = WebSocketReadyState.CLOSED; + if (onErrorHandler != null) { + onErrorHandler.accept(new RuntimeException(t)); + } + connectionFuture.completeExceptionally(t); + } + + @Override + protected void onWebSocketClosed(WebSocket webSocket, int code, String reason) { + readyState = WebSocketReadyState.CLOSED; + if (onDisconnectedHandler != null) { + onDisconnectedHandler.accept(new DisconnectReason(code, reason)); + } + } + }; + clientOptions.registerWebSocket(this); + reconnectingListener.connect(); + return connectionFuture; + } + + /** + * Establishes the WebSocket connection asynchronously with default options. + * @return a CompletableFuture that completes when the connection is established + */ + public CompletableFuture connect() { + return connect(V1ConnectOptions.builder().build()); + } + + /** + * Disconnects the WebSocket connection and releases resources. + */ + public void disconnect() { + clientOptions.unregisterWebSocket(this); + if (reconnectingListener != null) { + reconnectingListener.disconnect(); + } + if (timeoutExecutor != null) { + timeoutExecutor.shutdownNow(); + timeoutExecutor = null; + } + } + + /** + * Gets the current state of the WebSocket connection. + * + * This provides the actual connection state, similar to the W3C WebSocket API. + * + * @return the current WebSocket ready state + */ + public WebSocketReadyState getReadyState() { + return readyState; + } + + /** + * Sends a SpeakV1Text message to the server asynchronously. + * @param message the message to send + * @return a CompletableFuture that completes when the message is sent + */ + public CompletableFuture sendText(SpeakV1Text message) { + return sendMessage(message); + } + + /** + * Sends a SpeakV1Flush message to the server asynchronously. + * @param message the message to send + * @return a CompletableFuture that completes when the message is sent + */ + public CompletableFuture sendFlush(SpeakV1Flush message) { + return sendMessage(message); + } + + /** + * Sends a SpeakV1Clear message to the server asynchronously. + * @param message the message to send + * @return a CompletableFuture that completes when the message is sent + */ + public CompletableFuture sendClear(SpeakV1Clear message) { + return sendMessage(message); + } + + /** + * Sends a SpeakV1Close message to the server asynchronously. + * @param message the message to send + * @return a CompletableFuture that completes when the message is sent + */ + public CompletableFuture sendClose(SpeakV1Close message) { + return sendMessage(message); + } + + /** + * Registers a handler for SpeakV1Audio messages from the server. + * @param handler the handler to invoke when a message is received + */ + public void onSpeakV1Audio(Consumer handler) { + this.speakV1AudioHandler = handler; + } + + /** + * Registers a handler for SpeakV1Metadata messages from the server. + * @param handler the handler to invoke when a message is received + */ + public void onMetadata(Consumer handler) { + this.metadataHandler = handler; + } + + /** + * Registers a handler for SpeakV1Flushed messages from the server. + * @param handler the handler to invoke when a message is received + */ + public void onFlushed(Consumer handler) { + this.flushedHandler = handler; + } + + /** + * Registers a handler for SpeakV1Cleared messages from the server. + * @param handler the handler to invoke when a message is received + */ + public void onCleared(Consumer handler) { + this.clearedHandler = handler; + } + + /** + * Registers a handler for SpeakV1Warning messages from the server. + * @param handler the handler to invoke when a message is received + */ + public void onWarning(Consumer handler) { + this.warningHandler = handler; + } + + /** + * Registers a handler called when the connection is established. + * @param handler the handler to invoke when connected + */ + public void onConnected(Runnable handler) { + this.onConnectedHandler = handler; + } + + /** + * Registers a handler called when the connection is closed. + * @param handler the handler to invoke when disconnected + */ + public void onDisconnected(Consumer handler) { + this.onDisconnectedHandler = handler; + } + + /** + * Registers a handler called when an error occurs. + * @param handler the handler to invoke on error + */ + public void onError(Consumer handler) { + this.onErrorHandler = handler; + } + + /** + * Registers a handler called for every incoming text message. + * The handler receives the raw JSON string before type-specific dispatch. + * @param handler the handler to invoke with the raw message JSON + */ + public void onMessage(Consumer handler) { + this.onMessageHandler = handler; + } + + /** + * Configures reconnection behavior. Must be called before {@link #connect}. + * + * @param options the reconnection options (backoff, retries, queue size) + */ + public void reconnectOptions(ReconnectingWebSocketListener.ReconnectOptions options) { + this.reconnectOptions = options; + } + + /** + * Closes this WebSocket client, releasing all resources. + * Equivalent to calling {@link #disconnect()}. + */ + @Override + public void close() { + disconnect(); + } + + /** + * Ensures the WebSocket is connected and ready to send messages. + * @throws IllegalStateException if the socket is not connected or not open + */ + private void assertSocketIsOpen() { + if (reconnectingListener.getWebSocket() == null) { + throw new IllegalStateException("WebSocket is not connected. Call connect() first."); + } + if (readyState != WebSocketReadyState.OPEN) { + throw new IllegalStateException("WebSocket is not open. Current state: " + readyState); + } + } + + private CompletableFuture sendMessage(Object body) { + CompletableFuture future = new CompletableFuture<>(); + try { + assertSocketIsOpen(); + String json = objectMapper.writeValueAsString(body); + // Use reconnecting listener's send method which handles queuing + reconnectingListener.send(json); + future.complete(null); + } catch (IllegalStateException e) { + future.completeExceptionally(e); + } catch (Exception e) { + future.completeExceptionally(new RuntimeException("Failed to send message", e)); + } + return future; + } + + private void handleIncomingMessage(String json) { + try { + if (onMessageHandler != null) { + onMessageHandler.accept(json); + } + JsonNode node = objectMapper.readTree(json); + if (node == null || node.isNull()) { + throw new IllegalArgumentException("Received null or invalid JSON message"); + } + if (node.has("request_id") + && node.has("model_name") + && node.has("model_version") + && node.has("model_uuid") + && "Metadata".equals(node.path("type").asText())) { + SpeakV1Metadata metadataHandlerEvent = null; + try { + metadataHandlerEvent = objectMapper.treeToValue(node, SpeakV1Metadata.class); + } catch (Exception e) { + } + if (metadataHandlerEvent != null) { + if (metadataHandler != null) { + metadataHandler.accept(metadataHandlerEvent); + } + return; + } + } + if (node.has("description") + && node.has("code") + && "Warning".equals(node.path("type").asText())) { + SpeakV1Warning warningHandlerEvent = null; + try { + warningHandlerEvent = objectMapper.treeToValue(node, SpeakV1Warning.class); + } catch (Exception e) { + } + if (warningHandlerEvent != null) { + if (warningHandler != null) { + warningHandler.accept(warningHandlerEvent); + } + return; + } + } + if (node.has("type") && node.has("sequence_id")) { + SpeakV1Flushed flushedHandlerEvent = null; + try { + flushedHandlerEvent = objectMapper.treeToValue(node, SpeakV1Flushed.class); + } catch (Exception e) { + } + if (flushedHandlerEvent != null) { + if (flushedHandler != null) { + flushedHandler.accept(flushedHandlerEvent); + } + return; + } + } + if (node.has("type") && node.has("sequence_id")) { + SpeakV1Cleared clearedHandlerEvent = null; + try { + clearedHandlerEvent = objectMapper.treeToValue(node, SpeakV1Cleared.class); + } catch (Exception e) { + } + if (clearedHandlerEvent != null) { + if (clearedHandler != null) { + clearedHandler.accept(clearedHandlerEvent); + } + return; + } + } + if (onErrorHandler != null) { + onErrorHandler.accept(new RuntimeException( + "Unrecognized WebSocket message: " + json.substring(0, Math.min(200, json.length())) + + "... Update your SDK version to support new message types.")); + } + } catch (Exception e) { + if (onErrorHandler != null) { + onErrorHandler.accept(e); + } + } + } +} diff --git a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Close.java.bak b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Close.java.bak new file mode 100644 index 0000000..7fecd79 --- /dev/null +++ b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Close.java.bak @@ -0,0 +1,83 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.resources.speak.v2.types; + +import com.deepgram.core.ObjectMappers; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.util.HashMap; +import java.util.Map; + +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonDeserialize(builder = SpeakV2Close.Builder.class) +public final class SpeakV2Close { + private final Map additionalProperties; + + private SpeakV2Close(Map additionalProperties) { + this.additionalProperties = additionalProperties; + } + + /** + * @return Message type identifier + */ + @JsonProperty("type") + public String getType() { + return "Close"; + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof SpeakV2Close; + } + + @java.lang.Override + public int hashCode() { + return getClass().hashCode(); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + @java.lang.Override + public String toString() { + return ObjectMappers.stringify(this); + } + + public static Builder builder() { + return new Builder(); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static final class Builder { + @JsonAnySetter + private Map additionalProperties = new HashMap<>(); + + private Builder() {} + + public Builder from(SpeakV2Close other) { + return this; + } + + public SpeakV2Close build() { + return new SpeakV2Close(additionalProperties); + } + + public Builder additionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + return this; + } + + public Builder additionalProperties(Map additionalProperties) { + this.additionalProperties.putAll(additionalProperties); + return this; + } + } +} diff --git a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Flush.java.bak b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Flush.java.bak new file mode 100644 index 0000000..130da0d --- /dev/null +++ b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Flush.java.bak @@ -0,0 +1,83 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.resources.speak.v2.types; + +import com.deepgram.core.ObjectMappers; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.util.HashMap; +import java.util.Map; + +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonDeserialize(builder = SpeakV2Flush.Builder.class) +public final class SpeakV2Flush { + private final Map additionalProperties; + + private SpeakV2Flush(Map additionalProperties) { + this.additionalProperties = additionalProperties; + } + + /** + * @return Message type identifier + */ + @JsonProperty("type") + public String getType() { + return "Flush"; + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof SpeakV2Flush; + } + + @java.lang.Override + public int hashCode() { + return getClass().hashCode(); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + @java.lang.Override + public String toString() { + return ObjectMappers.stringify(this); + } + + public static Builder builder() { + return new Builder(); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static final class Builder { + @JsonAnySetter + private Map additionalProperties = new HashMap<>(); + + private Builder() {} + + public Builder from(SpeakV2Flush other) { + return this; + } + + public SpeakV2Flush build() { + return new SpeakV2Flush(additionalProperties); + } + + public Builder additionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + return this; + } + + public Builder additionalProperties(Map additionalProperties) { + this.additionalProperties.putAll(additionalProperties); + return this; + } + } +} diff --git a/src/main/java/com/deepgram/resources/speak/v2/websocket/V2WebSocketClient.java.bak b/src/main/java/com/deepgram/resources/speak/v2/websocket/V2WebSocketClient.java.bak new file mode 100644 index 0000000..b4e01f7 --- /dev/null +++ b/src/main/java/com/deepgram/resources/speak/v2/websocket/V2WebSocketClient.java.bak @@ -0,0 +1,630 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.resources.speak.v2.websocket; + +import com.deepgram.core.ClientOptions; +import com.deepgram.core.DisconnectReason; +import com.deepgram.core.ObjectMappers; +import com.deepgram.core.QueryStringMapper; +import com.deepgram.core.ReconnectingWebSocketListener; +import com.deepgram.core.RequestOptions; +import com.deepgram.core.WebSocketReadyState; +import com.deepgram.resources.speak.v2.types.SpeakV2Close; +import com.deepgram.resources.speak.v2.types.SpeakV2Configure; +import com.deepgram.resources.speak.v2.types.SpeakV2ConfigureFailure; +import com.deepgram.resources.speak.v2.types.SpeakV2ConfigureSuccess; +import com.deepgram.resources.speak.v2.types.SpeakV2Connected; +import com.deepgram.resources.speak.v2.types.SpeakV2Error; +import com.deepgram.resources.speak.v2.types.SpeakV2Flush; +import com.deepgram.resources.speak.v2.types.SpeakV2Flushed; +import com.deepgram.resources.speak.v2.types.SpeakV2Interrupt; +import com.deepgram.resources.speak.v2.types.SpeakV2SessionMetadata; +import com.deepgram.resources.speak.v2.types.SpeakV2Speak; +import com.deepgram.resources.speak.v2.types.SpeakV2SpeechInterrupted; +import com.deepgram.resources.speak.v2.types.SpeakV2SpeechMetadata; +import com.deepgram.resources.speak.v2.types.SpeakV2SpeechStarted; +import com.deepgram.resources.speak.v2.types.SpeakV2Warning; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ScheduledExecutorService; +import java.util.function.Consumer; +import okhttp3.HttpUrl; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.WebSocket; +import okio.ByteString; + +/** + * WebSocket client for the v2 channel. + * Provides real-time bidirectional communication with strongly-typed messages. + */ +public class V2WebSocketClient implements AutoCloseable { + protected final ClientOptions clientOptions; + + private final ObjectMapper objectMapper; + + private final OkHttpClient okHttpClient; + + private ScheduledExecutorService timeoutExecutor; + + private volatile WebSocketReadyState readyState = WebSocketReadyState.CLOSED; + + private volatile Runnable onConnectedHandler; + + private volatile Consumer onDisconnectedHandler; + + private volatile Consumer onErrorHandler; + + private volatile Consumer onMessageHandler; + + private volatile ReconnectingWebSocketListener.ReconnectOptions reconnectOptions; + + private CompletableFuture connectionFuture; + + private ReconnectingWebSocketListener reconnectingListener; + + private volatile Consumer speakV2AudioHandler; + + private volatile Consumer connectedHandler; + + private volatile Consumer speechStartedHandler; + + private volatile Consumer speechMetadataHandler; + + private volatile Consumer speechInterruptedHandler; + + private volatile Consumer flushedHandler; + + private volatile Consumer sessionMetadataHandler; + + private volatile Consumer configureSuccessHandler; + + private volatile Consumer configureFailureHandler; + + private volatile Consumer warningHandler; + + private volatile Consumer errorHandler; + + /** + * Creates a new async WebSocket client for the v2 channel. + */ + public V2WebSocketClient(ClientOptions clientOptions) { + this.clientOptions = clientOptions; + this.objectMapper = ObjectMappers.JSON_MAPPER; + this.okHttpClient = clientOptions.httpClient(); + } + + /** + * Establishes the WebSocket connection asynchronously with automatic reconnection. + * @return a CompletableFuture that completes when the connection is established + * @param options connection options including query parameters + */ + public CompletableFuture connect(V2ConnectOptions options) { + connectionFuture = new CompletableFuture<>(); + String baseUrl = clientOptions.environment().getProductionURL(); + String fullPath = "/v2/speak"; + if (baseUrl.endsWith("/") && fullPath.startsWith("/")) { + fullPath = fullPath.substring(1); + } else if (!baseUrl.endsWith("/") && !fullPath.startsWith("/")) { + fullPath = "/" + fullPath; + } + // OkHttp's HttpUrl only supports http/https schemes; convert wss/ws for URL parsing + if (baseUrl.startsWith("wss://")) { + baseUrl = "https://" + baseUrl.substring(6); + } else if (baseUrl.startsWith("ws://")) { + baseUrl = "http://" + baseUrl.substring(5); + } + HttpUrl parsedUrl = HttpUrl.parse(baseUrl + fullPath); + if (parsedUrl == null) { + throw new IllegalArgumentException("Invalid WebSocket URL: " + baseUrl + fullPath); + } + HttpUrl.Builder urlBuilder = parsedUrl.newBuilder(); + urlBuilder.addQueryParameter("model", String.valueOf(options.getModel())); + if (options.getEncoding() != null && options.getEncoding().isPresent()) { + urlBuilder.addQueryParameter( + "encoding", String.valueOf(options.getEncoding().get())); + } + if (options.getSampleRate() != null && options.getSampleRate().isPresent()) { + urlBuilder.addQueryParameter( + "sample_rate", String.valueOf(options.getSampleRate().get())); + } + if (options.getSpeed() != null && options.getSpeed().isPresent()) { + urlBuilder.addQueryParameter( + "speed", String.valueOf(options.getSpeed().get())); + } + if (options.getExpressivity() != null && options.getExpressivity().isPresent()) { + urlBuilder.addQueryParameter( + "expressivity", String.valueOf(options.getExpressivity().get())); + } + if (options.getMipOptOut() != null && options.getMipOptOut().isPresent()) { + urlBuilder.addQueryParameter( + "mip_opt_out", String.valueOf(options.getMipOptOut().get())); + } + if (options.getTag() != null && options.getTag().isPresent()) { + QueryStringMapper.addQueryParameter(urlBuilder, "tag", options.getTag().get().get(), true); + } + if (options.getAdditionalProperties() != null) { + options.getAdditionalProperties().forEach((key, value) -> { + if (value != null) { + QueryStringMapper.addQueryParameter(urlBuilder, key, value, true); + } + }); + } + Request.Builder requestBuilder = new Request.Builder().url(urlBuilder.build()); + clientOptions.headers((RequestOptions) null).forEach(requestBuilder::addHeader); + final Request request = requestBuilder.build(); + this.readyState = WebSocketReadyState.CONNECTING; + ReconnectingWebSocketListener.ReconnectOptions reconnectOpts = this.reconnectOptions != null + ? this.reconnectOptions + : ReconnectingWebSocketListener.ReconnectOptions.builder().build(); + this.reconnectingListener = + new ReconnectingWebSocketListener( + reconnectOpts, + () -> { + if (clientOptions.isClosed()) { + throw new IllegalStateException("root client has been closed"); + } + if (clientOptions.webSocketFactory().isPresent()) { + return clientOptions + .webSocketFactory() + .get() + .create(request, this.reconnectingListener); + } else { + return okHttpClient.newWebSocket(request, this.reconnectingListener); + } + }, + clientOptions::isClosed) { + @Override + protected void onWebSocketOpen(WebSocket webSocket, Response response) { + readyState = WebSocketReadyState.OPEN; + if (onConnectedHandler != null) { + onConnectedHandler.run(); + } + connectionFuture.complete(null); + } + + @Override + protected void onWebSocketMessage(WebSocket webSocket, String text) { + handleIncomingMessage(text); + } + + @Override + protected void onWebSocketBinaryMessage(WebSocket webSocket, ByteString bytes) { + if (speakV2AudioHandler != null) { + speakV2AudioHandler.accept(bytes); + } + } + + @Override + protected void onWebSocketFailure(WebSocket webSocket, Throwable t, Response response) { + readyState = WebSocketReadyState.CLOSED; + if (onErrorHandler != null) { + onErrorHandler.accept(new RuntimeException(t)); + } + connectionFuture.completeExceptionally(t); + } + + @Override + protected void onWebSocketClosed(WebSocket webSocket, int code, String reason) { + readyState = WebSocketReadyState.CLOSED; + if (onDisconnectedHandler != null) { + onDisconnectedHandler.accept(new DisconnectReason(code, reason)); + } + } + }; + clientOptions.registerWebSocket(this); + reconnectingListener.connect(); + return connectionFuture; + } + + /** + * Disconnects the WebSocket connection and releases resources. + */ + public void disconnect() { + clientOptions.unregisterWebSocket(this); + if (reconnectingListener != null) { + reconnectingListener.disconnect(); + } + if (timeoutExecutor != null) { + timeoutExecutor.shutdownNow(); + timeoutExecutor = null; + } + } + + /** + * Gets the current state of the WebSocket connection. + * + * This provides the actual connection state, similar to the W3C WebSocket API. + * + * @return the current WebSocket ready state + */ + public WebSocketReadyState getReadyState() { + return readyState; + } + + /** + * Sends a SpeakV2Speak message to the server asynchronously. + * @param message the message to send + * @return a CompletableFuture that completes when the message is sent + */ + public CompletableFuture sendSpeak(SpeakV2Speak message) { + return sendMessage(message); + } + + /** + * Sends a SpeakV2Flush message to the server asynchronously. + * @param message the message to send + * @return a CompletableFuture that completes when the message is sent + */ + public CompletableFuture sendFlush(SpeakV2Flush message) { + return sendMessage(message); + } + + /** + * Sends a SpeakV2Interrupt message to the server asynchronously. + * @param message the message to send + * @return a CompletableFuture that completes when the message is sent + */ + public CompletableFuture sendInterrupt(SpeakV2Interrupt message) { + return sendMessage(message); + } + + /** + * Sends a SpeakV2Configure message to the server asynchronously. + * @param message the message to send + * @return a CompletableFuture that completes when the message is sent + */ + public CompletableFuture sendConfigure(SpeakV2Configure message) { + return sendMessage(message); + } + + /** + * Sends a SpeakV2Close message to the server asynchronously. + * @param message the message to send + * @return a CompletableFuture that completes when the message is sent + */ + public CompletableFuture sendClose(SpeakV2Close message) { + return sendMessage(message); + } + + /** + * Registers a handler for SpeakV2Audio messages from the server. + * @param handler the handler to invoke when a message is received + */ + public void onSpeakV2Audio(Consumer handler) { + this.speakV2AudioHandler = handler; + } + + /** + * Registers a handler for SpeakV2Connected messages from the server. + * @param handler the handler to invoke when a message is received + */ + public void onConnected(Consumer handler) { + this.connectedHandler = handler; + } + + /** + * Registers a handler for SpeakV2SpeechStarted messages from the server. + * @param handler the handler to invoke when a message is received + */ + public void onSpeechStarted(Consumer handler) { + this.speechStartedHandler = handler; + } + + /** + * Registers a handler for SpeakV2SpeechMetadata messages from the server. + * @param handler the handler to invoke when a message is received + */ + public void onSpeechMetadata(Consumer handler) { + this.speechMetadataHandler = handler; + } + + /** + * Registers a handler for SpeakV2SpeechInterrupted messages from the server. + * @param handler the handler to invoke when a message is received + */ + public void onSpeechInterrupted(Consumer handler) { + this.speechInterruptedHandler = handler; + } + + /** + * Registers a handler for SpeakV2Flushed messages from the server. + * @param handler the handler to invoke when a message is received + */ + public void onFlushed(Consumer handler) { + this.flushedHandler = handler; + } + + /** + * Registers a handler for SpeakV2SessionMetadata messages from the server. + * @param handler the handler to invoke when a message is received + */ + public void onSessionMetadata(Consumer handler) { + this.sessionMetadataHandler = handler; + } + + /** + * Registers a handler for SpeakV2ConfigureSuccess messages from the server. + * @param handler the handler to invoke when a message is received + */ + public void onConfigureSuccess(Consumer handler) { + this.configureSuccessHandler = handler; + } + + /** + * Registers a handler for SpeakV2ConfigureFailure messages from the server. + * @param handler the handler to invoke when a message is received + */ + public void onConfigureFailure(Consumer handler) { + this.configureFailureHandler = handler; + } + + /** + * Registers a handler for SpeakV2Warning messages from the server. + * @param handler the handler to invoke when a message is received + */ + public void onWarning(Consumer handler) { + this.warningHandler = handler; + } + + /** + * Registers a handler for SpeakV2Error messages from the server. + * @param handler the handler to invoke when a message is received + */ + public void onErrorMessage(Consumer handler) { + this.errorHandler = handler; + } + + /** + * Registers a handler called when the connection is established. + * @param handler the handler to invoke when connected + */ + public void onConnected(Runnable handler) { + this.onConnectedHandler = handler; + } + + /** + * Registers a handler called when the connection is closed. + * @param handler the handler to invoke when disconnected + */ + public void onDisconnected(Consumer handler) { + this.onDisconnectedHandler = handler; + } + + /** + * Registers a handler called when an error occurs. + * @param handler the handler to invoke on error + */ + public void onError(Consumer handler) { + this.onErrorHandler = handler; + } + + /** + * Registers a handler called for every incoming text message. + * The handler receives the raw JSON string before type-specific dispatch. + * @param handler the handler to invoke with the raw message JSON + */ + public void onMessage(Consumer handler) { + this.onMessageHandler = handler; + } + + /** + * Configures reconnection behavior. Must be called before {@link #connect}. + * + * @param options the reconnection options (backoff, retries, queue size) + */ + public void reconnectOptions(ReconnectingWebSocketListener.ReconnectOptions options) { + this.reconnectOptions = options; + } + + /** + * Closes this WebSocket client, releasing all resources. + * Equivalent to calling {@link #disconnect()}. + */ + @Override + public void close() { + disconnect(); + } + + /** + * Ensures the WebSocket is connected and ready to send messages. + * @throws IllegalStateException if the socket is not connected or not open + */ + private void assertSocketIsOpen() { + if (reconnectingListener.getWebSocket() == null) { + throw new IllegalStateException("WebSocket is not connected. Call connect() first."); + } + if (readyState != WebSocketReadyState.OPEN) { + throw new IllegalStateException("WebSocket is not open. Current state: " + readyState); + } + } + + private CompletableFuture sendMessage(Object body) { + CompletableFuture future = new CompletableFuture<>(); + try { + assertSocketIsOpen(); + String json = objectMapper.writeValueAsString(body); + // Use reconnecting listener's send method which handles queuing + reconnectingListener.send(json); + future.complete(null); + } catch (IllegalStateException e) { + future.completeExceptionally(e); + } catch (Exception e) { + future.completeExceptionally(new RuntimeException("Failed to send message", e)); + } + return future; + } + + private void handleIncomingMessage(String json) { + try { + if (onMessageHandler != null) { + onMessageHandler.accept(json); + } + JsonNode node = objectMapper.readTree(json); + if (node == null || node.isNull()) { + throw new IllegalArgumentException("Received null or invalid JSON message"); + } + if (node.has("speech_id") + && node.has("audio_duration_ms") + && node.has("input_character_count") + && node.has("billable_character_count") + && node.has("controls_applied") + && "SpeechMetadata".equals(node.path("type").asText())) { + SpeakV2SpeechMetadata speechMetadataHandlerEvent = null; + try { + speechMetadataHandlerEvent = objectMapper.treeToValue(node, SpeakV2SpeechMetadata.class); + } catch (Exception e) { + } + if (speechMetadataHandlerEvent != null) { + if (speechMetadataHandler != null) { + speechMetadataHandler.accept(speechMetadataHandlerEvent); + } + return; + } + } + if (node.has("request_id") + && node.has("model_name") + && node.has("model_version") + && node.has("model_uuids") + && "Connected".equals(node.path("type").asText())) { + SpeakV2Connected connectedHandlerEvent = null; + try { + connectedHandlerEvent = objectMapper.treeToValue(node, SpeakV2Connected.class); + } catch (Exception e) { + } + if (connectedHandlerEvent != null) { + if (connectedHandler != null) { + connectedHandler.accept(connectedHandlerEvent); + } + return; + } + } + if (node.has("total_audio_duration_ms") + && node.has("total_input_character_count") + && node.has("total_billable_character_count") + && "SessionMetadata".equals(node.path("type").asText())) { + SpeakV2SessionMetadata sessionMetadataHandlerEvent = null; + try { + sessionMetadataHandlerEvent = objectMapper.treeToValue(node, SpeakV2SessionMetadata.class); + } catch (Exception e) { + } + if (sessionMetadataHandlerEvent != null) { + if (sessionMetadataHandler != null) { + sessionMetadataHandler.accept(sessionMetadataHandlerEvent); + } + return; + } + } + if (node.has("audio_played_ms") + && node.has("metadata") + && "SpeechInterrupted".equals(node.path("type").asText())) { + SpeakV2SpeechInterrupted speechInterruptedHandlerEvent = null; + try { + speechInterruptedHandlerEvent = objectMapper.treeToValue(node, SpeakV2SpeechInterrupted.class); + } catch (Exception e) { + } + if (speechInterruptedHandlerEvent != null) { + if (speechInterruptedHandler != null) { + speechInterruptedHandler.accept(speechInterruptedHandlerEvent); + } + return; + } + } + if (node.has("code") + && node.has("description") + && "ConfigureFailure".equals(node.path("type").asText())) { + SpeakV2ConfigureFailure configureFailureHandlerEvent = null; + try { + configureFailureHandlerEvent = objectMapper.treeToValue(node, SpeakV2ConfigureFailure.class); + } catch (Exception e) { + } + if (configureFailureHandlerEvent != null) { + if (configureFailureHandler != null) { + configureFailureHandler.accept(configureFailureHandlerEvent); + } + return; + } + } + if (node.has("code") + && node.has("description") + && "Warning".equals(node.path("type").asText())) { + SpeakV2Warning warningHandlerEvent = null; + try { + warningHandlerEvent = objectMapper.treeToValue(node, SpeakV2Warning.class); + } catch (Exception e) { + } + if (warningHandlerEvent != null) { + if (warningHandler != null) { + warningHandler.accept(warningHandlerEvent); + } + return; + } + } + if (node.has("code") + && node.has("description") + && "Error".equals(node.path("type").asText())) { + SpeakV2Error errorHandlerEvent = null; + try { + errorHandlerEvent = objectMapper.treeToValue(node, SpeakV2Error.class); + } catch (Exception e) { + } + if (errorHandlerEvent != null) { + if (errorHandler != null) { + errorHandler.accept(errorHandlerEvent); + } + return; + } + } + if (node.has("speech_id") + && "SpeechStarted".equals(node.path("type").asText())) { + SpeakV2SpeechStarted speechStartedHandlerEvent = null; + try { + speechStartedHandlerEvent = objectMapper.treeToValue(node, SpeakV2SpeechStarted.class); + } catch (Exception e) { + } + if (speechStartedHandlerEvent != null) { + if (speechStartedHandler != null) { + speechStartedHandler.accept(speechStartedHandlerEvent); + } + return; + } + } + if (node.has("speech_id") && "Flushed".equals(node.path("type").asText())) { + SpeakV2Flushed flushedHandlerEvent = null; + try { + flushedHandlerEvent = objectMapper.treeToValue(node, SpeakV2Flushed.class); + } catch (Exception e) { + } + if (flushedHandlerEvent != null) { + if (flushedHandler != null) { + flushedHandler.accept(flushedHandlerEvent); + } + return; + } + } + if (node.has("applied") + && "ConfigureSuccess".equals(node.path("type").asText())) { + SpeakV2ConfigureSuccess configureSuccessHandlerEvent = null; + try { + configureSuccessHandlerEvent = objectMapper.treeToValue(node, SpeakV2ConfigureSuccess.class); + } catch (Exception e) { + } + if (configureSuccessHandlerEvent != null) { + if (configureSuccessHandler != null) { + configureSuccessHandler.accept(configureSuccessHandlerEvent); + } + return; + } + } + // The raw frame is already delivered to onMessage(String), so ignore unknown typed + // frames for forward compatibility with newly added server control messages. + } catch (Exception e) { + if (onErrorHandler != null) { + onErrorHandler.accept(e); + } + } + } +} diff --git a/src/main/java/com/deepgram/types/DeepgramModel.java.bak b/src/main/java/com/deepgram/types/DeepgramModel.java.bak new file mode 100644 index 0000000..6444d7f --- /dev/null +++ b/src/main/java/com/deepgram/types/DeepgramModel.java.bak @@ -0,0 +1,1071 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.types; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +public final class DeepgramModel { + public static final DeepgramModel AURA2SIRIO_ES = new DeepgramModel(Value.AURA2SIRIO_ES, "aura-2-sirio-es"); + + public static final DeepgramModel AURA2HERA_EN = new DeepgramModel(Value.AURA2HERA_EN, "aura-2-hera-en"); + + public static final DeepgramModel FLUX_KELSEY_EN = new DeepgramModel(Value.FLUX_KELSEY_EN, "flux-kelsey-en"); + + public static final DeepgramModel FLUX_RENEE_EN = new DeepgramModel(Value.FLUX_RENEE_EN, "flux-renee-en"); + + public static final DeepgramModel FLUX_SIENNA_EN = new DeepgramModel(Value.FLUX_SIENNA_EN, "flux-sienna-en"); + + public static final DeepgramModel AURA2HARMONIA_EN = + new DeepgramModel(Value.AURA2HARMONIA_EN, "aura-2-harmonia-en"); + + public static final DeepgramModel AURA2CARINA_ES = new DeepgramModel(Value.AURA2CARINA_ES, "aura-2-carina-es"); + + public static final DeepgramModel FLUX_MEENA_EN = new DeepgramModel(Value.FLUX_MEENA_EN, "flux-meena-en"); + + public static final DeepgramModel FLUX_MEGHAN_EN = new DeepgramModel(Value.FLUX_MEGHAN_EN, "flux-meghan-en"); + + public static final DeepgramModel AURA_ZEUS_EN = new DeepgramModel(Value.AURA_ZEUS_EN, "aura-zeus-en"); + + public static final DeepgramModel AURA2HERMES_EN = new DeepgramModel(Value.AURA2HERMES_EN, "aura-2-hermes-en"); + + public static final DeepgramModel FLUX_CONOR_EN = new DeepgramModel(Value.FLUX_CONOR_EN, "flux-conor-en"); + + public static final DeepgramModel AURA2NEPTUNE_EN = new DeepgramModel(Value.AURA2NEPTUNE_EN, "aura-2-neptune-en"); + + public static final DeepgramModel FLUX_BROOKE_EN = new DeepgramModel(Value.FLUX_BROOKE_EN, "flux-brooke-en"); + + public static final DeepgramModel FLUX_RUFUS_EN = new DeepgramModel(Value.FLUX_RUFUS_EN, "flux-rufus-en"); + + public static final DeepgramModel FLUX_WES_EN = new DeepgramModel(Value.FLUX_WES_EN, "flux-wes-en"); + + public static final DeepgramModel AURA2CALLISTA_EN = + new DeepgramModel(Value.AURA2CALLISTA_EN, "aura-2-callista-en"); + + public static final DeepgramModel AURA2AURORA_EN = new DeepgramModel(Value.AURA2AURORA_EN, "aura-2-aurora-en"); + + public static final DeepgramModel AURA2OPHELIA_EN = new DeepgramModel(Value.AURA2OPHELIA_EN, "aura-2-ophelia-en"); + + public static final DeepgramModel FLUX_BRUCE_EN = new DeepgramModel(Value.FLUX_BRUCE_EN, "flux-bruce-en"); + + public static final DeepgramModel AURA2APOLLO_EN = new DeepgramModel(Value.AURA2APOLLO_EN, "aura-2-apollo-en"); + + public static final DeepgramModel AURA2DELIA_EN = new DeepgramModel(Value.AURA2DELIA_EN, "aura-2-delia-en"); + + public static final DeepgramModel AURA2MARS_EN = new DeepgramModel(Value.AURA2MARS_EN, "aura-2-mars-en"); + + public static final DeepgramModel AURA_HERA_EN = new DeepgramModel(Value.AURA_HERA_EN, "aura-hera-en"); + + public static final DeepgramModel FLUX_MAEVE_EN = new DeepgramModel(Value.FLUX_MAEVE_EN, "flux-maeve-en"); + + public static final DeepgramModel FLUX_MARCUS_EN = new DeepgramModel(Value.FLUX_MARCUS_EN, "flux-marcus-en"); + + public static final DeepgramModel AURA2ARIES_EN = new DeepgramModel(Value.AURA2ARIES_EN, "aura-2-aries-en"); + + public static final DeepgramModel FLUX_PAIGE_EN = new DeepgramModel(Value.FLUX_PAIGE_EN, "flux-paige-en"); + + public static final DeepgramModel AURA2JUNO_EN = new DeepgramModel(Value.AURA2JUNO_EN, "aura-2-juno-en"); + + public static final DeepgramModel FLUX_DREW_EN = new DeepgramModel(Value.FLUX_DREW_EN, "flux-drew-en"); + + public static final DeepgramModel AURA2JAVIER_ES = new DeepgramModel(Value.AURA2JAVIER_ES, "aura-2-javier-es"); + + public static final DeepgramModel AURA2ANDROMEDA_EN = + new DeepgramModel(Value.AURA2ANDROMEDA_EN, "aura-2-andromeda-en"); + + public static final DeepgramModel AURA2SATURN_EN = new DeepgramModel(Value.AURA2SATURN_EN, "aura-2-saturn-en"); + + public static final DeepgramModel AURA2IRIS_EN = new DeepgramModel(Value.AURA2IRIS_EN, "aura-2-iris-en"); + + public static final DeepgramModel AURA_ANGUS_EN = new DeepgramModel(Value.AURA_ANGUS_EN, "aura-angus-en"); + + public static final DeepgramModel FLUX_KAI_EN = new DeepgramModel(Value.FLUX_KAI_EN, "flux-kai-en"); + + public static final DeepgramModel FLUX_BRITTANY_EN = new DeepgramModel(Value.FLUX_BRITTANY_EN, "flux-brittany-en"); + + public static final DeepgramModel FLUX_SEAN_EN = new DeepgramModel(Value.FLUX_SEAN_EN, "flux-sean-en"); + + public static final DeepgramModel AURA2HELENA_EN = new DeepgramModel(Value.AURA2HELENA_EN, "aura-2-helena-en"); + + public static final DeepgramModel FLUX_HALEY_EN = new DeepgramModel(Value.FLUX_HALEY_EN, "flux-haley-en"); + + public static final DeepgramModel AURA_STELLA_EN = new DeepgramModel(Value.AURA_STELLA_EN, "aura-stella-en"); + + public static final DeepgramModel FLUX_JACK_EN = new DeepgramModel(Value.FLUX_JACK_EN, "flux-jack-en"); + + public static final DeepgramModel AURA2DRACO_EN = new DeepgramModel(Value.AURA2DRACO_EN, "aura-2-draco-en"); + + public static final DeepgramModel FLUX_PRIYA_EN = new DeepgramModel(Value.FLUX_PRIYA_EN, "flux-priya-en"); + + public static final DeepgramModel AURA_HELIOS_EN = new DeepgramModel(Value.AURA_HELIOS_EN, "aura-helios-en"); + + public static final DeepgramModel AURA2JANUS_EN = new DeepgramModel(Value.AURA2JANUS_EN, "aura-2-janus-en"); + + public static final DeepgramModel AURA2NESTOR_ES = new DeepgramModel(Value.AURA2NESTOR_ES, "aura-2-nestor-es"); + + public static final DeepgramModel AURA2ORION_EN = new DeepgramModel(Value.AURA2ORION_EN, "aura-2-orion-en"); + + public static final DeepgramModel AURA2MINERVA_EN = new DeepgramModel(Value.AURA2MINERVA_EN, "aura-2-minerva-en"); + + public static final DeepgramModel AURA2ALVARO_ES = new DeepgramModel(Value.AURA2ALVARO_ES, "aura-2-alvaro-es"); + + public static final DeepgramModel AURA_PERSEUS_EN = new DeepgramModel(Value.AURA_PERSEUS_EN, "aura-perseus-en"); + + public static final DeepgramModel AURA2VESTA_EN = new DeepgramModel(Value.AURA2VESTA_EN, "aura-2-vesta-en"); + + public static final DeepgramModel FLUX_COLE_EN = new DeepgramModel(Value.FLUX_COLE_EN, "flux-cole-en"); + + public static final DeepgramModel AURA2ZEUS_EN = new DeepgramModel(Value.AURA2ZEUS_EN, "aura-2-zeus-en"); + + public static final DeepgramModel AURA2ORPHEUS_EN = new DeepgramModel(Value.AURA2ORPHEUS_EN, "aura-2-orpheus-en"); + + public static final DeepgramModel AURA2THALIA_EN = new DeepgramModel(Value.AURA2THALIA_EN, "aura-2-thalia-en"); + + public static final DeepgramModel FLUX_NAVEEN_EN = new DeepgramModel(Value.FLUX_NAVEEN_EN, "flux-naveen-en"); + + public static final DeepgramModel AURA2ASTERIA_EN = new DeepgramModel(Value.AURA2ASTERIA_EN, "aura-2-asteria-en"); + + public static final DeepgramModel AURA2SELENA_ES = new DeepgramModel(Value.AURA2SELENA_ES, "aura-2-selena-es"); + + public static final DeepgramModel FLUX_MARCELO_EN = new DeepgramModel(Value.FLUX_MARCELO_EN, "flux-marcelo-en"); + + public static final DeepgramModel FLUX_ELISE_EN = new DeepgramModel(Value.FLUX_ELISE_EN, "flux-elise-en"); + + public static final DeepgramModel FLUX_ALEXIS_EN = new DeepgramModel(Value.FLUX_ALEXIS_EN, "flux-alexis-en"); + + public static final DeepgramModel AURA_LUNA_EN = new DeepgramModel(Value.AURA_LUNA_EN, "aura-luna-en"); + + public static final DeepgramModel AURA_ORPHEUS_EN = new DeepgramModel(Value.AURA_ORPHEUS_EN, "aura-orpheus-en"); + + public static final DeepgramModel AURA2AMALTHEA_EN = + new DeepgramModel(Value.AURA2AMALTHEA_EN, "aura-2-amalthea-en"); + + public static final DeepgramModel FLUX_DONOVAN_EN = new DeepgramModel(Value.FLUX_DONOVAN_EN, "flux-donovan-en"); + + public static final DeepgramModel AURA2SELENE_EN = new DeepgramModel(Value.AURA2SELENE_EN, "aura-2-selene-en"); + + public static final DeepgramModel FLUX_TANNER_EN = new DeepgramModel(Value.FLUX_TANNER_EN, "flux-tanner-en"); + + public static final DeepgramModel FLUX_SHARON_EN = new DeepgramModel(Value.FLUX_SHARON_EN, "flux-sharon-en"); + + public static final DeepgramModel AURA2LUNA_EN = new DeepgramModel(Value.AURA2LUNA_EN, "aura-2-luna-en"); + + public static final DeepgramModel AURA2PHOEBE_EN = new DeepgramModel(Value.AURA2PHOEBE_EN, "aura-2-phoebe-en"); + + public static final DeepgramModel FLUX_HANNAH_EN = new DeepgramModel(Value.FLUX_HANNAH_EN, "flux-hannah-en"); + + public static final DeepgramModel AURA2DIANA_ES = new DeepgramModel(Value.AURA2DIANA_ES, "aura-2-diana-es"); + + public static final DeepgramModel AURA_ORION_EN = new DeepgramModel(Value.AURA_ORION_EN, "aura-orion-en"); + + public static final DeepgramModel AURA2ATHENA_EN = new DeepgramModel(Value.AURA2ATHENA_EN, "aura-2-athena-en"); + + public static final DeepgramModel AURA_ARCAS_EN = new DeepgramModel(Value.AURA_ARCAS_EN, "aura-arcas-en"); + + public static final DeepgramModel AURA2THEIA_EN = new DeepgramModel(Value.AURA2THEIA_EN, "aura-2-theia-en"); + + public static final DeepgramModel FLUX_WADE_EN = new DeepgramModel(Value.FLUX_WADE_EN, "flux-wade-en"); + + public static final DeepgramModel FLUX_HEATHER_EN = new DeepgramModel(Value.FLUX_HEATHER_EN, "flux-heather-en"); + + public static final DeepgramModel FLUX_CLIFF_EN = new DeepgramModel(Value.FLUX_CLIFF_EN, "flux-cliff-en"); + + public static final DeepgramModel AURA2JUPITER_EN = new DeepgramModel(Value.AURA2JUPITER_EN, "aura-2-jupiter-en"); + + public static final DeepgramModel FLUX_KIT_EN = new DeepgramModel(Value.FLUX_KIT_EN, "flux-kit-en"); + + public static final DeepgramModel AURA2AQUILA_ES = new DeepgramModel(Value.AURA2AQUILA_ES, "aura-2-aquila-es"); + + public static final DeepgramModel AURA2CORA_EN = new DeepgramModel(Value.AURA2CORA_EN, "aura-2-cora-en"); + + public static final DeepgramModel AURA2CORDELIA_EN = + new DeepgramModel(Value.AURA2CORDELIA_EN, "aura-2-cordelia-en"); + + public static final DeepgramModel AURA2ATLAS_EN = new DeepgramModel(Value.AURA2ATLAS_EN, "aura-2-atlas-en"); + + public static final DeepgramModel AURA2HYPERION_EN = + new DeepgramModel(Value.AURA2HYPERION_EN, "aura-2-hyperion-en"); + + public static final DeepgramModel AURA2CELESTE_ES = new DeepgramModel(Value.AURA2CELESTE_ES, "aura-2-celeste-es"); + + public static final DeepgramModel AURA2PLUTO_EN = new DeepgramModel(Value.AURA2PLUTO_EN, "aura-2-pluto-en"); + + public static final DeepgramModel FLUX_BREE_EN = new DeepgramModel(Value.FLUX_BREE_EN, "flux-bree-en"); + + public static final DeepgramModel AURA2ARCAS_EN = new DeepgramModel(Value.AURA2ARCAS_EN, "aura-2-arcas-en"); + + public static final DeepgramModel FLUX_COLIN_EN = new DeepgramModel(Value.FLUX_COLIN_EN, "flux-colin-en"); + + public static final DeepgramModel AURA_ATHENA_EN = new DeepgramModel(Value.AURA_ATHENA_EN, "aura-athena-en"); + + public static final DeepgramModel AURA2ODYSSEUS_EN = + new DeepgramModel(Value.AURA2ODYSSEUS_EN, "aura-2-odysseus-en"); + + public static final DeepgramModel AURA2PANDORA_EN = new DeepgramModel(Value.AURA2PANDORA_EN, "aura-2-pandora-en"); + + public static final DeepgramModel FLUX_MILES_EN = new DeepgramModel(Value.FLUX_MILES_EN, "flux-miles-en"); + + public static final DeepgramModel AURA_ASTERIA_EN = new DeepgramModel(Value.AURA_ASTERIA_EN, "aura-asteria-en"); + + public static final DeepgramModel AURA2ELECTRA_EN = new DeepgramModel(Value.AURA2ELECTRA_EN, "aura-2-electra-en"); + + public static final DeepgramModel FLUX_GEMMA_EN = new DeepgramModel(Value.FLUX_GEMMA_EN, "flux-gemma-en"); + + public static final DeepgramModel AURA2ESTRELLA_ES = + new DeepgramModel(Value.AURA2ESTRELLA_ES, "aura-2-estrella-es"); + + private final Value value; + + private final String string; + + DeepgramModel(Value value, String string) { + this.value = value; + this.string = string; + } + + public Value getEnumValue() { + return value; + } + + @java.lang.Override + @JsonValue + public String toString() { + return this.string; + } + + @java.lang.Override + public boolean equals(Object other) { + return (this == other) + || (other instanceof DeepgramModel && this.string.equals(((DeepgramModel) other).string)); + } + + @java.lang.Override + public int hashCode() { + return this.string.hashCode(); + } + + public T visit(Visitor visitor) { + switch (value) { + case AURA2SIRIO_ES: + return visitor.visitAura2SirioEs(); + case AURA2HERA_EN: + return visitor.visitAura2HeraEn(); + case FLUX_KELSEY_EN: + return visitor.visitFluxKelseyEn(); + case FLUX_RENEE_EN: + return visitor.visitFluxReneeEn(); + case FLUX_SIENNA_EN: + return visitor.visitFluxSiennaEn(); + case AURA2HARMONIA_EN: + return visitor.visitAura2HarmoniaEn(); + case AURA2CARINA_ES: + return visitor.visitAura2CarinaEs(); + case FLUX_MEENA_EN: + return visitor.visitFluxMeenaEn(); + case FLUX_MEGHAN_EN: + return visitor.visitFluxMeghanEn(); + case AURA_ZEUS_EN: + return visitor.visitAuraZeusEn(); + case AURA2HERMES_EN: + return visitor.visitAura2HermesEn(); + case FLUX_CONOR_EN: + return visitor.visitFluxConorEn(); + case AURA2NEPTUNE_EN: + return visitor.visitAura2NeptuneEn(); + case FLUX_BROOKE_EN: + return visitor.visitFluxBrookeEn(); + case FLUX_RUFUS_EN: + return visitor.visitFluxRufusEn(); + case FLUX_WES_EN: + return visitor.visitFluxWesEn(); + case AURA2CALLISTA_EN: + return visitor.visitAura2CallistaEn(); + case AURA2AURORA_EN: + return visitor.visitAura2AuroraEn(); + case AURA2OPHELIA_EN: + return visitor.visitAura2OpheliaEn(); + case FLUX_BRUCE_EN: + return visitor.visitFluxBruceEn(); + case AURA2APOLLO_EN: + return visitor.visitAura2ApolloEn(); + case AURA2DELIA_EN: + return visitor.visitAura2DeliaEn(); + case AURA2MARS_EN: + return visitor.visitAura2MarsEn(); + case AURA_HERA_EN: + return visitor.visitAuraHeraEn(); + case FLUX_MAEVE_EN: + return visitor.visitFluxMaeveEn(); + case FLUX_MARCUS_EN: + return visitor.visitFluxMarcusEn(); + case AURA2ARIES_EN: + return visitor.visitAura2AriesEn(); + case FLUX_PAIGE_EN: + return visitor.visitFluxPaigeEn(); + case AURA2JUNO_EN: + return visitor.visitAura2JunoEn(); + case FLUX_DREW_EN: + return visitor.visitFluxDrewEn(); + case AURA2JAVIER_ES: + return visitor.visitAura2JavierEs(); + case AURA2ANDROMEDA_EN: + return visitor.visitAura2AndromedaEn(); + case AURA2SATURN_EN: + return visitor.visitAura2SaturnEn(); + case AURA2IRIS_EN: + return visitor.visitAura2IrisEn(); + case AURA_ANGUS_EN: + return visitor.visitAuraAngusEn(); + case FLUX_KAI_EN: + return visitor.visitFluxKaiEn(); + case FLUX_BRITTANY_EN: + return visitor.visitFluxBrittanyEn(); + case FLUX_SEAN_EN: + return visitor.visitFluxSeanEn(); + case AURA2HELENA_EN: + return visitor.visitAura2HelenaEn(); + case FLUX_HALEY_EN: + return visitor.visitFluxHaleyEn(); + case AURA_STELLA_EN: + return visitor.visitAuraStellaEn(); + case FLUX_JACK_EN: + return visitor.visitFluxJackEn(); + case AURA2DRACO_EN: + return visitor.visitAura2DracoEn(); + case FLUX_PRIYA_EN: + return visitor.visitFluxPriyaEn(); + case AURA_HELIOS_EN: + return visitor.visitAuraHeliosEn(); + case AURA2JANUS_EN: + return visitor.visitAura2JanusEn(); + case AURA2NESTOR_ES: + return visitor.visitAura2NestorEs(); + case AURA2ORION_EN: + return visitor.visitAura2OrionEn(); + case AURA2MINERVA_EN: + return visitor.visitAura2MinervaEn(); + case AURA2ALVARO_ES: + return visitor.visitAura2AlvaroEs(); + case AURA_PERSEUS_EN: + return visitor.visitAuraPerseusEn(); + case AURA2VESTA_EN: + return visitor.visitAura2VestaEn(); + case FLUX_COLE_EN: + return visitor.visitFluxColeEn(); + case AURA2ZEUS_EN: + return visitor.visitAura2ZeusEn(); + case AURA2ORPHEUS_EN: + return visitor.visitAura2OrpheusEn(); + case AURA2THALIA_EN: + return visitor.visitAura2ThaliaEn(); + case FLUX_NAVEEN_EN: + return visitor.visitFluxNaveenEn(); + case AURA2ASTERIA_EN: + return visitor.visitAura2AsteriaEn(); + case AURA2SELENA_ES: + return visitor.visitAura2SelenaEs(); + case FLUX_MARCELO_EN: + return visitor.visitFluxMarceloEn(); + case FLUX_ELISE_EN: + return visitor.visitFluxEliseEn(); + case FLUX_ALEXIS_EN: + return visitor.visitFluxAlexisEn(); + case AURA_LUNA_EN: + return visitor.visitAuraLunaEn(); + case AURA_ORPHEUS_EN: + return visitor.visitAuraOrpheusEn(); + case AURA2AMALTHEA_EN: + return visitor.visitAura2AmaltheaEn(); + case FLUX_DONOVAN_EN: + return visitor.visitFluxDonovanEn(); + case AURA2SELENE_EN: + return visitor.visitAura2SeleneEn(); + case FLUX_TANNER_EN: + return visitor.visitFluxTannerEn(); + case FLUX_SHARON_EN: + return visitor.visitFluxSharonEn(); + case AURA2LUNA_EN: + return visitor.visitAura2LunaEn(); + case AURA2PHOEBE_EN: + return visitor.visitAura2PhoebeEn(); + case FLUX_HANNAH_EN: + return visitor.visitFluxHannahEn(); + case AURA2DIANA_ES: + return visitor.visitAura2DianaEs(); + case AURA_ORION_EN: + return visitor.visitAuraOrionEn(); + case AURA2ATHENA_EN: + return visitor.visitAura2AthenaEn(); + case AURA_ARCAS_EN: + return visitor.visitAuraArcasEn(); + case AURA2THEIA_EN: + return visitor.visitAura2TheiaEn(); + case FLUX_WADE_EN: + return visitor.visitFluxWadeEn(); + case FLUX_HEATHER_EN: + return visitor.visitFluxHeatherEn(); + case FLUX_CLIFF_EN: + return visitor.visitFluxCliffEn(); + case AURA2JUPITER_EN: + return visitor.visitAura2JupiterEn(); + case FLUX_KIT_EN: + return visitor.visitFluxKitEn(); + case AURA2AQUILA_ES: + return visitor.visitAura2AquilaEs(); + case AURA2CORA_EN: + return visitor.visitAura2CoraEn(); + case AURA2CORDELIA_EN: + return visitor.visitAura2CordeliaEn(); + case AURA2ATLAS_EN: + return visitor.visitAura2AtlasEn(); + case AURA2HYPERION_EN: + return visitor.visitAura2HyperionEn(); + case AURA2CELESTE_ES: + return visitor.visitAura2CelesteEs(); + case AURA2PLUTO_EN: + return visitor.visitAura2PlutoEn(); + case FLUX_BREE_EN: + return visitor.visitFluxBreeEn(); + case AURA2ARCAS_EN: + return visitor.visitAura2ArcasEn(); + case FLUX_COLIN_EN: + return visitor.visitFluxColinEn(); + case AURA_ATHENA_EN: + return visitor.visitAuraAthenaEn(); + case AURA2ODYSSEUS_EN: + return visitor.visitAura2OdysseusEn(); + case AURA2PANDORA_EN: + return visitor.visitAura2PandoraEn(); + case FLUX_MILES_EN: + return visitor.visitFluxMilesEn(); + case AURA_ASTERIA_EN: + return visitor.visitAuraAsteriaEn(); + case AURA2ELECTRA_EN: + return visitor.visitAura2ElectraEn(); + case FLUX_GEMMA_EN: + return visitor.visitFluxGemmaEn(); + case AURA2ESTRELLA_ES: + return visitor.visitAura2EstrellaEs(); + case UNKNOWN: + default: + return visitor.visitUnknown(string); + } + } + + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) + public static DeepgramModel valueOf(String value) { + switch (value) { + case "aura-2-sirio-es": + return AURA2SIRIO_ES; + case "aura-2-hera-en": + return AURA2HERA_EN; + case "flux-kelsey-en": + return FLUX_KELSEY_EN; + case "flux-renee-en": + return FLUX_RENEE_EN; + case "flux-sienna-en": + return FLUX_SIENNA_EN; + case "aura-2-harmonia-en": + return AURA2HARMONIA_EN; + case "aura-2-carina-es": + return AURA2CARINA_ES; + case "flux-meena-en": + return FLUX_MEENA_EN; + case "flux-meghan-en": + return FLUX_MEGHAN_EN; + case "aura-zeus-en": + return AURA_ZEUS_EN; + case "aura-2-hermes-en": + return AURA2HERMES_EN; + case "flux-conor-en": + return FLUX_CONOR_EN; + case "aura-2-neptune-en": + return AURA2NEPTUNE_EN; + case "flux-brooke-en": + return FLUX_BROOKE_EN; + case "flux-rufus-en": + return FLUX_RUFUS_EN; + case "flux-wes-en": + return FLUX_WES_EN; + case "aura-2-callista-en": + return AURA2CALLISTA_EN; + case "aura-2-aurora-en": + return AURA2AURORA_EN; + case "aura-2-ophelia-en": + return AURA2OPHELIA_EN; + case "flux-bruce-en": + return FLUX_BRUCE_EN; + case "aura-2-apollo-en": + return AURA2APOLLO_EN; + case "aura-2-delia-en": + return AURA2DELIA_EN; + case "aura-2-mars-en": + return AURA2MARS_EN; + case "aura-hera-en": + return AURA_HERA_EN; + case "flux-maeve-en": + return FLUX_MAEVE_EN; + case "flux-marcus-en": + return FLUX_MARCUS_EN; + case "aura-2-aries-en": + return AURA2ARIES_EN; + case "flux-paige-en": + return FLUX_PAIGE_EN; + case "aura-2-juno-en": + return AURA2JUNO_EN; + case "flux-drew-en": + return FLUX_DREW_EN; + case "aura-2-javier-es": + return AURA2JAVIER_ES; + case "aura-2-andromeda-en": + return AURA2ANDROMEDA_EN; + case "aura-2-saturn-en": + return AURA2SATURN_EN; + case "aura-2-iris-en": + return AURA2IRIS_EN; + case "aura-angus-en": + return AURA_ANGUS_EN; + case "flux-kai-en": + return FLUX_KAI_EN; + case "flux-brittany-en": + return FLUX_BRITTANY_EN; + case "flux-sean-en": + return FLUX_SEAN_EN; + case "aura-2-helena-en": + return AURA2HELENA_EN; + case "flux-haley-en": + return FLUX_HALEY_EN; + case "aura-stella-en": + return AURA_STELLA_EN; + case "flux-jack-en": + return FLUX_JACK_EN; + case "aura-2-draco-en": + return AURA2DRACO_EN; + case "flux-priya-en": + return FLUX_PRIYA_EN; + case "aura-helios-en": + return AURA_HELIOS_EN; + case "aura-2-janus-en": + return AURA2JANUS_EN; + case "aura-2-nestor-es": + return AURA2NESTOR_ES; + case "aura-2-orion-en": + return AURA2ORION_EN; + case "aura-2-minerva-en": + return AURA2MINERVA_EN; + case "aura-2-alvaro-es": + return AURA2ALVARO_ES; + case "aura-perseus-en": + return AURA_PERSEUS_EN; + case "aura-2-vesta-en": + return AURA2VESTA_EN; + case "flux-cole-en": + return FLUX_COLE_EN; + case "aura-2-zeus-en": + return AURA2ZEUS_EN; + case "aura-2-orpheus-en": + return AURA2ORPHEUS_EN; + case "aura-2-thalia-en": + return AURA2THALIA_EN; + case "flux-naveen-en": + return FLUX_NAVEEN_EN; + case "aura-2-asteria-en": + return AURA2ASTERIA_EN; + case "aura-2-selena-es": + return AURA2SELENA_ES; + case "flux-marcelo-en": + return FLUX_MARCELO_EN; + case "flux-elise-en": + return FLUX_ELISE_EN; + case "flux-alexis-en": + return FLUX_ALEXIS_EN; + case "aura-luna-en": + return AURA_LUNA_EN; + case "aura-orpheus-en": + return AURA_ORPHEUS_EN; + case "aura-2-amalthea-en": + return AURA2AMALTHEA_EN; + case "flux-donovan-en": + return FLUX_DONOVAN_EN; + case "aura-2-selene-en": + return AURA2SELENE_EN; + case "flux-tanner-en": + return FLUX_TANNER_EN; + case "flux-sharon-en": + return FLUX_SHARON_EN; + case "aura-2-luna-en": + return AURA2LUNA_EN; + case "aura-2-phoebe-en": + return AURA2PHOEBE_EN; + case "flux-hannah-en": + return FLUX_HANNAH_EN; + case "aura-2-diana-es": + return AURA2DIANA_ES; + case "aura-orion-en": + return AURA_ORION_EN; + case "aura-2-athena-en": + return AURA2ATHENA_EN; + case "aura-arcas-en": + return AURA_ARCAS_EN; + case "aura-2-theia-en": + return AURA2THEIA_EN; + case "flux-wade-en": + return FLUX_WADE_EN; + case "flux-heather-en": + return FLUX_HEATHER_EN; + case "flux-cliff-en": + return FLUX_CLIFF_EN; + case "aura-2-jupiter-en": + return AURA2JUPITER_EN; + case "flux-kit-en": + return FLUX_KIT_EN; + case "aura-2-aquila-es": + return AURA2AQUILA_ES; + case "aura-2-cora-en": + return AURA2CORA_EN; + case "aura-2-cordelia-en": + return AURA2CORDELIA_EN; + case "aura-2-atlas-en": + return AURA2ATLAS_EN; + case "aura-2-hyperion-en": + return AURA2HYPERION_EN; + case "aura-2-celeste-es": + return AURA2CELESTE_ES; + case "aura-2-pluto-en": + return AURA2PLUTO_EN; + case "flux-bree-en": + return FLUX_BREE_EN; + case "aura-2-arcas-en": + return AURA2ARCAS_EN; + case "flux-colin-en": + return FLUX_COLIN_EN; + case "aura-athena-en": + return AURA_ATHENA_EN; + case "aura-2-odysseus-en": + return AURA2ODYSSEUS_EN; + case "aura-2-pandora-en": + return AURA2PANDORA_EN; + case "flux-miles-en": + return FLUX_MILES_EN; + case "aura-asteria-en": + return AURA_ASTERIA_EN; + case "aura-2-electra-en": + return AURA2ELECTRA_EN; + case "flux-gemma-en": + return FLUX_GEMMA_EN; + case "aura-2-estrella-es": + return AURA2ESTRELLA_ES; + default: + return new DeepgramModel(Value.UNKNOWN, value); + } + } + + public enum Value { + AURA_ASTERIA_EN, + + AURA_LUNA_EN, + + AURA_STELLA_EN, + + AURA_ATHENA_EN, + + AURA_HERA_EN, + + AURA_ORION_EN, + + AURA_ARCAS_EN, + + AURA_PERSEUS_EN, + + AURA_ANGUS_EN, + + AURA_ORPHEUS_EN, + + AURA_HELIOS_EN, + + AURA_ZEUS_EN, + + AURA2AMALTHEA_EN, + + AURA2ANDROMEDA_EN, + + AURA2APOLLO_EN, + + AURA2ARCAS_EN, + + AURA2ARIES_EN, + + AURA2ASTERIA_EN, + + AURA2ATHENA_EN, + + AURA2ATLAS_EN, + + AURA2AURORA_EN, + + AURA2CALLISTA_EN, + + AURA2CORA_EN, + + AURA2CORDELIA_EN, + + AURA2DELIA_EN, + + AURA2DRACO_EN, + + AURA2ELECTRA_EN, + + AURA2HARMONIA_EN, + + AURA2HELENA_EN, + + AURA2HERA_EN, + + AURA2HERMES_EN, + + AURA2HYPERION_EN, + + AURA2IRIS_EN, + + AURA2JANUS_EN, + + AURA2JUNO_EN, + + AURA2JUPITER_EN, + + AURA2LUNA_EN, + + AURA2MARS_EN, + + AURA2MINERVA_EN, + + AURA2NEPTUNE_EN, + + AURA2ODYSSEUS_EN, + + AURA2OPHELIA_EN, + + AURA2ORION_EN, + + AURA2ORPHEUS_EN, + + AURA2PANDORA_EN, + + AURA2PHOEBE_EN, + + AURA2PLUTO_EN, + + AURA2SATURN_EN, + + AURA2SELENE_EN, + + AURA2THALIA_EN, + + AURA2THEIA_EN, + + AURA2VESTA_EN, + + AURA2ZEUS_EN, + + AURA2SIRIO_ES, + + AURA2NESTOR_ES, + + AURA2CARINA_ES, + + AURA2CELESTE_ES, + + AURA2ALVARO_ES, + + AURA2DIANA_ES, + + AURA2AQUILA_ES, + + AURA2SELENA_ES, + + AURA2ESTRELLA_ES, + + AURA2JAVIER_ES, + + FLUX_ALEXIS_EN, + + FLUX_BREE_EN, + + FLUX_BRITTANY_EN, + + FLUX_BROOKE_EN, + + FLUX_BRUCE_EN, + + FLUX_CLIFF_EN, + + FLUX_COLE_EN, + + FLUX_COLIN_EN, + + FLUX_CONOR_EN, + + FLUX_DONOVAN_EN, + + FLUX_DREW_EN, + + FLUX_ELISE_EN, + + FLUX_GEMMA_EN, + + FLUX_HALEY_EN, + + FLUX_HANNAH_EN, + + FLUX_HEATHER_EN, + + FLUX_JACK_EN, + + FLUX_KAI_EN, + + FLUX_KELSEY_EN, + + FLUX_KIT_EN, + + FLUX_MAEVE_EN, + + FLUX_MARCELO_EN, + + FLUX_MARCUS_EN, + + FLUX_MEENA_EN, + + FLUX_MEGHAN_EN, + + FLUX_MILES_EN, + + FLUX_NAVEEN_EN, + + FLUX_PAIGE_EN, + + FLUX_PRIYA_EN, + + FLUX_RENEE_EN, + + FLUX_RUFUS_EN, + + FLUX_SEAN_EN, + + FLUX_SHARON_EN, + + FLUX_SIENNA_EN, + + FLUX_TANNER_EN, + + FLUX_WADE_EN, + + FLUX_WES_EN, + + UNKNOWN + } + + public interface Visitor { + T visitAuraAsteriaEn(); + + T visitAuraLunaEn(); + + T visitAuraStellaEn(); + + T visitAuraAthenaEn(); + + T visitAuraHeraEn(); + + T visitAuraOrionEn(); + + T visitAuraArcasEn(); + + T visitAuraPerseusEn(); + + T visitAuraAngusEn(); + + T visitAuraOrpheusEn(); + + T visitAuraHeliosEn(); + + T visitAuraZeusEn(); + + T visitAura2AmaltheaEn(); + + T visitAura2AndromedaEn(); + + T visitAura2ApolloEn(); + + T visitAura2ArcasEn(); + + T visitAura2AriesEn(); + + T visitAura2AsteriaEn(); + + T visitAura2AthenaEn(); + + T visitAura2AtlasEn(); + + T visitAura2AuroraEn(); + + T visitAura2CallistaEn(); + + T visitAura2CoraEn(); + + T visitAura2CordeliaEn(); + + T visitAura2DeliaEn(); + + T visitAura2DracoEn(); + + T visitAura2ElectraEn(); + + T visitAura2HarmoniaEn(); + + T visitAura2HelenaEn(); + + T visitAura2HeraEn(); + + T visitAura2HermesEn(); + + T visitAura2HyperionEn(); + + T visitAura2IrisEn(); + + T visitAura2JanusEn(); + + T visitAura2JunoEn(); + + T visitAura2JupiterEn(); + + T visitAura2LunaEn(); + + T visitAura2MarsEn(); + + T visitAura2MinervaEn(); + + T visitAura2NeptuneEn(); + + T visitAura2OdysseusEn(); + + T visitAura2OpheliaEn(); + + T visitAura2OrionEn(); + + T visitAura2OrpheusEn(); + + T visitAura2PandoraEn(); + + T visitAura2PhoebeEn(); + + T visitAura2PlutoEn(); + + T visitAura2SaturnEn(); + + T visitAura2SeleneEn(); + + T visitAura2ThaliaEn(); + + T visitAura2TheiaEn(); + + T visitAura2VestaEn(); + + T visitAura2ZeusEn(); + + T visitAura2SirioEs(); + + T visitAura2NestorEs(); + + T visitAura2CarinaEs(); + + T visitAura2CelesteEs(); + + T visitAura2AlvaroEs(); + + T visitAura2DianaEs(); + + T visitAura2AquilaEs(); + + T visitAura2SelenaEs(); + + T visitAura2EstrellaEs(); + + T visitAura2JavierEs(); + + T visitFluxAlexisEn(); + + T visitFluxBreeEn(); + + T visitFluxBrittanyEn(); + + T visitFluxBrookeEn(); + + T visitFluxBruceEn(); + + T visitFluxCliffEn(); + + T visitFluxColeEn(); + + T visitFluxColinEn(); + + T visitFluxConorEn(); + + T visitFluxDonovanEn(); + + T visitFluxDrewEn(); + + T visitFluxEliseEn(); + + T visitFluxGemmaEn(); + + T visitFluxHaleyEn(); + + T visitFluxHannahEn(); + + T visitFluxHeatherEn(); + + T visitFluxJackEn(); + + T visitFluxKaiEn(); + + T visitFluxKelseyEn(); + + T visitFluxKitEn(); + + T visitFluxMaeveEn(); + + T visitFluxMarceloEn(); + + T visitFluxMarcusEn(); + + T visitFluxMeenaEn(); + + T visitFluxMeghanEn(); + + T visitFluxMilesEn(); + + T visitFluxNaveenEn(); + + T visitFluxPaigeEn(); + + T visitFluxPriyaEn(); + + T visitFluxReneeEn(); + + T visitFluxRufusEn(); + + T visitFluxSeanEn(); + + T visitFluxSharonEn(); + + T visitFluxSiennaEn(); + + T visitFluxTannerEn(); + + T visitFluxWadeEn(); + + T visitFluxWesEn(); + + T visitUnknown(String unknownType); + } +} From 564f5e69ca7dc0244f20f3cbceaa367e0dcd846e Mon Sep 17 00:00:00 2001 From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com> Date: Wed, 14 Oct 2026 08:50:57 +0000 Subject: [PATCH 3/8] SDK regeneration --- .fern/metadata.json | 8 +- .../com/deepgram/AsyncDeepgramApiClient.java | 5 +- .../java/com/deepgram/DeepgramApiClient.java | 5 +- .../java/com/deepgram/core/ClientOptions.java | 85 +----- .../deepgram/core/OkHttpWebSocketFactory.java | 22 -- .../core/ReconnectingWebSocketListener.java | 95 ++----- .../com/deepgram/core/RetryInterceptor.java | 66 +---- .../agent/v1/types/AgentV1AgentAudioDone.java | 5 - .../types/AgentV1CustomFromThinkProvider.java | 125 -------- .../types/AgentV1CustomToThinkProvider.java | 125 -------- .../agent/v1/types/AgentV1ForceEndTurn.java | 5 - .../agent/v1/types/AgentV1KeepAlive.java | 5 - .../agent/v1/types/AgentV1ListenUpdated.java | 5 - .../agent/v1/types/AgentV1PromptUpdated.java | 5 - ...tV1SettingsAgentContextListenProvider.java | 2 +- .../AgentV1SettingsAgentListenProvider.java | 2 +- .../v1/types/AgentV1SettingsApplied.java | 5 - .../agent/v1/types/AgentV1SpeakUpdated.java | 5 - .../agent/v1/types/AgentV1ThinkUpdated.java | 5 - .../AgentV1UpdateListenListenProvider.java | 2 +- .../v1/types/AgentV1UserStartedSpeaking.java | 5 - .../agent/v1/websocket/V1WebSocketClient.java | 65 +---- .../listen/v1/types/ListenV1Configure.java | 165 ----------- .../listen/v1/types/ListenV1Error.java | 267 ------------------ .../v1/websocket/V1WebSocketClient.java | 92 ++---- .../listen/v2/types/ListenV2CloseStream.java | 5 - .../v2/types/ListenV2ConfigureFailure.java | 100 +------ .../listen/v2/types/ListenV2ForceEndTurn.java | 5 - .../listen/v2/types/ListenV2Warning.java | 247 ---------------- .../v2/websocket/V2WebSocketClient.java | 104 ++----- .../speak/v1/websocket/V1WebSocketClient.java | 37 +-- .../v2/audio/requests/SpeakV2Request.java | 14 +- .../speak/v2/types/SpeakV2Close.java | 5 - .../v2/types/SpeakV2ConfigureFailure.java | 6 +- .../v2/types/SpeakV2ConfigureFailureCode.java | 11 - .../speak/v2/types/SpeakV2Error.java | 6 +- .../speak/v2/types/SpeakV2Flush.java | 5 - .../speak/v2/types/SpeakV2Speak.java | 6 +- .../SpeakV2SpeechInterruptedMetadata.java | 6 +- ...echInterruptedMetadataControlsApplied.java | 18 +- .../speak/v2/types/SpeakV2SpeechMetadata.java | 6 +- .../SpeakV2SpeechMetadataControlsApplied.java | 18 +- .../speak/v2/types/SpeakV2Warning.java | 9 +- .../speak/v2/websocket/V2WebSocketClient.java | 46 +-- .../com/deepgram/types/DeepgramModel.java | 10 - .../com/deepgram/types/SharedIntents.java | 34 ++- .../deepgram/types/SharedIntentsResults.java | 106 +++++++ .../types/SharedIntentsResultsIntents.java | 108 +++++++ ...redIntentsResultsIntentsSegmentsItem.java} | 29 +- ...esultsIntentsSegmentsItemIntentsItem.java} | 19 +- .../java/com/deepgram/types/SharedTopics.java | 33 ++- .../deepgram/types/SharedTopicsResults.java | 105 +++++++ .../types/SharedTopicsResultsTopics.java | 107 +++++++ ...haredTopicsResultsTopicsSegmentsItem.java} | 29 +- ...sResultsTopicsSegmentsItemTopicsItem.java} | 18 +- 55 files changed, 667 insertions(+), 1761 deletions(-) delete mode 100644 src/main/java/com/deepgram/resources/agent/v1/types/AgentV1CustomFromThinkProvider.java delete mode 100644 src/main/java/com/deepgram/resources/agent/v1/types/AgentV1CustomToThinkProvider.java delete mode 100644 src/main/java/com/deepgram/resources/listen/v1/types/ListenV1Configure.java delete mode 100644 src/main/java/com/deepgram/resources/listen/v1/types/ListenV1Error.java delete mode 100644 src/main/java/com/deepgram/resources/listen/v2/types/ListenV2Warning.java create mode 100644 src/main/java/com/deepgram/types/SharedIntentsResults.java create mode 100644 src/main/java/com/deepgram/types/SharedIntentsResultsIntents.java rename src/main/java/com/deepgram/types/{SharedIntentsSegmentsItem.java => SharedIntentsResultsIntentsSegmentsItem.java} (78%) rename src/main/java/com/deepgram/types/{SharedIntentsSegmentsItemIntentsItem.java => SharedIntentsResultsIntentsSegmentsItemIntentsItem.java} (81%) create mode 100644 src/main/java/com/deepgram/types/SharedTopicsResults.java create mode 100644 src/main/java/com/deepgram/types/SharedTopicsResultsTopics.java rename src/main/java/com/deepgram/types/{SharedTopicsSegmentsItem.java => SharedTopicsResultsTopicsSegmentsItem.java} (78%) rename src/main/java/com/deepgram/types/{SharedTopicsSegmentsItemTopicsItem.java => SharedTopicsResultsTopicsSegmentsItemTopicsItem.java} (82%) diff --git a/.fern/metadata.json b/.fern/metadata.json index 1955a2a..65cffab 100644 --- a/.fern/metadata.json +++ b/.fern/metadata.json @@ -1,7 +1,7 @@ { "cliVersion": "5.95.1", "generatorName": "fernapi/fern-java-sdk", - "generatorVersion": "4.23.1", + "generatorVersion": "4.21.0", "generatorConfig": { "package-prefix": "com.deepgram", "base-api-exception-class-name": "DeepgramHttpException", @@ -12,8 +12,8 @@ "enable-wire-tests": true, "runtime-version": true }, - "originGitCommit": "9dcbd3d5e8d36420319e1b33988613ad2cb2be10", + "originGitCommit": "97e7b8ba56fdf31596232836ed4849148d72813e", "originGitCommitIsDirty": true, "invokedBy": "manual", - "sdkVersion": "0.11.1" -} + "sdkVersion": "0.11.2" +} \ No newline at end of file diff --git a/src/main/java/com/deepgram/AsyncDeepgramApiClient.java b/src/main/java/com/deepgram/AsyncDeepgramApiClient.java index 0ae6c11..c2aa87e 100644 --- a/src/main/java/com/deepgram/AsyncDeepgramApiClient.java +++ b/src/main/java/com/deepgram/AsyncDeepgramApiClient.java @@ -79,9 +79,8 @@ public AsyncVoiceAgentClient voiceAgent() { } /** - * Releases resources owned by this client: any WebSocket clients still connected through - * it are disconnected first, then the SDK-owned HTTP client is shut down. See - * {@code ClientOptions.close()} for what is and is not released. + * Releases resources owned by this client. See {@code ClientOptions.close()} for what is + * and is not released. */ @Override public void close() { diff --git a/src/main/java/com/deepgram/DeepgramApiClient.java b/src/main/java/com/deepgram/DeepgramApiClient.java index a67528f..ccb0d4a 100644 --- a/src/main/java/com/deepgram/DeepgramApiClient.java +++ b/src/main/java/com/deepgram/DeepgramApiClient.java @@ -79,9 +79,8 @@ public VoiceAgentClient voiceAgent() { } /** - * Releases resources owned by this client: any WebSocket clients still connected through - * it are disconnected first, then the SDK-owned HTTP client is shut down. See - * {@code ClientOptions.close()} for what is and is not released. + * Releases resources owned by this client. See {@code ClientOptions.close()} for what is + * and is not released. */ @Override public void close() { diff --git a/src/main/java/com/deepgram/core/ClientOptions.java b/src/main/java/com/deepgram/core/ClientOptions.java index b2c87ee..0c075cc 100644 --- a/src/main/java/com/deepgram/core/ClientOptions.java +++ b/src/main/java/com/deepgram/core/ClientOptions.java @@ -3,14 +3,10 @@ */ package com.deepgram.core; -import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Optional; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; import okhttp3.OkHttpClient; @@ -25,10 +21,6 @@ public final class ClientOptions { private final boolean ownsHttpClient; - private final AtomicBoolean closed; - - private final Set openWebSockets; - private final int timeout; private final int maxRetries; @@ -49,8 +41,6 @@ private ClientOptions( Map> headerSuppliers, OkHttpClient httpClient, boolean ownsHttpClient, - AtomicBoolean closed, - Set openWebSockets, int timeout, int maxRetries, Optional initialRetryDelayMillis, @@ -63,17 +53,15 @@ private ClientOptions( this.headers.putAll(headers); this.headers.putAll(new HashMap() { { - put("User-Agent", "com.deepgram:deepgram-java-sdk/0.11.1"); // x-release-please-version + put("User-Agent", "com.deepgram.deepgram-java-sdk/" + getSdkVersion()); put("X-Fern-Language", "JAVA"); put("X-Fern-SDK-Name", "com.deepgram:deepgram-java-sdk"); - put("X-Fern-SDK-Version", "0.11.1"); // x-release-please-version + put("X-Fern-SDK-Version", getSdkVersion()); } }); this.headerSuppliers = headerSuppliers; this.httpClient = httpClient; this.ownsHttpClient = ownsHttpClient; - this.closed = closed; - this.openWebSockets = openWebSockets; this.timeout = timeout; this.maxRetries = maxRetries; this.initialRetryDelayMillis = initialRetryDelayMillis; @@ -98,6 +86,11 @@ public Map headers(RequestOptions requestOptions) { return values; } + private static String getSdkVersion() { + String version = ClientOptions.class.getPackage().getImplementationVersion(); + return version != null ? version : "0.11.2"; + } + public int timeout(RequestOptions requestOptions) { if (requestOptions == null) { return this.timeout; @@ -144,29 +137,12 @@ public Optional retryJitterFactor() { * OkHttpClient itself; an OkHttpClient supplied via httpClient is left running, since the * caller owns its lifecycle. *

- * In-flight calls are not cancelled or awaited. When this client owns its OkHttpClient, later - * asynchronous HTTP requests can fail when the dispatcher rejects work, while synchronous - * requests may still run. An OkHttpClient supplied through {@code httpClient(...)} remains - * caller-owned and running. Options derived via {@code Builder.from(...)} share lifecycle - * state; calling this method more than once has no further effect. - *

- * WebSocket clients created from this client that are still connected are disconnected - * first (whether or not the OkHttpClient is owned), so they stop reconnecting before the - * dispatcher goes away. Any WebSocket connect or reconnect attempted afterwards fails with - * an {@code IllegalStateException} explaining that the client has been closed. + * In-flight calls are not cancelled or awaited, and any request issued after this method + * returns fails with a {@code RejectedExecutionException}. Options derived from this one via + * {@code Builder.from(...)} share the same dispatcher and connection pool, so closing either + * releases them for both. Calling this method more than once has no further effect. */ public void close() { - if (!this.closed.compareAndSet(false, true)) { - return; - } - for (AutoCloseable webSocket : new ArrayList<>(this.openWebSockets)) { - try { - webSocket.close(); - } catch (Exception e) { - // best effort; keep closing the remaining sockets and the HTTP client - } - } - this.openWebSockets.clear(); if (!this.ownsHttpClient) { return; } @@ -174,33 +150,6 @@ public void close() { this.httpClient.connectionPool().evictAll(); } - /** - * Returns whether {@link #close()} has been called on this client. - */ - public boolean isClosed() { - return this.closed.get(); - } - - /** - * Tracks a connected WebSocket client so that {@link #close()} disconnects it. - * - * @throws IllegalStateException if this client has already been closed - */ - public void registerWebSocket(AutoCloseable webSocket) { - this.openWebSockets.add(webSocket); - if (this.closed.get()) { - this.openWebSockets.remove(webSocket); - throw new IllegalStateException("root client has been closed"); - } - } - - /** - * Stops tracking a WebSocket client that has been disconnected. - */ - public void unregisterWebSocket(AutoCloseable webSocket) { - this.openWebSockets.remove(webSocket); - } - public Optional webSocketFactory() { return this.webSocketFactory; } @@ -234,10 +183,6 @@ public static class Builder { private boolean ownsHttpClient = true; - private AtomicBoolean closed; - - private Set openWebSockets; - private Optional logging = Optional.empty(); private Optional webSocketFactory = Optional.empty(); @@ -363,18 +308,12 @@ public ClientOptions build() { this.httpClient = httpClientBuilder.build(); this.timeout = Optional.of(httpClient.callTimeoutMillis() / 1000); - AtomicBoolean closedToUse = this.closed != null ? this.closed : new AtomicBoolean(false); - Set openWebSocketsToUse = - this.openWebSockets != null ? this.openWebSockets : ConcurrentHashMap.newKeySet(); - return new ClientOptions( environment, headers, headerSuppliers, httpClient, this.ownsHttpClient, - closedToUse, - openWebSocketsToUse, this.timeout.get(), this.maxRetries, this.initialRetryDelayMillis, @@ -393,8 +332,6 @@ public static Builder from(ClientOptions clientOptions) { builder.timeout = Optional.of(clientOptions.timeout(null)); builder.httpClient = clientOptions.httpClient(); builder.ownsHttpClient = clientOptions.ownsHttpClient; - builder.closed = clientOptions.closed; - builder.openWebSockets = clientOptions.openWebSockets; builder.headers.putAll(clientOptions.headers); builder.headerSuppliers.putAll(clientOptions.headerSuppliers); builder.maxRetries = clientOptions.maxRetries(); diff --git a/src/main/java/com/deepgram/core/OkHttpWebSocketFactory.java b/src/main/java/com/deepgram/core/OkHttpWebSocketFactory.java index 30653bc..70e6c86 100644 --- a/src/main/java/com/deepgram/core/OkHttpWebSocketFactory.java +++ b/src/main/java/com/deepgram/core/OkHttpWebSocketFactory.java @@ -3,7 +3,6 @@ */ package com.deepgram.core; -import java.util.function.BooleanSupplier; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.WebSocket; @@ -16,38 +15,17 @@ public final class OkHttpWebSocketFactory implements WebSocketFactory { private final OkHttpClient okHttpClient; - private final BooleanSupplier closedCheck; - /** * Creates a new OkHttpWebSocketFactory with the specified OkHttpClient. * * @param okHttpClient The OkHttpClient instance to use for creating WebSockets */ public OkHttpWebSocketFactory(OkHttpClient okHttpClient) { - this(okHttpClient, () -> false); - } - - /** - * Creates a new OkHttpWebSocketFactory that refuses to open WebSockets once the owning - * client has been closed. - * - * @param okHttpClient The OkHttpClient instance to use for creating WebSockets - * @param closedCheck Returns true once the owning client has been closed (e.g. - * {@code clientOptions::isClosed}) - */ - public OkHttpWebSocketFactory(OkHttpClient okHttpClient, BooleanSupplier closedCheck) { this.okHttpClient = okHttpClient; - this.closedCheck = closedCheck; } - /** - * @throws IllegalStateException if the owning client has been closed - */ @Override public WebSocket create(Request request, WebSocketListener listener) { - if (closedCheck.getAsBoolean()) { - throw new IllegalStateException("root client has been closed"); - } return okHttpClient.newWebSocket(request, listener); } } diff --git a/src/main/java/com/deepgram/core/ReconnectingWebSocketListener.java b/src/main/java/com/deepgram/core/ReconnectingWebSocketListener.java index b51aacc..c6a2ebc 100644 --- a/src/main/java/com/deepgram/core/ReconnectingWebSocketListener.java +++ b/src/main/java/com/deepgram/core/ReconnectingWebSocketListener.java @@ -14,7 +14,6 @@ import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.BooleanSupplier; import java.util.function.Consumer; import java.util.function.Supplier; import okhttp3.Response; @@ -27,7 +26,13 @@ * Provides production-ready resilience for WebSocket connections. */ public abstract class ReconnectingWebSocketListener extends WebSocketListener { - private volatile ReconnectOptions activeOptions; + private final long minReconnectionDelayMs; + + private final long maxReconnectionDelayMs; + + private final double reconnectionDelayGrowFactor; + + private final int maxRetries; private final int maxEnqueuedMessages; @@ -49,8 +54,6 @@ public abstract class ReconnectingWebSocketListener extends WebSocketListener { private final Supplier connectionSupplier; - private final BooleanSupplier closedCheck; - /** * Creates a new reconnecting WebSocket listener. * @@ -59,79 +62,45 @@ public abstract class ReconnectingWebSocketListener extends WebSocketListener { */ public ReconnectingWebSocketListener( ReconnectingWebSocketListener.ReconnectOptions options, Supplier connectionSupplier) { - this(options, connectionSupplier, () -> false); - } - - /** - * Creates a new reconnecting WebSocket listener. - * - * @param options Reconnection configuration options - * @param connectionSupplier Supplier that creates new WebSocket connections - * @param closedCheck Returns true once the owning client has been closed; connect and - * reconnect attempts made after that point fail with an {@link IllegalStateException} - * instead of being retried - */ - public ReconnectingWebSocketListener( - ReconnectingWebSocketListener.ReconnectOptions options, - Supplier connectionSupplier, - BooleanSupplier closedCheck) { - this.activeOptions = options; + this.minReconnectionDelayMs = options.minReconnectionDelayMs; + this.maxReconnectionDelayMs = options.maxReconnectionDelayMs; + this.reconnectionDelayGrowFactor = options.reconnectionDelayGrowFactor; + this.maxRetries = options.maxRetries; this.maxEnqueuedMessages = options.maxEnqueuedMessages; this.connectionSupplier = connectionSupplier; - this.closedCheck = closedCheck; - } - - /** - * Replaces option-derived reconnect settings without rebuilding generated clients. - * - * @param options replacement options; {@code null} is a no-op - */ - public void applyOptionsOverride(ReconnectOptions options) { - if (options != null) { - this.activeOptions = options; - } } /** * Initiates a WebSocket connection with automatic reconnection enabled. * * Connection behavior: - * - Times out after {@code ReconnectOptions.connectionTimeoutMs} (default 4000ms) + * - Times out after 4000 milliseconds * - Thread-safe via atomic lock (returns immediately if connection in progress) - * - {@code maxRetries} counts retries only; {@code maxRetries(0)} means connect once, do not retry + * - Retry count not incremented for initial connection attempt * * Error handling: * - TimeoutException: Includes retry attempt context * - InterruptedException: Preserves thread interruption status * - ExecutionException: Extracts actual cause and adds context - * - Owning client closed: reports an IllegalStateException once and stops reconnecting */ public void connect() { if (!connectLock.compareAndSet(false, true)) { return; } - if (closedCheck.getAsBoolean()) { - shouldReconnect.set(false); - connectLock.set(false); - onWebSocketFailure(null, new IllegalStateException("root client has been closed"), null); - return; - } - ReconnectOptions options = this.activeOptions; - if (retryCount.get() > options.maxRetries) { + if (retryCount.get() >= maxRetries) { connectLock.set(false); return; } try { CompletableFuture connectionFuture = CompletableFuture.supplyAsync(connectionSupplier); try { - webSocket = connectionFuture.get(options.connectionTimeoutMs, MILLISECONDS); + webSocket = connectionFuture.get(4000, MILLISECONDS); } catch (TimeoutException e) { connectionFuture.cancel(true); TimeoutException timeoutError = - new TimeoutException("WebSocket connection timeout after " + options.connectionTimeoutMs - + " milliseconds" + new TimeoutException("WebSocket connection timeout after " + 4000 + " milliseconds" + (retryCount.get() > 0 - ? " (retry attempt #" + retryCount.get() + ")" + ? " (retry attempt #" + retryCount.get() : " (initial connection attempt)")); onWebSocketFailure(null, timeoutError, null); if (shouldReconnect.get()) { @@ -419,24 +388,17 @@ protected boolean shouldReconnectAfterClose(WebSocket webSocket, int code, Strin */ private long getNextDelay() { if (retryCount.get() == 1) { - return activeOptions.minReconnectionDelayMs; + return minReconnectionDelayMs; } - ReconnectOptions options = this.activeOptions; - long delay = (long) - (options.minReconnectionDelayMs * Math.pow(options.reconnectionDelayGrowFactor, retryCount.get() - 1)); - return Math.min(delay, options.maxReconnectionDelayMs); + long delay = (long) (minReconnectionDelayMs * Math.pow(reconnectionDelayGrowFactor, retryCount.get() - 1)); + return Math.min(delay, maxReconnectionDelayMs); } /** * Schedules a reconnection attempt with appropriate delay. * Increments retry count and uses exponential backoff. - * Does nothing once the owning client has been closed. */ private void scheduleReconnect() { - if (closedCheck.getAsBoolean()) { - shouldReconnect.set(false); - return; - } retryCount.incrementAndGet(); long delay = getNextDelay(); reconnectExecutor.schedule(this::connect, delay, MILLISECONDS); @@ -510,15 +472,12 @@ public static final class ReconnectOptions { public final int maxEnqueuedMessages; - public final long connectionTimeoutMs; - private ReconnectOptions(Builder builder) { this.minReconnectionDelayMs = builder.minReconnectionDelayMs; this.maxReconnectionDelayMs = builder.maxReconnectionDelayMs; this.reconnectionDelayGrowFactor = builder.reconnectionDelayGrowFactor; this.maxRetries = builder.maxRetries; this.maxEnqueuedMessages = builder.maxEnqueuedMessages; - this.connectionTimeoutMs = builder.connectionTimeoutMs; } public static Builder builder() { @@ -536,15 +495,12 @@ public static final class Builder { private int maxEnqueuedMessages; - private long connectionTimeoutMs; - public Builder() { this.minReconnectionDelayMs = 1000; this.maxReconnectionDelayMs = 10000; this.reconnectionDelayGrowFactor = 1.3; this.maxRetries = 2147483647; this.maxEnqueuedMessages = 1000; - this.connectionTimeoutMs = 4000; } public Builder minReconnectionDelayMs(long minReconnectionDelayMs) { @@ -572,14 +528,6 @@ public Builder maxEnqueuedMessages(int maxEnqueuedMessages) { return this; } - /** - * Sets the per-attempt connection timeout in milliseconds. Defaults to {@code 4000}. - */ - public Builder connectionTimeoutMs(long connectionTimeoutMs) { - this.connectionTimeoutMs = connectionTimeoutMs; - return this; - } - /** * Builds the ReconnectOptions with validation. * @@ -612,9 +560,6 @@ public ReconnectOptions build() { if (maxEnqueuedMessages < 0) { throw new IllegalArgumentException("maxEnqueuedMessages must be non-negative"); } - if (connectionTimeoutMs <= 0) { - throw new IllegalArgumentException("connectionTimeoutMs must be positive"); - } return new ReconnectOptions(this); } } diff --git a/src/main/java/com/deepgram/core/RetryInterceptor.java b/src/main/java/com/deepgram/core/RetryInterceptor.java index aad032c..a0959bb 100644 --- a/src/main/java/com/deepgram/core/RetryInterceptor.java +++ b/src/main/java/com/deepgram/core/RetryInterceptor.java @@ -10,13 +10,9 @@ import java.time.format.DateTimeParseException; import java.util.Optional; import java.util.Random; -import okhttp3.Call; import okhttp3.Interceptor; import okhttp3.Request; import okhttp3.Response; -import okhttp3.ResponseBody; -import okio.AsyncTimeout; -import okio.Timeout; public class RetryInterceptor implements Interceptor { @@ -82,28 +78,13 @@ private Response retryChain(Response response, Chain chain, int maxRetries) thro ExponentialBackoff backoff = new ExponentialBackoff(maxRetries); Optional nextBackoff = backoff.nextBackoff(response); while (nextBackoff.isPresent()) { - response = bufferResponse(response); - Optional callTimeout = suspendCallTimeout(chain); try { Thread.sleep(nextBackoff.get().toMillis()); } catch (InterruptedException e) { - response.close(); throw new IOException("Interrupted while trying request", e); - } finally { - callTimeout.ifPresent(AsyncTimeout::enter); - } - Response nextResponse; - try { - nextResponse = chain.proceed(chain.request()); - } catch (IOException e) { - // A retry attempt failed with a transport error (connection reset, unreachable host, ...). The - // error is intentionally dropped: the response already received from the API is more actionable. - // Note that a call-timeout expiry or an explicit cancel() also ends up here, but OkHttp then - // discards whatever the interceptor chain returns and reports the cancellation itself. - return response; } response.close(); - response = nextResponse; + response = chain.proceed(chain.request()); if (shouldRetry(response.code())) { nextBackoff = backoff.nextBackoff(response); } else { @@ -114,51 +95,6 @@ private Response retryChain(Response response, Chain chain, int maxRetries) thro return response; } - /** - * Pauses the OkHttp call timeout so that it applies to each attempt individually rather than to the whole - * retry loop: the backoff wait (e.g. a {@code Retry-After} the size of the call timeout) does not consume the - * budget of the next attempt, and each attempt starts with a fresh budget once {@link AsyncTimeout#enter()} - * is called again. - * - *

{@link AsyncTimeout#exit()} and {@link AsyncTimeout#enter()} must stay strictly paired: {@code exit()} on - * a timeout that is not armed is a no-op, but {@code enter()} on one that is already armed throws - * {@code IllegalStateException}. Every caller must re-enter the returned timeout exactly once, on all paths. - */ - private static Optional suspendCallTimeout(Chain chain) { - Call call = chain.call(); - if (call == null) { - return Optional.empty(); - } - Timeout timeout = call.timeout(); - if (!(timeout instanceof AsyncTimeout)) { - return Optional.empty(); - } - AsyncTimeout callTimeout = (AsyncTimeout) timeout; - callTimeout.exit(); - return Optional.of(callTimeout); - } - - /** - * Reads the body into memory so the response stays usable after the underlying connection - * is released or cancelled by a later attempt. - */ - private static Response bufferResponse(Response response) { - ResponseBody body = response.body(); - if (body == null) { - return response; - } - try { - byte[] bytes = body.bytes(); - Response buffered = response.newBuilder() - .body(ResponseBody.create(bytes, body.contentType())) - .build(); - response.close(); - return buffered; - } catch (IOException e) { - return response; - } - } - /** * Calculates the retry delay from response headers, with fallback to exponential backoff. * Priority: Retry-After > X-RateLimit-Reset > Exponential Backoff diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1AgentAudioDone.java b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1AgentAudioDone.java index 5962f4b..71825ed 100644 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1AgentAudioDone.java +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1AgentAudioDone.java @@ -36,11 +36,6 @@ public boolean equals(Object other) { return other instanceof AgentV1AgentAudioDone; } - @java.lang.Override - public int hashCode() { - return getClass().hashCode(); - } - @JsonAnyGetter public Map getAdditionalProperties() { return this.additionalProperties; diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1CustomFromThinkProvider.java b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1CustomFromThinkProvider.java deleted file mode 100644 index 777078c..0000000 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1CustomFromThinkProvider.java +++ /dev/null @@ -1,125 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.resources.agent.v1.types; - -import com.deepgram.core.ObjectMappers; -import com.fasterxml.jackson.annotation.JsonAnyGetter; -import com.fasterxml.jackson.annotation.JsonAnySetter; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonSetter; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -@JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = AgentV1CustomFromThinkProvider.Builder.class) -public final class AgentV1CustomFromThinkProvider { - private final Object content; - - private final Map additionalProperties; - - private AgentV1CustomFromThinkProvider(Object content, Map additionalProperties) { - this.content = content; - this.additionalProperties = additionalProperties; - } - - /** - * @return Message type identifier for a custom payload returned by the think provider - */ - @JsonProperty("type") - public String getType() { - return "__customFromThinkProvider"; - } - - @JsonProperty("content") - public Object getContent() { - return content; - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof AgentV1CustomFromThinkProvider && equalTo((AgentV1CustomFromThinkProvider) other); - } - - @JsonAnyGetter - public Map getAdditionalProperties() { - return this.additionalProperties; - } - - private boolean equalTo(AgentV1CustomFromThinkProvider other) { - return content.equals(other.content); - } - - @java.lang.Override - public int hashCode() { - return Objects.hash(this.content); - } - - @java.lang.Override - public String toString() { - return ObjectMappers.stringify(this); - } - - public static ContentStage builder() { - return new Builder(); - } - - public interface ContentStage { - _FinalStage content(Object content); - - Builder from(AgentV1CustomFromThinkProvider other); - } - - public interface _FinalStage { - AgentV1CustomFromThinkProvider build(); - - _FinalStage additionalProperty(String key, Object value); - - _FinalStage additionalProperties(Map additionalProperties); - } - - @JsonIgnoreProperties(ignoreUnknown = true) - public static final class Builder implements ContentStage, _FinalStage { - private Object content; - - @JsonAnySetter - private Map additionalProperties = new HashMap<>(); - - private Builder() {} - - @java.lang.Override - public Builder from(AgentV1CustomFromThinkProvider other) { - content(other.getContent()); - return this; - } - - @java.lang.Override - @JsonSetter("content") - public _FinalStage content(Object content) { - this.content = content; - return this; - } - - @java.lang.Override - public AgentV1CustomFromThinkProvider build() { - return new AgentV1CustomFromThinkProvider(content, additionalProperties); - } - - @java.lang.Override - public Builder additionalProperty(String key, Object value) { - this.additionalProperties.put(key, value); - return this; - } - - @java.lang.Override - public Builder additionalProperties(Map additionalProperties) { - this.additionalProperties.putAll(additionalProperties); - return this; - } - } -} diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1CustomToThinkProvider.java b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1CustomToThinkProvider.java deleted file mode 100644 index 5dc5b4b..0000000 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1CustomToThinkProvider.java +++ /dev/null @@ -1,125 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.resources.agent.v1.types; - -import com.deepgram.core.ObjectMappers; -import com.fasterxml.jackson.annotation.JsonAnyGetter; -import com.fasterxml.jackson.annotation.JsonAnySetter; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonSetter; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -@JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = AgentV1CustomToThinkProvider.Builder.class) -public final class AgentV1CustomToThinkProvider { - private final Object content; - - private final Map additionalProperties; - - private AgentV1CustomToThinkProvider(Object content, Map additionalProperties) { - this.content = content; - this.additionalProperties = additionalProperties; - } - - /** - * @return Message type identifier for sending a custom payload to the think provider - */ - @JsonProperty("type") - public String getType() { - return "__customToThinkProvider"; - } - - @JsonProperty("content") - public Object getContent() { - return content; - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof AgentV1CustomToThinkProvider && equalTo((AgentV1CustomToThinkProvider) other); - } - - @JsonAnyGetter - public Map getAdditionalProperties() { - return this.additionalProperties; - } - - private boolean equalTo(AgentV1CustomToThinkProvider other) { - return content.equals(other.content); - } - - @java.lang.Override - public int hashCode() { - return Objects.hash(this.content); - } - - @java.lang.Override - public String toString() { - return ObjectMappers.stringify(this); - } - - public static ContentStage builder() { - return new Builder(); - } - - public interface ContentStage { - _FinalStage content(Object content); - - Builder from(AgentV1CustomToThinkProvider other); - } - - public interface _FinalStage { - AgentV1CustomToThinkProvider build(); - - _FinalStage additionalProperty(String key, Object value); - - _FinalStage additionalProperties(Map additionalProperties); - } - - @JsonIgnoreProperties(ignoreUnknown = true) - public static final class Builder implements ContentStage, _FinalStage { - private Object content; - - @JsonAnySetter - private Map additionalProperties = new HashMap<>(); - - private Builder() {} - - @java.lang.Override - public Builder from(AgentV1CustomToThinkProvider other) { - content(other.getContent()); - return this; - } - - @java.lang.Override - @JsonSetter("content") - public _FinalStage content(Object content) { - this.content = content; - return this; - } - - @java.lang.Override - public AgentV1CustomToThinkProvider build() { - return new AgentV1CustomToThinkProvider(content, additionalProperties); - } - - @java.lang.Override - public Builder additionalProperty(String key, Object value) { - this.additionalProperties.put(key, value); - return this; - } - - @java.lang.Override - public Builder additionalProperties(Map additionalProperties) { - this.additionalProperties.putAll(additionalProperties); - return this; - } - } -} diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ForceEndTurn.java b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ForceEndTurn.java index 9bd5f76..1672d2d 100644 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ForceEndTurn.java +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ForceEndTurn.java @@ -36,11 +36,6 @@ public boolean equals(Object other) { return other instanceof AgentV1ForceEndTurn; } - @java.lang.Override - public int hashCode() { - return getClass().hashCode(); - } - @JsonAnyGetter public Map getAdditionalProperties() { return this.additionalProperties; diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1KeepAlive.java b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1KeepAlive.java index f82f59e..7842266 100644 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1KeepAlive.java +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1KeepAlive.java @@ -36,11 +36,6 @@ public boolean equals(Object other) { return other instanceof AgentV1KeepAlive; } - @java.lang.Override - public int hashCode() { - return getClass().hashCode(); - } - @JsonAnyGetter public Map getAdditionalProperties() { return this.additionalProperties; diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ListenUpdated.java b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ListenUpdated.java index 43b8628..65878c9 100644 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ListenUpdated.java +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ListenUpdated.java @@ -36,11 +36,6 @@ public boolean equals(Object other) { return other instanceof AgentV1ListenUpdated; } - @java.lang.Override - public int hashCode() { - return getClass().hashCode(); - } - @JsonAnyGetter public Map getAdditionalProperties() { return this.additionalProperties; diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1PromptUpdated.java b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1PromptUpdated.java index e6efced..68d71cc 100644 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1PromptUpdated.java +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1PromptUpdated.java @@ -36,11 +36,6 @@ public boolean equals(Object other) { return other instanceof AgentV1PromptUpdated; } - @java.lang.Override - public int hashCode() { - return getClass().hashCode(); - } - @JsonAnyGetter public Map getAdditionalProperties() { return this.additionalProperties; diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentContextListenProvider.java b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentContextListenProvider.java index 393f1f9..eea1585 100644 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentContextListenProvider.java +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentContextListenProvider.java @@ -99,7 +99,7 @@ public interface Visitor { T _visitUnknown(Object unknownType); } - @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "version", visible = true, defaultImpl = V2Value.class) + @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "version", visible = true, defaultImpl = _UnknownValue.class) @JsonSubTypes({@JsonSubTypes.Type(V1Value.class), @JsonSubTypes.Type(V2Value.class)}) @JsonIgnoreProperties(ignoreUnknown = true) private interface Value { diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentListenProvider.java b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentListenProvider.java index 345ba2f..4309ec0 100644 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentListenProvider.java +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentListenProvider.java @@ -99,7 +99,7 @@ public interface Visitor { T _visitUnknown(Object unknownType); } - @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "version", visible = true, defaultImpl = V2Value.class) + @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "version", visible = true, defaultImpl = _UnknownValue.class) @JsonSubTypes({@JsonSubTypes.Type(V1Value.class), @JsonSubTypes.Type(V2Value.class)}) @JsonIgnoreProperties(ignoreUnknown = true) private interface Value { diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsApplied.java b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsApplied.java index ad1fdb2..0d60b72 100644 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsApplied.java +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsApplied.java @@ -36,11 +36,6 @@ public boolean equals(Object other) { return other instanceof AgentV1SettingsApplied; } - @java.lang.Override - public int hashCode() { - return getClass().hashCode(); - } - @JsonAnyGetter public Map getAdditionalProperties() { return this.additionalProperties; diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SpeakUpdated.java b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SpeakUpdated.java index 8b134b5..747aa9d 100644 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SpeakUpdated.java +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SpeakUpdated.java @@ -36,11 +36,6 @@ public boolean equals(Object other) { return other instanceof AgentV1SpeakUpdated; } - @java.lang.Override - public int hashCode() { - return getClass().hashCode(); - } - @JsonAnyGetter public Map getAdditionalProperties() { return this.additionalProperties; diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ThinkUpdated.java b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ThinkUpdated.java index 2d67cad..5668a71 100644 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ThinkUpdated.java +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ThinkUpdated.java @@ -36,11 +36,6 @@ public boolean equals(Object other) { return other instanceof AgentV1ThinkUpdated; } - @java.lang.Override - public int hashCode() { - return getClass().hashCode(); - } - @JsonAnyGetter public Map getAdditionalProperties() { return this.additionalProperties; diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UpdateListenListenProvider.java b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UpdateListenListenProvider.java index e739aec..e693a04 100644 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UpdateListenListenProvider.java +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UpdateListenListenProvider.java @@ -99,7 +99,7 @@ public interface Visitor { T _visitUnknown(Object unknownType); } - @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "version", visible = true, defaultImpl = V2Value.class) + @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "version", visible = true, defaultImpl = _UnknownValue.class) @JsonSubTypes({@JsonSubTypes.Type(V1Value.class), @JsonSubTypes.Type(V2Value.class)}) @JsonIgnoreProperties(ignoreUnknown = true) private interface Value { diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UserStartedSpeaking.java b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UserStartedSpeaking.java index 3556d31..edb80f8 100644 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UserStartedSpeaking.java +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UserStartedSpeaking.java @@ -36,11 +36,6 @@ public boolean equals(Object other) { return other instanceof AgentV1UserStartedSpeaking; } - @java.lang.Override - public int hashCode() { - return getClass().hashCode(); - } - @JsonAnyGetter public Map getAdditionalProperties() { return this.additionalProperties; diff --git a/src/main/java/com/deepgram/resources/agent/v1/websocket/V1WebSocketClient.java b/src/main/java/com/deepgram/resources/agent/v1/websocket/V1WebSocketClient.java index 1aa1b9d..1a5c224 100644 --- a/src/main/java/com/deepgram/resources/agent/v1/websocket/V1WebSocketClient.java +++ b/src/main/java/com/deepgram/resources/agent/v1/websocket/V1WebSocketClient.java @@ -13,8 +13,6 @@ import com.deepgram.resources.agent.v1.types.AgentV1AgentStartedSpeaking; import com.deepgram.resources.agent.v1.types.AgentV1AgentThinking; import com.deepgram.resources.agent.v1.types.AgentV1ConversationText; -import com.deepgram.resources.agent.v1.types.AgentV1CustomFromThinkProvider; -import com.deepgram.resources.agent.v1.types.AgentV1CustomToThinkProvider; import com.deepgram.resources.agent.v1.types.AgentV1Error; import com.deepgram.resources.agent.v1.types.AgentV1ForceEndTurn; import com.deepgram.resources.agent.v1.types.AgentV1FunctionCallCancelled; @@ -113,8 +111,6 @@ public class V1WebSocketClient implements AutoCloseable { private volatile Consumer agentAudioDoneHandler; - private volatile Consumer customFromThinkProviderHandler; - private volatile Consumer errorHandler; private volatile Consumer warningHandler; @@ -164,22 +160,13 @@ public CompletableFuture connect() { ? this.reconnectOptions : ReconnectingWebSocketListener.ReconnectOptions.builder().build(); this.reconnectingListener = - new ReconnectingWebSocketListener( - reconnectOpts, - () -> { - if (clientOptions.isClosed()) { - throw new IllegalStateException("root client has been closed"); - } - if (clientOptions.webSocketFactory().isPresent()) { - return clientOptions - .webSocketFactory() - .get() - .create(request, this.reconnectingListener); - } else { - return okHttpClient.newWebSocket(request, this.reconnectingListener); - } - }, - clientOptions::isClosed) { + new ReconnectingWebSocketListener(reconnectOpts, () -> { + if (clientOptions.webSocketFactory().isPresent()) { + return clientOptions.webSocketFactory().get().create(request, this.reconnectingListener); + } else { + return okHttpClient.newWebSocket(request, this.reconnectingListener); + } + }) { @Override protected void onWebSocketOpen(WebSocket webSocket, Response response) { readyState = WebSocketReadyState.OPEN; @@ -218,7 +205,6 @@ protected void onWebSocketClosed(WebSocket webSocket, int code, String reason) { } } }; - clientOptions.registerWebSocket(this); reconnectingListener.connect(); return connectionFuture; } @@ -227,10 +213,7 @@ protected void onWebSocketClosed(WebSocket webSocket, int code, String reason) { * Disconnects the WebSocket connection and releases resources. */ public void disconnect() { - clientOptions.unregisterWebSocket(this); - if (reconnectingListener != null) { - reconnectingListener.disconnect(); - } + reconnectingListener.disconnect(); if (timeoutExecutor != null) { timeoutExecutor.shutdownNow(); timeoutExecutor = null; @@ -338,15 +321,6 @@ public CompletableFuture sendForceEndTurn(AgentV1ForceEndTurn message) { return sendMessage(message); } - /** - * Sends an AgentV1CustomToThinkProvider message to the server asynchronously. - * @param message the message to send - * @return a CompletableFuture that completes when the message is sent - */ - public CompletableFuture sendCustomToThinkProvider(AgentV1CustomToThinkProvider message) { - return sendMessage(message); - } - /** * Sends an AgentV1Media message to the server asynchronously. * @param message the message to send @@ -493,14 +467,6 @@ public void onAgentAudioDone(Consumer handler) { this.agentAudioDoneHandler = handler; } - /** - * Registers a handler for AgentV1CustomFromThinkProvider messages from the server. - * @param handler the handler to invoke when a message is received - */ - public void onCustomFromThinkProvider(Consumer handler) { - this.customFromThinkProviderHandler = handler; - } - /** * Registers a handler for AgentV1Error messages from the server. * @param handler the handler to invoke when a message is received @@ -769,21 +735,6 @@ private void handleIncomingMessage(String json) { return; } } - if (node.has("content") - && "__customFromThinkProvider".equals(node.path("type").asText())) { - AgentV1CustomFromThinkProvider customFromThinkProviderHandlerEvent = null; - try { - customFromThinkProviderHandlerEvent = - objectMapper.treeToValue(node, AgentV1CustomFromThinkProvider.class); - } catch (Exception e) { - } - if (customFromThinkProviderHandlerEvent != null) { - if (customFromThinkProviderHandler != null) { - customFromThinkProviderHandler.accept(customFromThinkProviderHandlerEvent); - } - return; - } - } if ("ListenUpdated".equals(node.path("type").asText())) { AgentV1ListenUpdated listenUpdatedHandlerEvent = null; try { diff --git a/src/main/java/com/deepgram/resources/listen/v1/types/ListenV1Configure.java b/src/main/java/com/deepgram/resources/listen/v1/types/ListenV1Configure.java deleted file mode 100644 index 967d27e..0000000 --- a/src/main/java/com/deepgram/resources/listen/v1/types/ListenV1Configure.java +++ /dev/null @@ -1,165 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.resources.listen.v1.types; - -import com.deepgram.core.ObjectMappers; -import com.fasterxml.jackson.annotation.JsonAnyGetter; -import com.fasterxml.jackson.annotation.JsonAnySetter; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonSetter; -import com.fasterxml.jackson.annotation.Nulls; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; - -@JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = ListenV1Configure.Builder.class) -public final class ListenV1Configure { - private final Optional> keyterms; - - private final Optional> features; - - private final Map additionalProperties; - - private ListenV1Configure( - Optional> keyterms, - Optional> features, - Map additionalProperties) { - this.keyterms = keyterms; - this.features = features; - this.additionalProperties = additionalProperties; - } - - /** - * @return Message type identifier - */ - @JsonProperty("type") - public String getType() { - return "Configure"; - } - - /** - * @return Replaces the stream's keyterms. Compatible with all Nova-3 models, monolingual and multilingual; on other - * models the server returns an Error with code KeytermsNotSupported. Each array replaces the entire list, - * including keyterms set with the keyterm query parameter. Send an empty array to clear all keyterms. Omit - * the field, or set it to null, to keep the current keyterms. - *

Each entry is a plain term or phrase with no weights or intensifiers. The 500-token keyterm limit that - * applies to the keyterm query parameter also applies to each update. An over-limit update returns an - * Error, and the stream keeps its previous keyterms.

- */ - @JsonProperty("keyterms") - public Optional> getKeyterms() { - return keyterms; - } - - /** - * @return Turns formatting features on or off. Each key is a feature name and each value is a boolean, for - * example {"numerals": true}. - */ - @JsonProperty("features") - public Optional> getFeatures() { - return features; - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof ListenV1Configure && equalTo((ListenV1Configure) other); - } - - @JsonAnyGetter - public Map getAdditionalProperties() { - return this.additionalProperties; - } - - private boolean equalTo(ListenV1Configure other) { - return keyterms.equals(other.keyterms) && features.equals(other.features); - } - - @java.lang.Override - public int hashCode() { - return Objects.hash(this.keyterms, this.features); - } - - @java.lang.Override - public String toString() { - return ObjectMappers.stringify(this); - } - - public static Builder builder() { - return new Builder(); - } - - @JsonIgnoreProperties(ignoreUnknown = true) - public static final class Builder { - private Optional> keyterms = Optional.empty(); - - private Optional> features = Optional.empty(); - - @JsonAnySetter - private Map additionalProperties = new HashMap<>(); - - private Builder() {} - - public Builder from(ListenV1Configure other) { - keyterms(other.getKeyterms()); - features(other.getFeatures()); - return this; - } - - /** - *

Replaces the stream's keyterms. Compatible with all Nova-3 models, monolingual and multilingual; on other - * models the server returns an Error with code KeytermsNotSupported. Each array replaces the entire list, - * including keyterms set with the keyterm query parameter. Send an empty array to clear all keyterms. Omit - * the field, or set it to null, to keep the current keyterms.

- *

Each entry is a plain term or phrase with no weights or intensifiers. The 500-token keyterm limit that - * applies to the keyterm query parameter also applies to each update. An over-limit update returns an - * Error, and the stream keeps its previous keyterms.

- */ - @JsonSetter(value = "keyterms", nulls = Nulls.SKIP) - public Builder keyterms(Optional> keyterms) { - this.keyterms = keyterms; - return this; - } - - public Builder keyterms(List keyterms) { - this.keyterms = Optional.ofNullable(keyterms); - return this; - } - - /** - *

Turns formatting features on or off. Each key is a feature name and each value is a boolean, for - * example {"numerals": true}.

- */ - @JsonSetter(value = "features", nulls = Nulls.SKIP) - public Builder features(Optional> features) { - this.features = features; - return this; - } - - public Builder features(Map features) { - this.features = Optional.ofNullable(features); - return this; - } - - public ListenV1Configure build() { - return new ListenV1Configure(keyterms, features, additionalProperties); - } - - public Builder additionalProperty(String key, Object value) { - this.additionalProperties.put(key, value); - return this; - } - - public Builder additionalProperties(Map additionalProperties) { - this.additionalProperties.putAll(additionalProperties); - return this; - } - } -} diff --git a/src/main/java/com/deepgram/resources/listen/v1/types/ListenV1Error.java b/src/main/java/com/deepgram/resources/listen/v1/types/ListenV1Error.java deleted file mode 100644 index fd0a4e0..0000000 --- a/src/main/java/com/deepgram/resources/listen/v1/types/ListenV1Error.java +++ /dev/null @@ -1,267 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.resources.listen.v1.types; - -import com.deepgram.core.ObjectMappers; -import com.fasterxml.jackson.annotation.JsonAnyGetter; -import com.fasterxml.jackson.annotation.JsonAnySetter; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonSetter; -import com.fasterxml.jackson.annotation.Nulls; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import org.jetbrains.annotations.NotNull; - -@JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = ListenV1Error.Builder.class) -public final class ListenV1Error { - private final String variant; - - private final String description; - - private final Optional code; - - private final Optional message; - - private final Map additionalProperties; - - private ListenV1Error( - String variant, - String description, - Optional code, - Optional message, - Map additionalProperties) { - this.variant = variant; - this.description = description; - this.code = code; - this.message = message; - this.additionalProperties = additionalProperties; - } - - /** - * @return Message type identifier for error responses - */ - @JsonProperty("type") - public String getType() { - return "Error"; - } - - /** - * @return The error category. SchemaError means the server could not parse a client text message. - * InvalidConfigureMessage means the server rejected a Configure message. - */ - @JsonProperty("variant") - public String getVariant() { - return variant; - } - - /** - * @return A human-readable description of what went wrong - */ - @JsonProperty("description") - public String getDescription() { - return description; - } - - /** - * @return Identifies the reason for an InvalidConfigureMessage error, for example KeytermsNotSupported - * when keyterms are sent on a model other than Nova-3. - */ - @JsonProperty("code") - public Optional getCode() { - return code; - } - - /** - * @return For SchemaError, the original client message that could not be parsed - */ - @JsonProperty("message") - public Optional getMessage() { - return message; - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof ListenV1Error && equalTo((ListenV1Error) other); - } - - @JsonAnyGetter - public Map getAdditionalProperties() { - return this.additionalProperties; - } - - private boolean equalTo(ListenV1Error other) { - return variant.equals(other.variant) - && description.equals(other.description) - && code.equals(other.code) - && message.equals(other.message); - } - - @java.lang.Override - public int hashCode() { - return Objects.hash(this.variant, this.description, this.code, this.message); - } - - @java.lang.Override - public String toString() { - return ObjectMappers.stringify(this); - } - - public static VariantStage builder() { - return new Builder(); - } - - public interface VariantStage { - /** - *

The error category. SchemaError means the server could not parse a client text message. - * InvalidConfigureMessage means the server rejected a Configure message.

- */ - DescriptionStage variant(@NotNull String variant); - - Builder from(ListenV1Error other); - } - - public interface DescriptionStage { - /** - *

A human-readable description of what went wrong

- */ - _FinalStage description(@NotNull String description); - } - - public interface _FinalStage { - ListenV1Error build(); - - _FinalStage additionalProperty(String key, Object value); - - _FinalStage additionalProperties(Map additionalProperties); - - /** - *

Identifies the reason for an InvalidConfigureMessage error, for example KeytermsNotSupported - * when keyterms are sent on a model other than Nova-3.

- */ - _FinalStage code(Optional code); - - _FinalStage code(String code); - - /** - *

For SchemaError, the original client message that could not be parsed

- */ - _FinalStage message(Optional message); - - _FinalStage message(String message); - } - - @JsonIgnoreProperties(ignoreUnknown = true) - public static final class Builder implements VariantStage, DescriptionStage, _FinalStage { - private String variant; - - private String description; - - private Optional message = Optional.empty(); - - private Optional code = Optional.empty(); - - @JsonAnySetter - private Map additionalProperties = new HashMap<>(); - - private Builder() {} - - @java.lang.Override - public Builder from(ListenV1Error other) { - variant(other.getVariant()); - description(other.getDescription()); - code(other.getCode()); - message(other.getMessage()); - return this; - } - - /** - *

The error category. SchemaError means the server could not parse a client text message. - * InvalidConfigureMessage means the server rejected a Configure message.

- * @return Reference to {@code this} so that method calls can be chained together. - */ - @java.lang.Override - @JsonSetter("variant") - public DescriptionStage variant(@NotNull String variant) { - this.variant = Objects.requireNonNull(variant, "variant must not be null"); - return this; - } - - /** - *

A human-readable description of what went wrong

- * @return Reference to {@code this} so that method calls can be chained together. - */ - @java.lang.Override - @JsonSetter("description") - public _FinalStage description(@NotNull String description) { - this.description = Objects.requireNonNull(description, "description must not be null"); - return this; - } - - /** - *

For SchemaError, the original client message that could not be parsed

- * @return Reference to {@code this} so that method calls can be chained together. - */ - @java.lang.Override - public _FinalStage message(String message) { - this.message = Optional.ofNullable(message); - return this; - } - - /** - *

For SchemaError, the original client message that could not be parsed

- */ - @java.lang.Override - @JsonSetter(value = "message", nulls = Nulls.SKIP) - public _FinalStage message(Optional message) { - this.message = message; - return this; - } - - /** - *

Identifies the reason for an InvalidConfigureMessage error, for example KeytermsNotSupported - * when keyterms are sent on a model other than Nova-3.

- * @return Reference to {@code this} so that method calls can be chained together. - */ - @java.lang.Override - public _FinalStage code(String code) { - this.code = Optional.ofNullable(code); - return this; - } - - /** - *

Identifies the reason for an InvalidConfigureMessage error, for example KeytermsNotSupported - * when keyterms are sent on a model other than Nova-3.

- */ - @java.lang.Override - @JsonSetter(value = "code", nulls = Nulls.SKIP) - public _FinalStage code(Optional code) { - this.code = code; - return this; - } - - @java.lang.Override - public ListenV1Error build() { - return new ListenV1Error(variant, description, code, message, additionalProperties); - } - - @java.lang.Override - public Builder additionalProperty(String key, Object value) { - this.additionalProperties.put(key, value); - return this; - } - - @java.lang.Override - public Builder additionalProperties(Map additionalProperties) { - this.additionalProperties.putAll(additionalProperties); - return this; - } - } -} diff --git a/src/main/java/com/deepgram/resources/listen/v1/websocket/V1WebSocketClient.java b/src/main/java/com/deepgram/resources/listen/v1/websocket/V1WebSocketClient.java index e7cd50c..4952808 100644 --- a/src/main/java/com/deepgram/resources/listen/v1/websocket/V1WebSocketClient.java +++ b/src/main/java/com/deepgram/resources/listen/v1/websocket/V1WebSocketClient.java @@ -6,13 +6,10 @@ import com.deepgram.core.ClientOptions; import com.deepgram.core.DisconnectReason; import com.deepgram.core.ObjectMappers; -import com.deepgram.core.QueryStringMapper; import com.deepgram.core.ReconnectingWebSocketListener; import com.deepgram.core.RequestOptions; import com.deepgram.core.WebSocketReadyState; import com.deepgram.resources.listen.v1.types.ListenV1CloseStream; -import com.deepgram.resources.listen.v1.types.ListenV1Configure; -import com.deepgram.resources.listen.v1.types.ListenV1Error; import com.deepgram.resources.listen.v1.types.ListenV1Finalize; import com.deepgram.resources.listen.v1.types.ListenV1KeepAlive; import com.deepgram.resources.listen.v1.types.ListenV1Metadata; @@ -68,8 +65,6 @@ public class V1WebSocketClient implements AutoCloseable { private volatile Consumer speechStartedHandler; - private volatile Consumer errorHandler; - /** * Creates a new async WebSocket client for the v1 channel. */ @@ -143,7 +138,8 @@ public CompletableFuture connect(V1ConnectOptions options) { "endpointing", String.valueOf(options.getEndpointing().get())); } if (options.getExtra() != null && options.getExtra().isPresent()) { - QueryStringMapper.addQueryParameter(urlBuilder, "extra", options.getExtra().get().get(), true); + urlBuilder.addQueryParameter( + "extra", String.valueOf(options.getExtra().get())); } if (options.getInterimResults() != null && options.getInterimResults().isPresent()) { urlBuilder.addQueryParameter( @@ -151,10 +147,12 @@ public CompletableFuture connect(V1ConnectOptions options) { String.valueOf(options.getInterimResults().get())); } if (options.getKeyterm() != null && options.getKeyterm().isPresent()) { - QueryStringMapper.addQueryParameter(urlBuilder, "keyterm", options.getKeyterm().get().get(), true); + urlBuilder.addQueryParameter( + "keyterm", String.valueOf(options.getKeyterm().get())); } if (options.getKeywords() != null && options.getKeywords().isPresent()) { - QueryStringMapper.addQueryParameter(urlBuilder, "keywords", options.getKeywords().get().get(), true); + urlBuilder.addQueryParameter( + "keywords", String.valueOf(options.getKeywords().get())); } if (options.getLanguage() != null && options.getLanguage().isPresent()) { urlBuilder.addQueryParameter( @@ -187,21 +185,23 @@ public CompletableFuture connect(V1ConnectOptions options) { "redact", String.valueOf(options.getRedact().get())); } if (options.getReplace() != null && options.getReplace().isPresent()) { - QueryStringMapper.addQueryParameter(urlBuilder, "replace", options.getReplace().get().get(), true); + urlBuilder.addQueryParameter( + "replace", String.valueOf(options.getReplace().get())); } if (options.getSampleRate() != null && options.getSampleRate().isPresent()) { urlBuilder.addQueryParameter( "sample_rate", String.valueOf(options.getSampleRate().get())); } if (options.getSearch() != null && options.getSearch().isPresent()) { - QueryStringMapper.addQueryParameter(urlBuilder, "search", options.getSearch().get().get(), true); + urlBuilder.addQueryParameter( + "search", String.valueOf(options.getSearch().get())); } if (options.getSmartFormat() != null && options.getSmartFormat().isPresent()) { urlBuilder.addQueryParameter( "smart_format", String.valueOf(options.getSmartFormat().get())); } if (options.getTag() != null && options.getTag().isPresent()) { - QueryStringMapper.addQueryParameter(urlBuilder, "tag", options.getTag().get().get(), true); + urlBuilder.addQueryParameter("tag", String.valueOf(options.getTag().get())); } if (options.getUtteranceEndMs() != null && options.getUtteranceEndMs().isPresent()) { urlBuilder.addQueryParameter( @@ -216,13 +216,6 @@ public CompletableFuture connect(V1ConnectOptions options) { urlBuilder.addQueryParameter( "version", String.valueOf(options.getVersion().get())); } - if (options.getAdditionalProperties() != null) { - options.getAdditionalProperties().forEach((key, value) -> { - if (value != null) { - QueryStringMapper.addQueryParameter(urlBuilder, key, value, true); - } - }); - } Request.Builder requestBuilder = new Request.Builder().url(urlBuilder.build()); clientOptions.headers((RequestOptions) null).forEach(requestBuilder::addHeader); final Request request = requestBuilder.build(); @@ -231,22 +224,13 @@ public CompletableFuture connect(V1ConnectOptions options) { ? this.reconnectOptions : ReconnectingWebSocketListener.ReconnectOptions.builder().build(); this.reconnectingListener = - new ReconnectingWebSocketListener( - reconnectOpts, - () -> { - if (clientOptions.isClosed()) { - throw new IllegalStateException("root client has been closed"); - } - if (clientOptions.webSocketFactory().isPresent()) { - return clientOptions - .webSocketFactory() - .get() - .create(request, this.reconnectingListener); - } else { - return okHttpClient.newWebSocket(request, this.reconnectingListener); - } - }, - clientOptions::isClosed) { + new ReconnectingWebSocketListener(reconnectOpts, () -> { + if (clientOptions.webSocketFactory().isPresent()) { + return clientOptions.webSocketFactory().get().create(request, this.reconnectingListener); + } else { + return okHttpClient.newWebSocket(request, this.reconnectingListener); + } + }) { @Override protected void onWebSocketOpen(WebSocket webSocket, Response response) { readyState = WebSocketReadyState.OPEN; @@ -281,7 +265,6 @@ protected void onWebSocketClosed(WebSocket webSocket, int code, String reason) { } } }; - clientOptions.registerWebSocket(this); reconnectingListener.connect(); return connectionFuture; } @@ -290,10 +273,7 @@ protected void onWebSocketClosed(WebSocket webSocket, int code, String reason) { * Disconnects the WebSocket connection and releases resources. */ public void disconnect() { - clientOptions.unregisterWebSocket(this); - if (reconnectingListener != null) { - reconnectingListener.disconnect(); - } + reconnectingListener.disconnect(); if (timeoutExecutor != null) { timeoutExecutor.shutdownNow(); timeoutExecutor = null; @@ -356,15 +336,6 @@ public CompletableFuture sendKeepAlive(ListenV1KeepAlive message) { return sendMessage(message); } - /** - * Sends a ListenV1Configure message to the server asynchronously. - * @param message the message to send - * @return a CompletableFuture that completes when the message is sent - */ - public CompletableFuture sendConfigure(ListenV1Configure message) { - return sendMessage(message); - } - /** * Registers a handler for ListenV1Results messages from the server. * @param handler the handler to invoke when a message is received @@ -397,14 +368,6 @@ public void onSpeechStarted(Consumer handler) { this.speechStartedHandler = handler; } - /** - * Registers a handler for ListenV1Error messages from the server. - * @param handler the handler to invoke when a message is received - */ - public void onErrorMessage(Consumer handler) { - this.errorHandler = handler; - } - /** * Registers a handler called when the connection is established. * @param handler the handler to invoke when connected @@ -561,23 +524,6 @@ private void handleIncomingMessage(String json) { return; } } - if (node.has("variant") - && node.has("description") - && "Error".equals(node.path("type").asText())) { - ListenV1Error errorHandlerEvent = null; - try { - errorHandlerEvent = objectMapper.treeToValue(node, ListenV1Error.class); - } catch (Exception e) { - } - if (errorHandlerEvent != null) { - if (errorHandler != null) { - errorHandler.accept(errorHandlerEvent); - } else if (onErrorHandler != null) { - onErrorHandler.accept(new ListenV1ErrorException(errorHandlerEvent)); - } - return; - } - } if (onErrorHandler != null) { onErrorHandler.accept(new RuntimeException( "Unrecognized WebSocket message: " + json.substring(0, Math.min(200, json.length())) diff --git a/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2CloseStream.java b/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2CloseStream.java index c9f2f35..e6308e2 100644 --- a/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2CloseStream.java +++ b/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2CloseStream.java @@ -36,11 +36,6 @@ public boolean equals(Object other) { return other instanceof ListenV2CloseStream; } - @java.lang.Override - public int hashCode() { - return getClass().hashCode(); - } - @JsonAnyGetter public Map getAdditionalProperties() { return this.additionalProperties; diff --git a/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ConfigureFailure.java b/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ConfigureFailure.java index a48faac..478307b 100644 --- a/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ConfigureFailure.java +++ b/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ConfigureFailure.java @@ -10,12 +10,10 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonSetter; -import com.fasterxml.jackson.annotation.Nulls; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import java.util.HashMap; import java.util.Map; import java.util.Objects; -import java.util.Optional; import org.jetbrains.annotations.NotNull; @JsonInclude(JsonInclude.Include.NON_ABSENT) @@ -25,22 +23,11 @@ public final class ListenV2ConfigureFailure { private final int sequenceId; - private final Optional code; - - private final Optional description; - private final Map additionalProperties; - private ListenV2ConfigureFailure( - String requestId, - int sequenceId, - Optional code, - Optional description, - Map additionalProperties) { + private ListenV2ConfigureFailure(String requestId, int sequenceId, Map additionalProperties) { this.requestId = requestId; this.sequenceId = sequenceId; - this.code = code; - this.description = description; this.additionalProperties = additionalProperties; } @@ -70,22 +57,6 @@ public int getSequenceId() { return sequenceId; } - /** - * @return Failure code identifying the rejected configuration - */ - @JsonProperty("code") - public Optional getCode() { - return code; - } - - /** - * @return A human-readable description of the configuration failure - */ - @JsonProperty("description") - public Optional getDescription() { - return description; - } - @java.lang.Override public boolean equals(Object other) { if (this == other) return true; @@ -98,15 +69,12 @@ public Map getAdditionalProperties() { } private boolean equalTo(ListenV2ConfigureFailure other) { - return requestId.equals(other.requestId) - && sequenceId == other.sequenceId - && code.equals(other.code) - && description.equals(other.description); + return requestId.equals(other.requestId) && sequenceId == other.sequenceId; } @java.lang.Override public int hashCode() { - return Objects.hash(this.requestId, this.sequenceId, this.code, this.description); + return Objects.hash(this.requestId, this.sequenceId); } @java.lang.Override @@ -142,20 +110,6 @@ public interface _FinalStage { _FinalStage additionalProperty(String key, Object value); _FinalStage additionalProperties(Map additionalProperties); - - /** - *

Failure code identifying the rejected configuration

- */ - _FinalStage code(Optional code); - - _FinalStage code(String code); - - /** - *

A human-readable description of the configuration failure

- */ - _FinalStage description(Optional description); - - _FinalStage description(String description); } @JsonIgnoreProperties(ignoreUnknown = true) @@ -164,10 +118,6 @@ public static final class Builder implements RequestIdStage, SequenceIdStage, _F private int sequenceId; - private Optional description = Optional.empty(); - - private Optional code = Optional.empty(); - @JsonAnySetter private Map additionalProperties = new HashMap<>(); @@ -177,8 +127,6 @@ private Builder() {} public Builder from(ListenV2ConfigureFailure other) { requestId(other.getRequestId()); sequenceId(other.getSequenceId()); - code(other.getCode()); - description(other.getDescription()); return this; } @@ -206,49 +154,9 @@ public _FinalStage sequenceId(int sequenceId) { return this; } - /** - *

A human-readable description of the configuration failure

- * @return Reference to {@code this} so that method calls can be chained together. - */ - @java.lang.Override - public _FinalStage description(String description) { - this.description = Optional.ofNullable(description); - return this; - } - - /** - *

A human-readable description of the configuration failure

- */ - @java.lang.Override - @JsonSetter(value = "description", nulls = Nulls.SKIP) - public _FinalStage description(Optional description) { - this.description = description; - return this; - } - - /** - *

Failure code identifying the rejected configuration

- * @return Reference to {@code this} so that method calls can be chained together. - */ - @java.lang.Override - public _FinalStage code(String code) { - this.code = Optional.ofNullable(code); - return this; - } - - /** - *

Failure code identifying the rejected configuration

- */ - @java.lang.Override - @JsonSetter(value = "code", nulls = Nulls.SKIP) - public _FinalStage code(Optional code) { - this.code = code; - return this; - } - @java.lang.Override public ListenV2ConfigureFailure build() { - return new ListenV2ConfigureFailure(requestId, sequenceId, code, description, additionalProperties); + return new ListenV2ConfigureFailure(requestId, sequenceId, additionalProperties); } @java.lang.Override diff --git a/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ForceEndTurn.java b/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ForceEndTurn.java index 894bd3c..c3dbd38 100644 --- a/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ForceEndTurn.java +++ b/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ForceEndTurn.java @@ -36,11 +36,6 @@ public boolean equals(Object other) { return other instanceof ListenV2ForceEndTurn; } - @java.lang.Override - public int hashCode() { - return getClass().hashCode(); - } - @JsonAnyGetter public Map getAdditionalProperties() { return this.additionalProperties; diff --git a/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2Warning.java b/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2Warning.java deleted file mode 100644 index 4eed2fb..0000000 --- a/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2Warning.java +++ /dev/null @@ -1,247 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.resources.listen.v2.types; - -import com.deepgram.core.ObjectMappers; -import com.fasterxml.jackson.annotation.JsonAnyGetter; -import com.fasterxml.jackson.annotation.JsonAnySetter; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonSetter; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import org.jetbrains.annotations.NotNull; - -@JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = ListenV2Warning.Builder.class) -public final class ListenV2Warning { - private final String requestId; - - private final int sequenceId; - - private final String code; - - private final String description; - - private final Map additionalProperties; - - private ListenV2Warning( - String requestId, - int sequenceId, - String code, - String description, - Map additionalProperties) { - this.requestId = requestId; - this.sequenceId = sequenceId; - this.code = code; - this.description = description; - this.additionalProperties = additionalProperties; - } - - /** - * @return Message type identifier - */ - @JsonProperty("type") - public String getType() { - return "Warning"; - } - - /** - * @return The unique identifier of the request - */ - @JsonProperty("request_id") - public String getRequestId() { - return requestId; - } - - /** - * @return Starts at 0 and increments for each message the server sends - * to the client. This includes messages of other types, like - * TurnInfo messages. - */ - @JsonProperty("sequence_id") - public int getSequenceId() { - return sequenceId; - } - - /** - * @return Warning code identifying the condition, in SCREAMING_SNAKE_CASE - */ - @JsonProperty("code") - public String getCode() { - return code; - } - - /** - * @return A human-readable description of the warning - */ - @JsonProperty("description") - public String getDescription() { - return description; - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof ListenV2Warning && equalTo((ListenV2Warning) other); - } - - @JsonAnyGetter - public Map getAdditionalProperties() { - return this.additionalProperties; - } - - private boolean equalTo(ListenV2Warning other) { - return requestId.equals(other.requestId) - && sequenceId == other.sequenceId - && code.equals(other.code) - && description.equals(other.description); - } - - @java.lang.Override - public int hashCode() { - return Objects.hash(this.requestId, this.sequenceId, this.code, this.description); - } - - @java.lang.Override - public String toString() { - return ObjectMappers.stringify(this); - } - - public static RequestIdStage builder() { - return new Builder(); - } - - public interface RequestIdStage { - /** - *

The unique identifier of the request

- */ - SequenceIdStage requestId(@NotNull String requestId); - - Builder from(ListenV2Warning other); - } - - public interface SequenceIdStage { - /** - *

Starts at 0 and increments for each message the server sends - * to the client. This includes messages of other types, like - * TurnInfo messages.

- */ - CodeStage sequenceId(int sequenceId); - } - - public interface CodeStage { - /** - *

Warning code identifying the condition, in SCREAMING_SNAKE_CASE

- */ - DescriptionStage code(@NotNull String code); - } - - public interface DescriptionStage { - /** - *

A human-readable description of the warning

- */ - _FinalStage description(@NotNull String description); - } - - public interface _FinalStage { - ListenV2Warning build(); - - _FinalStage additionalProperty(String key, Object value); - - _FinalStage additionalProperties(Map additionalProperties); - } - - @JsonIgnoreProperties(ignoreUnknown = true) - public static final class Builder - implements RequestIdStage, SequenceIdStage, CodeStage, DescriptionStage, _FinalStage { - private String requestId; - - private int sequenceId; - - private String code; - - private String description; - - @JsonAnySetter - private Map additionalProperties = new HashMap<>(); - - private Builder() {} - - @java.lang.Override - public Builder from(ListenV2Warning other) { - requestId(other.getRequestId()); - sequenceId(other.getSequenceId()); - code(other.getCode()); - description(other.getDescription()); - return this; - } - - /** - *

The unique identifier of the request

- * @return Reference to {@code this} so that method calls can be chained together. - */ - @java.lang.Override - @JsonSetter("request_id") - public SequenceIdStage requestId(@NotNull String requestId) { - this.requestId = Objects.requireNonNull(requestId, "requestId must not be null"); - return this; - } - - /** - *

Starts at 0 and increments for each message the server sends - * to the client. This includes messages of other types, like - * TurnInfo messages.

- * @return Reference to {@code this} so that method calls can be chained together. - */ - @java.lang.Override - @JsonSetter("sequence_id") - public CodeStage sequenceId(int sequenceId) { - this.sequenceId = sequenceId; - return this; - } - - /** - *

Warning code identifying the condition, in SCREAMING_SNAKE_CASE

- * @return Reference to {@code this} so that method calls can be chained together. - */ - @java.lang.Override - @JsonSetter("code") - public DescriptionStage code(@NotNull String code) { - this.code = Objects.requireNonNull(code, "code must not be null"); - return this; - } - - /** - *

A human-readable description of the warning

- * @return Reference to {@code this} so that method calls can be chained together. - */ - @java.lang.Override - @JsonSetter("description") - public _FinalStage description(@NotNull String description) { - this.description = Objects.requireNonNull(description, "description must not be null"); - return this; - } - - @java.lang.Override - public ListenV2Warning build() { - return new ListenV2Warning(requestId, sequenceId, code, description, additionalProperties); - } - - @java.lang.Override - public Builder additionalProperty(String key, Object value) { - this.additionalProperties.put(key, value); - return this; - } - - @java.lang.Override - public Builder additionalProperties(Map additionalProperties) { - this.additionalProperties.putAll(additionalProperties); - return this; - } - } -} diff --git a/src/main/java/com/deepgram/resources/listen/v2/websocket/V2WebSocketClient.java b/src/main/java/com/deepgram/resources/listen/v2/websocket/V2WebSocketClient.java index 5f55fea..0e1535b 100644 --- a/src/main/java/com/deepgram/resources/listen/v2/websocket/V2WebSocketClient.java +++ b/src/main/java/com/deepgram/resources/listen/v2/websocket/V2WebSocketClient.java @@ -6,7 +6,6 @@ import com.deepgram.core.ClientOptions; import com.deepgram.core.DisconnectReason; import com.deepgram.core.ObjectMappers; -import com.deepgram.core.QueryStringMapper; import com.deepgram.core.ReconnectingWebSocketListener; import com.deepgram.core.RequestOptions; import com.deepgram.core.WebSocketReadyState; @@ -18,12 +17,10 @@ import com.deepgram.resources.listen.v2.types.ListenV2FatalError; import com.deepgram.resources.listen.v2.types.ListenV2ForceEndTurn; import com.deepgram.resources.listen.v2.types.ListenV2TurnInfo; -import com.deepgram.resources.listen.v2.types.ListenV2Warning; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; import okhttp3.HttpUrl; import okhttp3.OkHttpClient; @@ -61,8 +58,6 @@ public class V2WebSocketClient implements AutoCloseable { private ReconnectingWebSocketListener reconnectingListener; - private final AtomicReference closeStreamSocket = new AtomicReference<>(); - private volatile Consumer connectedHandler; private volatile Consumer turnInfoHandler; @@ -71,8 +66,6 @@ public class V2WebSocketClient implements AutoCloseable { private volatile Consumer configureFailureHandler; - private volatile Consumer warningHandler; - private volatile Consumer errorHandler; /** @@ -91,7 +84,6 @@ public V2WebSocketClient(ClientOptions clientOptions) { */ public CompletableFuture connect(V2ConnectOptions options) { connectionFuture = new CompletableFuture<>(); - closeStreamSocket.set(null); String baseUrl = clientOptions.environment().getProductionURL(); String fullPath = "/v2/listen"; if (baseUrl.endsWith("/") && fullPath.startsWith("/")) { @@ -134,12 +126,12 @@ public CompletableFuture connect(V2ConnectOptions options) { "eot_timeout_ms", String.valueOf(options.getEotTimeoutMs().get())); } if (options.getKeyterm() != null && options.getKeyterm().isPresent()) { - QueryStringMapper.addQueryParameter( - urlBuilder, "keyterm", options.getKeyterm().get().get(), true); + urlBuilder.addQueryParameter( + "keyterm", String.valueOf(options.getKeyterm().get())); } if (options.getLanguageHint() != null && options.getLanguageHint().isPresent()) { - QueryStringMapper.addQueryParameter( - urlBuilder, "language_hint", options.getLanguageHint().get().get(), true); + urlBuilder.addQueryParameter( + "language_hint", String.valueOf(options.getLanguageHint().get())); } if (options.getProfanityFilter() != null && options.getProfanityFilter().isPresent()) { urlBuilder.addQueryParameter( @@ -159,14 +151,7 @@ public CompletableFuture connect(V2ConnectOptions options) { "mip_opt_out", String.valueOf(options.getMipOptOut().get())); } if (options.getTag() != null && options.getTag().isPresent()) { - QueryStringMapper.addQueryParameter(urlBuilder, "tag", options.getTag().get().get(), true); - } - if (options.getAdditionalProperties() != null) { - options.getAdditionalProperties().forEach((key, value) -> { - if (value != null) { - QueryStringMapper.addQueryParameter(urlBuilder, key, value, true); - } - }); + urlBuilder.addQueryParameter("tag", String.valueOf(options.getTag().get())); } Request.Builder requestBuilder = new Request.Builder().url(urlBuilder.build()); clientOptions.headers((RequestOptions) null).forEach(requestBuilder::addHeader); @@ -176,25 +161,15 @@ public CompletableFuture connect(V2ConnectOptions options) { ? this.reconnectOptions : ReconnectingWebSocketListener.ReconnectOptions.builder().build(); this.reconnectingListener = - new ReconnectingWebSocketListener( - reconnectOpts, - () -> { - if (clientOptions.isClosed()) { - throw new IllegalStateException("root client has been closed"); - } - if (clientOptions.webSocketFactory().isPresent()) { - return clientOptions - .webSocketFactory() - .get() - .create(request, this.reconnectingListener); - } else { - return okHttpClient.newWebSocket(request, this.reconnectingListener); - } - }, - clientOptions::isClosed) { + new ReconnectingWebSocketListener(reconnectOpts, () -> { + if (clientOptions.webSocketFactory().isPresent()) { + return clientOptions.webSocketFactory().get().create(request, this.reconnectingListener); + } else { + return okHttpClient.newWebSocket(request, this.reconnectingListener); + } + }) { @Override protected void onWebSocketOpen(WebSocket webSocket, Response response) { - closeStreamSocket.set(null); readyState = WebSocketReadyState.OPEN; if (onConnectedHandler != null) { onConnectedHandler.run(); @@ -226,14 +201,7 @@ protected void onWebSocketClosed(WebSocket webSocket, int code, String reason) { onDisconnectedHandler.accept(new DisconnectReason(code, reason)); } } - - @Override - protected boolean shouldReconnectAfterClose(WebSocket webSocket, int code, String reason) { - return super.shouldReconnectAfterClose(webSocket, code, reason) - && (code != 1005 || closeStreamSocket.get() != webSocket); - } }; - clientOptions.registerWebSocket(this); reconnectingListener.connect(); return connectionFuture; } @@ -242,10 +210,7 @@ protected boolean shouldReconnectAfterClose(WebSocket webSocket, int code, Strin * Disconnects the WebSocket connection and releases resources. */ public void disconnect() { - clientOptions.unregisterWebSocket(this); - if (reconnectingListener != null) { - reconnectingListener.disconnect(); - } + reconnectingListener.disconnect(); if (timeoutExecutor != null) { timeoutExecutor.shutdownNow(); timeoutExecutor = null; @@ -282,13 +247,12 @@ public CompletableFuture sendMedia(ByteString message) { } /** - * Sends a ListenV2CloseStream message to the server asynchronously. A queued CloseStream does - * not suppress reconnects because it might never reach the server. + * Sends a ListenV2CloseStream message to the server asynchronously. * @param message the message to send * @return a CompletableFuture that completes when the message is sent */ public CompletableFuture sendCloseStream(ListenV2CloseStream message) { - return sendMessage(message, closeStreamSocket::set); + return sendMessage(message); } /** @@ -341,14 +305,6 @@ public void onConfigureFailure(Consumer handler) { this.configureFailureHandler = handler; } - /** - * Registers a handler for ListenV2Warning messages from the server. - * @param handler the handler to invoke when a message is received - */ - public void onWarning(Consumer handler) { - this.warningHandler = handler; - } - /** * Registers a handler for ListenV2FatalError messages from the server. * @param handler the handler to invoke when a message is received @@ -422,16 +378,12 @@ private void assertSocketIsOpen() { } private CompletableFuture sendMessage(Object body) { - return sendMessage(body, null); - } - - private CompletableFuture sendMessage(Object body, Consumer onSent) { CompletableFuture future = new CompletableFuture<>(); try { assertSocketIsOpen(); String json = objectMapper.writeValueAsString(body); // Use reconnecting listener's send method which handles queuing - reconnectingListener.send(json, onSent); + reconnectingListener.send(json); future.complete(null); } catch (IllegalStateException e) { future.completeExceptionally(e); @@ -489,23 +441,6 @@ private void handleIncomingMessage(String json) { return; } } - if (node.has("request_id") - && node.has("sequence_id") - && node.has("code") - && node.has("description") - && "Warning".equals(node.path("type").asText())) { - ListenV2Warning warningHandlerEvent = null; - try { - warningHandlerEvent = objectMapper.treeToValue(node, ListenV2Warning.class); - } catch (Exception e) { - } - if (warningHandlerEvent != null) { - if (warningHandler != null) { - warningHandler.accept(warningHandlerEvent); - } - return; - } - } if (node.has("sequence_id") && node.has("code") && node.has("description") @@ -552,8 +487,11 @@ private void handleIncomingMessage(String json) { return; } } - // The raw frame is already delivered to onMessage(String), so ignore unknown typed - // frames for forward compatibility with newly added server control messages. + if (onErrorHandler != null) { + onErrorHandler.accept(new RuntimeException( + "Unrecognized WebSocket message: " + json.substring(0, Math.min(200, json.length())) + + "... Update your SDK version to support new message types.")); + } } catch (Exception e) { if (onErrorHandler != null) { onErrorHandler.accept(e); diff --git a/src/main/java/com/deepgram/resources/speak/v1/websocket/V1WebSocketClient.java b/src/main/java/com/deepgram/resources/speak/v1/websocket/V1WebSocketClient.java index e6824a3..8af4275 100644 --- a/src/main/java/com/deepgram/resources/speak/v1/websocket/V1WebSocketClient.java +++ b/src/main/java/com/deepgram/resources/speak/v1/websocket/V1WebSocketClient.java @@ -6,7 +6,6 @@ import com.deepgram.core.ClientOptions; import com.deepgram.core.DisconnectReason; import com.deepgram.core.ObjectMappers; -import com.deepgram.core.QueryStringMapper; import com.deepgram.core.ReconnectingWebSocketListener; import com.deepgram.core.RequestOptions; import com.deepgram.core.WebSocketReadyState; @@ -123,13 +122,6 @@ public CompletableFuture connect(V1ConnectOptions options) { urlBuilder.addQueryParameter( "speed", String.valueOf(options.getSpeed().get())); } - if (options.getAdditionalProperties() != null) { - options.getAdditionalProperties().forEach((key, value) -> { - if (value != null) { - QueryStringMapper.addQueryParameter(urlBuilder, key, value, true); - } - }); - } Request.Builder requestBuilder = new Request.Builder().url(urlBuilder.build()); clientOptions.headers((RequestOptions) null).forEach(requestBuilder::addHeader); final Request request = requestBuilder.build(); @@ -138,22 +130,13 @@ public CompletableFuture connect(V1ConnectOptions options) { ? this.reconnectOptions : ReconnectingWebSocketListener.ReconnectOptions.builder().build(); this.reconnectingListener = - new ReconnectingWebSocketListener( - reconnectOpts, - () -> { - if (clientOptions.isClosed()) { - throw new IllegalStateException("root client has been closed"); - } - if (clientOptions.webSocketFactory().isPresent()) { - return clientOptions - .webSocketFactory() - .get() - .create(request, this.reconnectingListener); - } else { - return okHttpClient.newWebSocket(request, this.reconnectingListener); - } - }, - clientOptions::isClosed) { + new ReconnectingWebSocketListener(reconnectOpts, () -> { + if (clientOptions.webSocketFactory().isPresent()) { + return clientOptions.webSocketFactory().get().create(request, this.reconnectingListener); + } else { + return okHttpClient.newWebSocket(request, this.reconnectingListener); + } + }) { @Override protected void onWebSocketOpen(WebSocket webSocket, Response response) { readyState = WebSocketReadyState.OPEN; @@ -192,7 +175,6 @@ protected void onWebSocketClosed(WebSocket webSocket, int code, String reason) { } } }; - clientOptions.registerWebSocket(this); reconnectingListener.connect(); return connectionFuture; } @@ -209,10 +191,7 @@ public CompletableFuture connect() { * Disconnects the WebSocket connection and releases resources. */ public void disconnect() { - clientOptions.unregisterWebSocket(this); - if (reconnectingListener != null) { - reconnectingListener.disconnect(); - } + reconnectingListener.disconnect(); if (timeoutExecutor != null) { timeoutExecutor.shutdownNow(); timeoutExecutor = null; diff --git a/src/main/java/com/deepgram/resources/speak/v2/audio/requests/SpeakV2Request.java b/src/main/java/com/deepgram/resources/speak/v2/audio/requests/SpeakV2Request.java index d1a3d82..bc3fb63 100644 --- a/src/main/java/com/deepgram/resources/speak/v2/audio/requests/SpeakV2Request.java +++ b/src/main/java/com/deepgram/resources/speak/v2/audio/requests/SpeakV2Request.java @@ -167,7 +167,7 @@ public Optional getSampleRate() { } /** - * @return Speaking rate multiplier that adjusts the pace of generated speech while preserving natural prosody and voice quality. Accepted values run 0.5 to 1.5 in 0.05 increments. Not yet supported in all languages. When the text contains an inline pause marker, speed is capped at 1.15 (PAUSE_SPEED_CAP_EXCEEDED above that). A value other than 1.0 cannot be combined with inline pronunciation controls (CONTROL_COMBINATION_INVALID). + * @return Speaking rate multiplier that adjusts the pace of generated speech while preserving natural prosody and voice quality. Accepted values run 0.5 to 1.5 in 0.05 increments. Not yet supported in all languages. */ @JsonIgnore public Optional getSpeed() { @@ -183,7 +183,7 @@ public Optional getPriority() { } /** - * @return The text content to be converted to speech. The server normalizes and preprocesses the text before synthesis. May contain inline pause controls (\{pause:500ms\}, 500-3000 ms in 100 ms steps, at most 8 per request) and inline pronunciation controls (\{"word": "...", "pronounce": "<IPA>"\}, Early Access). Pronunciation cannot be combined with pause or with a speed other than 1.0, and speed is capped at 1.15 when a pause is present. See Speed, Pause, Pronunciation. + * @return The text content to be converted to speech. The server normalizes and preprocesses the text before synthesis. Inline pause and pronunciation controls are not yet applied; they are stripped from the text before synthesis. */ @JsonProperty("text") public String getText() { @@ -255,7 +255,7 @@ public interface ModelStage { public interface TextStage { /** - *

The text content to be converted to speech. The server normalizes and preprocesses the text before synthesis. May contain inline pause controls (\{pause:500ms\}, 500-3000 ms in 100 ms steps, at most 8 per request) and inline pronunciation controls (\{"word": "...", "pronounce": "<IPA>"\}, Early Access). Pronunciation cannot be combined with pause or with a speed other than 1.0, and speed is capped at 1.15 when a pause is present. See Speed, Pause, Pronunciation.

+ *

The text content to be converted to speech. The server normalizes and preprocesses the text before synthesis. Inline pause and pronunciation controls are not yet applied; they are stripped from the text before synthesis.

*/ _FinalStage text(@NotNull String text); } @@ -333,7 +333,7 @@ public interface _FinalStage { _FinalStage sampleRate(Integer sampleRate); /** - *

Speaking rate multiplier that adjusts the pace of generated speech while preserving natural prosody and voice quality. Accepted values run 0.5 to 1.5 in 0.05 increments. Not yet supported in all languages. When the text contains an inline pause marker, speed is capped at 1.15 (PAUSE_SPEED_CAP_EXCEEDED above that). A value other than 1.0 cannot be combined with inline pronunciation controls (CONTROL_COMBINATION_INVALID).

+ *

Speaking rate multiplier that adjusts the pace of generated speech while preserving natural prosody and voice quality. Accepted values run 0.5 to 1.5 in 0.05 increments. Not yet supported in all languages.

*/ _FinalStage speed(Optional speed); @@ -410,7 +410,7 @@ public TextStage model(@NotNull String model) { } /** - *

The text content to be converted to speech. The server normalizes and preprocesses the text before synthesis. May contain inline pause controls (\{pause:500ms\}, 500-3000 ms in 100 ms steps, at most 8 per request) and inline pronunciation controls (\{"word": "...", "pronounce": "<IPA>"\}, Early Access). Pronunciation cannot be combined with pause or with a speed other than 1.0, and speed is capped at 1.15 when a pause is present. See Speed, Pause, Pronunciation.

+ *

The text content to be converted to speech. The server normalizes and preprocesses the text before synthesis. Inline pause and pronunciation controls are not yet applied; they are stripped from the text before synthesis.

* @return Reference to {@code this} so that method calls can be chained together. */ @java.lang.Override @@ -441,7 +441,7 @@ public _FinalStage priority(Optional priority) { } /** - *

Speaking rate multiplier that adjusts the pace of generated speech while preserving natural prosody and voice quality. Accepted values run 0.5 to 1.5 in 0.05 increments. Not yet supported in all languages. When the text contains an inline pause marker, speed is capped at 1.15 (PAUSE_SPEED_CAP_EXCEEDED above that). A value other than 1.0 cannot be combined with inline pronunciation controls (CONTROL_COMBINATION_INVALID).

+ *

Speaking rate multiplier that adjusts the pace of generated speech while preserving natural prosody and voice quality. Accepted values run 0.5 to 1.5 in 0.05 increments. Not yet supported in all languages.

* @return Reference to {@code this} so that method calls can be chained together. */ @java.lang.Override @@ -451,7 +451,7 @@ public _FinalStage speed(Double speed) { } /** - *

Speaking rate multiplier that adjusts the pace of generated speech while preserving natural prosody and voice quality. Accepted values run 0.5 to 1.5 in 0.05 increments. Not yet supported in all languages. When the text contains an inline pause marker, speed is capped at 1.15 (PAUSE_SPEED_CAP_EXCEEDED above that). A value other than 1.0 cannot be combined with inline pronunciation controls (CONTROL_COMBINATION_INVALID).

+ *

Speaking rate multiplier that adjusts the pace of generated speech while preserving natural prosody and voice quality. Accepted values run 0.5 to 1.5 in 0.05 increments. Not yet supported in all languages.

*/ @java.lang.Override @JsonSetter(value = "speed", nulls = Nulls.SKIP) diff --git a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Close.java b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Close.java index 7fecd79..2e96a5c 100644 --- a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Close.java +++ b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Close.java @@ -36,11 +36,6 @@ public boolean equals(Object other) { return other instanceof SpeakV2Close; } - @java.lang.Override - public int hashCode() { - return getClass().hashCode(); - } - @JsonAnyGetter public Map getAdditionalProperties() { return this.additionalProperties; diff --git a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2ConfigureFailure.java b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2ConfigureFailure.java index 7970232..e43c252 100644 --- a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2ConfigureFailure.java +++ b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2ConfigureFailure.java @@ -53,7 +53,7 @@ public String getType() { } /** - * @return Failure code, in SCREAMING_SNAKE_CASE. SPEED_OUT_OF_RANGE: outside the range the model publishes. SPEED_INCREMENT_INVALID: inside the published range but off the 0.05 increment. SPEED_NOT_SUPPORTED: this model or language has no runtime speed control at all. CONTROL_COMBINATION_INVALID: speed was set while a turn buffered behind the active one still carries a pronunciation control; pronunciation and speed cannot be combined, so flush that turn before setting speed (pronunciations in the active turn do not block the change). INTERNAL_ERROR: the configuration was acceptable but the server could not apply it — unlike the others, a server-side failure rather than a statement about the request. + * @return Failure code, in SCREAMING_SNAKE_CASE. SPEED_OUT_OF_RANGE: outside the range the model publishes. SPEED_INCREMENT_INVALID: inside the published range but off the 0.05 increment. SPEED_NOT_SUPPORTED: this model or language has no runtime speed control at all. INTERNAL_ERROR: the configuration was acceptable but the server could not apply it — unlike the others, a server-side failure rather than a statement about the request. */ @JsonProperty("code") public SpeakV2ConfigureFailureCode getCode() { @@ -118,7 +118,7 @@ public static CodeStage builder() { public interface CodeStage { /** - *

Failure code, in SCREAMING_SNAKE_CASE. SPEED_OUT_OF_RANGE: outside the range the model publishes. SPEED_INCREMENT_INVALID: inside the published range but off the 0.05 increment. SPEED_NOT_SUPPORTED: this model or language has no runtime speed control at all. CONTROL_COMBINATION_INVALID: speed was set while a turn buffered behind the active one still carries a pronunciation control; pronunciation and speed cannot be combined, so flush that turn before setting speed (pronunciations in the active turn do not block the change). INTERNAL_ERROR: the configuration was acceptable but the server could not apply it — unlike the others, a server-side failure rather than a statement about the request.

+ *

Failure code, in SCREAMING_SNAKE_CASE. SPEED_OUT_OF_RANGE: outside the range the model publishes. SPEED_INCREMENT_INVALID: inside the published range but off the 0.05 increment. SPEED_NOT_SUPPORTED: this model or language has no runtime speed control at all. INTERNAL_ERROR: the configuration was acceptable but the server could not apply it — unlike the others, a server-side failure rather than a statement about the request.

*/ DescriptionStage code(@NotNull SpeakV2ConfigureFailureCode code); @@ -179,7 +179,7 @@ public Builder from(SpeakV2ConfigureFailure other) { } /** - *

Failure code, in SCREAMING_SNAKE_CASE. SPEED_OUT_OF_RANGE: outside the range the model publishes. SPEED_INCREMENT_INVALID: inside the published range but off the 0.05 increment. SPEED_NOT_SUPPORTED: this model or language has no runtime speed control at all. CONTROL_COMBINATION_INVALID: speed was set while a turn buffered behind the active one still carries a pronunciation control; pronunciation and speed cannot be combined, so flush that turn before setting speed (pronunciations in the active turn do not block the change). INTERNAL_ERROR: the configuration was acceptable but the server could not apply it — unlike the others, a server-side failure rather than a statement about the request.

+ *

Failure code, in SCREAMING_SNAKE_CASE. SPEED_OUT_OF_RANGE: outside the range the model publishes. SPEED_INCREMENT_INVALID: inside the published range but off the 0.05 increment. SPEED_NOT_SUPPORTED: this model or language has no runtime speed control at all. INTERNAL_ERROR: the configuration was acceptable but the server could not apply it — unlike the others, a server-side failure rather than a statement about the request.

* @return Reference to {@code this} so that method calls can be chained together. */ @java.lang.Override diff --git a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2ConfigureFailureCode.java b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2ConfigureFailureCode.java index 63ec45a..7d02bce 100644 --- a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2ConfigureFailureCode.java +++ b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2ConfigureFailureCode.java @@ -7,9 +7,6 @@ import com.fasterxml.jackson.annotation.JsonValue; public final class SpeakV2ConfigureFailureCode { - public static final SpeakV2ConfigureFailureCode CONTROL_COMBINATION_INVALID = - new SpeakV2ConfigureFailureCode(Value.CONTROL_COMBINATION_INVALID, "CONTROL_COMBINATION_INVALID"); - public static final SpeakV2ConfigureFailureCode SPEED_OUT_OF_RANGE = new SpeakV2ConfigureFailureCode(Value.SPEED_OUT_OF_RANGE, "SPEED_OUT_OF_RANGE"); @@ -55,8 +52,6 @@ public int hashCode() { public T visit(Visitor visitor) { switch (value) { - case CONTROL_COMBINATION_INVALID: - return visitor.visitControlCombinationInvalid(); case SPEED_OUT_OF_RANGE: return visitor.visitSpeedOutOfRange(); case SPEED_INCREMENT_INVALID: @@ -74,8 +69,6 @@ public T visit(Visitor visitor) { @JsonCreator(mode = JsonCreator.Mode.DELEGATING) public static SpeakV2ConfigureFailureCode valueOf(String value) { switch (value) { - case "CONTROL_COMBINATION_INVALID": - return CONTROL_COMBINATION_INVALID; case "SPEED_OUT_OF_RANGE": return SPEED_OUT_OF_RANGE; case "SPEED_INCREMENT_INVALID": @@ -96,8 +89,6 @@ public enum Value { SPEED_NOT_SUPPORTED, - CONTROL_COMBINATION_INVALID, - INTERNAL_ERROR, UNKNOWN @@ -110,8 +101,6 @@ public interface Visitor { T visitSpeedNotSupported(); - T visitControlCombinationInvalid(); - T visitInternalError(); T visitUnknown(String unknownType); diff --git a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Error.java b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Error.java index 0a82847..343cfa7 100644 --- a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Error.java +++ b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Error.java @@ -40,7 +40,7 @@ public String getType() { } /** - * @return A code identifying the error, e.g. MESSAGE-0000 or NET-0000. DATA-0002 covers invalid inline controls and speed, including an inline pause marker (pause is batch-only) and a pronunciation control combined with a speed other than 1.0; description names the specific rule. + * @return A code identifying the error, e.g. MESSAGE-0000 or NET-0000. */ @JsonProperty("code") public SpeakV2ErrorCode getCode() { @@ -86,7 +86,7 @@ public static CodeStage builder() { public interface CodeStage { /** - *

A code identifying the error, e.g. MESSAGE-0000 or NET-0000. DATA-0002 covers invalid inline controls and speed, including an inline pause marker (pause is batch-only) and a pronunciation control combined with a speed other than 1.0; description names the specific rule.

+ *

A code identifying the error, e.g. MESSAGE-0000 or NET-0000.

*/ DescriptionStage code(@NotNull SpeakV2ErrorCode code); @@ -127,7 +127,7 @@ public Builder from(SpeakV2Error other) { } /** - *

A code identifying the error, e.g. MESSAGE-0000 or NET-0000. DATA-0002 covers invalid inline controls and speed, including an inline pause marker (pause is batch-only) and a pronunciation control combined with a speed other than 1.0; description names the specific rule.

+ *

A code identifying the error, e.g. MESSAGE-0000 or NET-0000.

* @return Reference to {@code this} so that method calls can be chained together. */ @java.lang.Override diff --git a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Flush.java b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Flush.java index 130da0d..acd717d 100644 --- a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Flush.java +++ b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Flush.java @@ -36,11 +36,6 @@ public boolean equals(Object other) { return other instanceof SpeakV2Flush; } - @java.lang.Override - public int hashCode() { - return getClass().hashCode(); - } - @JsonAnyGetter public Map getAdditionalProperties() { return this.additionalProperties; diff --git a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Speak.java b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Speak.java index 8c8e563..16150bf 100644 --- a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Speak.java +++ b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Speak.java @@ -37,7 +37,7 @@ public String getType() { } /** - * @return The input text to synthesize. May contain inline pronunciation controls (\{"word": "...", "pronounce": "<IPA>"\}), which are in Early Access. Inline pause controls are supported on the batch (REST) transport only; a pause marker sent over the WebSocket fails the connection with DATA-0002. Pronunciation cannot be combined with a speed other than 1.0: text carrying a pronunciation control on a session opened with speed, or after a Configure that set it, also fails the connection with DATA-0002. See Speed, Pause, Pronunciation. + * @return The input text to synthesize. Inline pause and pronunciation controls are not yet applied; they are stripped from the text before synthesis. */ @JsonProperty("text") public String getText() { @@ -75,7 +75,7 @@ public static TextStage builder() { public interface TextStage { /** - *

The input text to synthesize. May contain inline pronunciation controls (\{"word": "...", "pronounce": "<IPA>"\}), which are in Early Access. Inline pause controls are supported on the batch (REST) transport only; a pause marker sent over the WebSocket fails the connection with DATA-0002. Pronunciation cannot be combined with a speed other than 1.0: text carrying a pronunciation control on a session opened with speed, or after a Configure that set it, also fails the connection with DATA-0002. See Speed, Pause, Pronunciation.

+ *

The input text to synthesize. Inline pause and pronunciation controls are not yet applied; they are stripped from the text before synthesis.

*/ _FinalStage text(@NotNull String text); @@ -106,7 +106,7 @@ public Builder from(SpeakV2Speak other) { } /** - *

The input text to synthesize. May contain inline pronunciation controls (\{"word": "...", "pronounce": "<IPA>"\}), which are in Early Access. Inline pause controls are supported on the batch (REST) transport only; a pause marker sent over the WebSocket fails the connection with DATA-0002. Pronunciation cannot be combined with a speed other than 1.0: text carrying a pronunciation control on a session opened with speed, or after a Configure that set it, also fails the connection with DATA-0002. See Speed, Pause, Pronunciation.

+ *

The input text to synthesize. Inline pause and pronunciation controls are not yet applied; they are stripped from the text before synthesis.

* @return Reference to {@code this} so that method calls can be chained together. */ @java.lang.Override diff --git a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechInterruptedMetadata.java b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechInterruptedMetadata.java index 586f3c2..da24995 100644 --- a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechInterruptedMetadata.java +++ b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechInterruptedMetadata.java @@ -79,7 +79,7 @@ public int getBillableCharacterCount() { } /** - * @return Counts of the inline controls the server acted on during the turn. A pronunciation override that triggers an IPA warning is still applied best-effort and counted in pronunciations_applied; the warning is reported separately through a Warning and pronunciation_warnings. + * @return Counts of the inline controls the server acted on during the turn. Inline pause and pronunciation controls are not applied at launch — support is coming soon — so every count is currently 0. */ @JsonProperty("controls_applied") public SpeakV2SpeechInterruptedMetadataControlsApplied getControlsApplied() { @@ -156,7 +156,7 @@ public interface BillableCharacterCountStage { public interface ControlsAppliedStage { /** - *

Counts of the inline controls the server acted on during the turn. A pronunciation override that triggers an IPA warning is still applied best-effort and counted in pronunciations_applied; the warning is reported separately through a Warning and pronunciation_warnings.

+ *

Counts of the inline controls the server acted on during the turn. Inline pause and pronunciation controls are not applied at launch — support is coming soon — so every count is currently 0.

*/ _FinalStage controlsApplied(@NotNull SpeakV2SpeechInterruptedMetadataControlsApplied controlsApplied); } @@ -247,7 +247,7 @@ public ControlsAppliedStage billableCharacterCount(int billableCharacterCount) { } /** - *

Counts of the inline controls the server acted on during the turn. A pronunciation override that triggers an IPA warning is still applied best-effort and counted in pronunciations_applied; the warning is reported separately through a Warning and pronunciation_warnings.

+ *

Counts of the inline controls the server acted on during the turn. Inline pause and pronunciation controls are not applied at launch — support is coming soon — so every count is currently 0.

* @return Reference to {@code this} so that method calls can be chained together. */ @java.lang.Override diff --git a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechInterruptedMetadataControlsApplied.java b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechInterruptedMetadataControlsApplied.java index 0d0e0dc..85000d9 100644 --- a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechInterruptedMetadataControlsApplied.java +++ b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechInterruptedMetadataControlsApplied.java @@ -38,7 +38,7 @@ private SpeakV2SpeechInterruptedMetadataControlsApplied( } /** - * @return Pronunciation overrides successfully applied. Mirrors the Aura-2 dg-pronunciations-applied REST header. + * @return Pronunciation overrides successfully applied. Mirrors the Aura-2 dg-pronunciations-applied REST header. Currently always 0. */ @JsonProperty("pronunciations_applied") public int getPronunciationsApplied() { @@ -46,7 +46,7 @@ public int getPronunciationsApplied() { } /** - * @return Pause (break) controls successfully applied. Mirrors the Aura-2 dg-breaks-applied REST header. Always 0 on the WebSocket, where inline pause controls are not supported. + * @return Pause (break) controls successfully applied. Mirrors the Aura-2 dg-breaks-applied REST header. Currently always 0. */ @JsonProperty("breaks_applied") public int getBreaksApplied() { @@ -54,7 +54,7 @@ public int getBreaksApplied() { } /** - * @return Pronunciation entries that triggered a warning (invalid IPA, word too long). On batch requests the corresponding PRON-NNN codes are returned in the dg-warnings response header. + * @return Pronunciation entries that triggered a warning (invalid IPA, word too long). Mirrors the Aura-2 dg-pronunciation-warnings REST header. Currently always 0. */ @JsonProperty("pronunciation_warnings") public int getPronunciationWarnings() { @@ -95,7 +95,7 @@ public static PronunciationsAppliedStage builder() { public interface PronunciationsAppliedStage { /** - *

Pronunciation overrides successfully applied. Mirrors the Aura-2 dg-pronunciations-applied REST header.

+ *

Pronunciation overrides successfully applied. Mirrors the Aura-2 dg-pronunciations-applied REST header. Currently always 0.

*/ BreaksAppliedStage pronunciationsApplied(int pronunciationsApplied); @@ -104,14 +104,14 @@ public interface PronunciationsAppliedStage { public interface BreaksAppliedStage { /** - *

Pause (break) controls successfully applied. Mirrors the Aura-2 dg-breaks-applied REST header. Always 0 on the WebSocket, where inline pause controls are not supported.

+ *

Pause (break) controls successfully applied. Mirrors the Aura-2 dg-breaks-applied REST header. Currently always 0.

*/ PronunciationWarningsStage breaksApplied(int breaksApplied); } public interface PronunciationWarningsStage { /** - *

Pronunciation entries that triggered a warning (invalid IPA, word too long). On batch requests the corresponding PRON-NNN codes are returned in the dg-warnings response header.

+ *

Pronunciation entries that triggered a warning (invalid IPA, word too long). Mirrors the Aura-2 dg-pronunciation-warnings REST header. Currently always 0.

*/ _FinalStage pronunciationWarnings(int pronunciationWarnings); } @@ -147,7 +147,7 @@ public Builder from(SpeakV2SpeechInterruptedMetadataControlsApplied other) { } /** - *

Pronunciation overrides successfully applied. Mirrors the Aura-2 dg-pronunciations-applied REST header.

+ *

Pronunciation overrides successfully applied. Mirrors the Aura-2 dg-pronunciations-applied REST header. Currently always 0.

* @return Reference to {@code this} so that method calls can be chained together. */ @java.lang.Override @@ -158,7 +158,7 @@ public BreaksAppliedStage pronunciationsApplied(int pronunciationsApplied) { } /** - *

Pause (break) controls successfully applied. Mirrors the Aura-2 dg-breaks-applied REST header. Always 0 on the WebSocket, where inline pause controls are not supported.

+ *

Pause (break) controls successfully applied. Mirrors the Aura-2 dg-breaks-applied REST header. Currently always 0.

* @return Reference to {@code this} so that method calls can be chained together. */ @java.lang.Override @@ -169,7 +169,7 @@ public PronunciationWarningsStage breaksApplied(int breaksApplied) { } /** - *

Pronunciation entries that triggered a warning (invalid IPA, word too long). On batch requests the corresponding PRON-NNN codes are returned in the dg-warnings response header.

+ *

Pronunciation entries that triggered a warning (invalid IPA, word too long). Mirrors the Aura-2 dg-pronunciation-warnings REST header. Currently always 0.

* @return Reference to {@code this} so that method calls can be chained together. */ @java.lang.Override diff --git a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechMetadata.java b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechMetadata.java index be1ab9f..d982b95 100644 --- a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechMetadata.java +++ b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechMetadata.java @@ -87,7 +87,7 @@ public int getBillableCharacterCount() { } /** - * @return Counts of the inline controls the server acted on during the turn. A pronunciation override that triggers an IPA warning is still applied best-effort and counted in pronunciations_applied; the warning is reported separately through a Warning and pronunciation_warnings. + * @return Counts of the inline controls the server acted on during the turn. Inline pause and pronunciation controls are not applied at launch — support is coming soon — so every count is currently 0. */ @JsonProperty("controls_applied") public SpeakV2SpeechMetadataControlsApplied getControlsApplied() { @@ -164,7 +164,7 @@ public interface BillableCharacterCountStage { public interface ControlsAppliedStage { /** - *

Counts of the inline controls the server acted on during the turn. A pronunciation override that triggers an IPA warning is still applied best-effort and counted in pronunciations_applied; the warning is reported separately through a Warning and pronunciation_warnings.

+ *

Counts of the inline controls the server acted on during the turn. Inline pause and pronunciation controls are not applied at launch — support is coming soon — so every count is currently 0.

*/ _FinalStage controlsApplied(@NotNull SpeakV2SpeechMetadataControlsApplied controlsApplied); } @@ -255,7 +255,7 @@ public ControlsAppliedStage billableCharacterCount(int billableCharacterCount) { } /** - *

Counts of the inline controls the server acted on during the turn. A pronunciation override that triggers an IPA warning is still applied best-effort and counted in pronunciations_applied; the warning is reported separately through a Warning and pronunciation_warnings.

+ *

Counts of the inline controls the server acted on during the turn. Inline pause and pronunciation controls are not applied at launch — support is coming soon — so every count is currently 0.

* @return Reference to {@code this} so that method calls can be chained together. */ @java.lang.Override diff --git a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechMetadataControlsApplied.java b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechMetadataControlsApplied.java index ddf185a..b258f91 100644 --- a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechMetadataControlsApplied.java +++ b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechMetadataControlsApplied.java @@ -38,7 +38,7 @@ private SpeakV2SpeechMetadataControlsApplied( } /** - * @return Pronunciation overrides successfully applied. Mirrors the Aura-2 dg-pronunciations-applied REST header. + * @return Pronunciation overrides successfully applied. Mirrors the Aura-2 dg-pronunciations-applied REST header. Currently always 0. */ @JsonProperty("pronunciations_applied") public int getPronunciationsApplied() { @@ -46,7 +46,7 @@ public int getPronunciationsApplied() { } /** - * @return Pause (break) controls successfully applied. Mirrors the Aura-2 dg-breaks-applied REST header. Always 0 on the WebSocket, where inline pause controls are not supported. + * @return Pause (break) controls successfully applied. Mirrors the Aura-2 dg-breaks-applied REST header. Currently always 0. */ @JsonProperty("breaks_applied") public int getBreaksApplied() { @@ -54,7 +54,7 @@ public int getBreaksApplied() { } /** - * @return Pronunciation entries that triggered a warning (invalid IPA, word too long). On batch requests the corresponding PRON-NNN codes are returned in the dg-warnings response header. + * @return Pronunciation entries that triggered a warning (invalid IPA, word too long). Mirrors the Aura-2 dg-pronunciation-warnings REST header. Currently always 0. */ @JsonProperty("pronunciation_warnings") public int getPronunciationWarnings() { @@ -95,7 +95,7 @@ public static PronunciationsAppliedStage builder() { public interface PronunciationsAppliedStage { /** - *

Pronunciation overrides successfully applied. Mirrors the Aura-2 dg-pronunciations-applied REST header.

+ *

Pronunciation overrides successfully applied. Mirrors the Aura-2 dg-pronunciations-applied REST header. Currently always 0.

*/ BreaksAppliedStage pronunciationsApplied(int pronunciationsApplied); @@ -104,14 +104,14 @@ public interface PronunciationsAppliedStage { public interface BreaksAppliedStage { /** - *

Pause (break) controls successfully applied. Mirrors the Aura-2 dg-breaks-applied REST header. Always 0 on the WebSocket, where inline pause controls are not supported.

+ *

Pause (break) controls successfully applied. Mirrors the Aura-2 dg-breaks-applied REST header. Currently always 0.

*/ PronunciationWarningsStage breaksApplied(int breaksApplied); } public interface PronunciationWarningsStage { /** - *

Pronunciation entries that triggered a warning (invalid IPA, word too long). On batch requests the corresponding PRON-NNN codes are returned in the dg-warnings response header.

+ *

Pronunciation entries that triggered a warning (invalid IPA, word too long). Mirrors the Aura-2 dg-pronunciation-warnings REST header. Currently always 0.

*/ _FinalStage pronunciationWarnings(int pronunciationWarnings); } @@ -147,7 +147,7 @@ public Builder from(SpeakV2SpeechMetadataControlsApplied other) { } /** - *

Pronunciation overrides successfully applied. Mirrors the Aura-2 dg-pronunciations-applied REST header.

+ *

Pronunciation overrides successfully applied. Mirrors the Aura-2 dg-pronunciations-applied REST header. Currently always 0.

* @return Reference to {@code this} so that method calls can be chained together. */ @java.lang.Override @@ -158,7 +158,7 @@ public BreaksAppliedStage pronunciationsApplied(int pronunciationsApplied) { } /** - *

Pause (break) controls successfully applied. Mirrors the Aura-2 dg-breaks-applied REST header. Always 0 on the WebSocket, where inline pause controls are not supported.

+ *

Pause (break) controls successfully applied. Mirrors the Aura-2 dg-breaks-applied REST header. Currently always 0.

* @return Reference to {@code this} so that method calls can be chained together. */ @java.lang.Override @@ -169,7 +169,7 @@ public PronunciationWarningsStage breaksApplied(int breaksApplied) { } /** - *

Pronunciation entries that triggered a warning (invalid IPA, word too long). On batch requests the corresponding PRON-NNN codes are returned in the dg-warnings response header.

+ *

Pronunciation entries that triggered a warning (invalid IPA, word too long). Mirrors the Aura-2 dg-pronunciation-warnings REST header. Currently always 0.

* @return Reference to {@code this} so that method calls can be chained together. */ @java.lang.Override diff --git a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Warning.java b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Warning.java index 84332f9..0eb0b3c 100644 --- a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Warning.java +++ b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Warning.java @@ -42,8 +42,7 @@ public String getType() { /** * @return Warning code identifying the condition, in SCREAMING_SNAKE_CASE. *

Turn-scoped codes: NO_ACTIVE_SPEECH (a speech-scoped message arrived with no active turn), NO_SYNTHESIZABLE_TEXT (the turn's text was entirely whitespace or punctuation, so it produced no audio and is completed with a zero-duration SpeechMetadata), and SYNTHESIS_RETRYING (a synthesis request failed and is being retried).

- *

Pronunciation codes: PRONUNCIATION_WARNINGS (a pronunciation override contained invalid IPA; it is still applied best-effort and counted in pronunciations_applied), PRONUNCIATION_TOO_LONG (an IPA string exceeded the length limit), PRONUNCIATIONS_LIMIT_EXCEEDED (too many pronunciation controls in one turn).

- *

Pause codes (BREAKS_LIMIT_EXCEEDED, BREAK_TOKENS_OUT_OF_RANGE, BREAK_TOKENS_WITH_INVALID_INCREMENTS) are reserved and not emitted: inline pause controls are batch-only, and a pause marker on the WebSocket fails the connection instead.

+ *

Inline-control codes are reserved and not currently emitted, because inline pause and pronunciation controls are not yet applied: BREAKS_LIMIT_EXCEEDED (too many pause controls, or two pauses with no intervening text), BREAK_TOKENS_OUT_OF_RANGE (pause durations outside the range the model supports), BREAK_TOKENS_WITH_INVALID_INCREMENTS (pause durations off the model's supported increment), PRONUNCIATION_WARNINGS (a pronunciation override contained invalid IPA), PRONUNCIATION_TOO_LONG (an IPA string exceeded the length limit), PRONUNCIATIONS_LIMIT_EXCEEDED (too many pronunciation controls in one turn).

*

Interrupt-scoped codes, each meaning the Interrupt was ignored: NO_AUDIO_GENERATED (the session has produced no audio yet, so there is nothing to interrupt), INTERRUPT_IN_PROGRESS (an earlier Interrupt is still being processed — at most one is handled at a time), INVALID_INTERRUPT_OFFSET (the playback_offset did not advance past the position a prior interrupt established).

*/ @JsonProperty("code") @@ -92,8 +91,7 @@ public interface CodeStage { /** *

Warning code identifying the condition, in SCREAMING_SNAKE_CASE.

*

Turn-scoped codes: NO_ACTIVE_SPEECH (a speech-scoped message arrived with no active turn), NO_SYNTHESIZABLE_TEXT (the turn's text was entirely whitespace or punctuation, so it produced no audio and is completed with a zero-duration SpeechMetadata), and SYNTHESIS_RETRYING (a synthesis request failed and is being retried).

- *

Pronunciation codes: PRONUNCIATION_WARNINGS (a pronunciation override contained invalid IPA; it is still applied best-effort and counted in pronunciations_applied), PRONUNCIATION_TOO_LONG (an IPA string exceeded the length limit), PRONUNCIATIONS_LIMIT_EXCEEDED (too many pronunciation controls in one turn).

- *

Pause codes (BREAKS_LIMIT_EXCEEDED, BREAK_TOKENS_OUT_OF_RANGE, BREAK_TOKENS_WITH_INVALID_INCREMENTS) are reserved and not emitted: inline pause controls are batch-only, and a pause marker on the WebSocket fails the connection instead.

+ *

Inline-control codes are reserved and not currently emitted, because inline pause and pronunciation controls are not yet applied: BREAKS_LIMIT_EXCEEDED (too many pause controls, or two pauses with no intervening text), BREAK_TOKENS_OUT_OF_RANGE (pause durations outside the range the model supports), BREAK_TOKENS_WITH_INVALID_INCREMENTS (pause durations off the model's supported increment), PRONUNCIATION_WARNINGS (a pronunciation override contained invalid IPA), PRONUNCIATION_TOO_LONG (an IPA string exceeded the length limit), PRONUNCIATIONS_LIMIT_EXCEEDED (too many pronunciation controls in one turn).

*

Interrupt-scoped codes, each meaning the Interrupt was ignored: NO_AUDIO_GENERATED (the session has produced no audio yet, so there is nothing to interrupt), INTERRUPT_IN_PROGRESS (an earlier Interrupt is still being processed — at most one is handled at a time), INVALID_INTERRUPT_OFFSET (the playback_offset did not advance past the position a prior interrupt established).

*/ DescriptionStage code(@NotNull String code); @@ -137,8 +135,7 @@ public Builder from(SpeakV2Warning other) { /** *

Warning code identifying the condition, in SCREAMING_SNAKE_CASE.

*

Turn-scoped codes: NO_ACTIVE_SPEECH (a speech-scoped message arrived with no active turn), NO_SYNTHESIZABLE_TEXT (the turn's text was entirely whitespace or punctuation, so it produced no audio and is completed with a zero-duration SpeechMetadata), and SYNTHESIS_RETRYING (a synthesis request failed and is being retried).

- *

Pronunciation codes: PRONUNCIATION_WARNINGS (a pronunciation override contained invalid IPA; it is still applied best-effort and counted in pronunciations_applied), PRONUNCIATION_TOO_LONG (an IPA string exceeded the length limit), PRONUNCIATIONS_LIMIT_EXCEEDED (too many pronunciation controls in one turn).

- *

Pause codes (BREAKS_LIMIT_EXCEEDED, BREAK_TOKENS_OUT_OF_RANGE, BREAK_TOKENS_WITH_INVALID_INCREMENTS) are reserved and not emitted: inline pause controls are batch-only, and a pause marker on the WebSocket fails the connection instead.

+ *

Inline-control codes are reserved and not currently emitted, because inline pause and pronunciation controls are not yet applied: BREAKS_LIMIT_EXCEEDED (too many pause controls, or two pauses with no intervening text), BREAK_TOKENS_OUT_OF_RANGE (pause durations outside the range the model supports), BREAK_TOKENS_WITH_INVALID_INCREMENTS (pause durations off the model's supported increment), PRONUNCIATION_WARNINGS (a pronunciation override contained invalid IPA), PRONUNCIATION_TOO_LONG (an IPA string exceeded the length limit), PRONUNCIATIONS_LIMIT_EXCEEDED (too many pronunciation controls in one turn).

*

Interrupt-scoped codes, each meaning the Interrupt was ignored: NO_AUDIO_GENERATED (the session has produced no audio yet, so there is nothing to interrupt), INTERRUPT_IN_PROGRESS (an earlier Interrupt is still being processed — at most one is handled at a time), INVALID_INTERRUPT_OFFSET (the playback_offset did not advance past the position a prior interrupt established).

* @return Reference to {@code this} so that method calls can be chained together. */ diff --git a/src/main/java/com/deepgram/resources/speak/v2/websocket/V2WebSocketClient.java b/src/main/java/com/deepgram/resources/speak/v2/websocket/V2WebSocketClient.java index b4e01f7..3e032b1 100644 --- a/src/main/java/com/deepgram/resources/speak/v2/websocket/V2WebSocketClient.java +++ b/src/main/java/com/deepgram/resources/speak/v2/websocket/V2WebSocketClient.java @@ -6,7 +6,6 @@ import com.deepgram.core.ClientOptions; import com.deepgram.core.DisconnectReason; import com.deepgram.core.ObjectMappers; -import com.deepgram.core.QueryStringMapper; import com.deepgram.core.ReconnectingWebSocketListener; import com.deepgram.core.RequestOptions; import com.deepgram.core.WebSocketReadyState; @@ -144,14 +143,7 @@ public CompletableFuture connect(V2ConnectOptions options) { "mip_opt_out", String.valueOf(options.getMipOptOut().get())); } if (options.getTag() != null && options.getTag().isPresent()) { - QueryStringMapper.addQueryParameter(urlBuilder, "tag", options.getTag().get().get(), true); - } - if (options.getAdditionalProperties() != null) { - options.getAdditionalProperties().forEach((key, value) -> { - if (value != null) { - QueryStringMapper.addQueryParameter(urlBuilder, key, value, true); - } - }); + urlBuilder.addQueryParameter("tag", String.valueOf(options.getTag().get())); } Request.Builder requestBuilder = new Request.Builder().url(urlBuilder.build()); clientOptions.headers((RequestOptions) null).forEach(requestBuilder::addHeader); @@ -161,22 +153,13 @@ public CompletableFuture connect(V2ConnectOptions options) { ? this.reconnectOptions : ReconnectingWebSocketListener.ReconnectOptions.builder().build(); this.reconnectingListener = - new ReconnectingWebSocketListener( - reconnectOpts, - () -> { - if (clientOptions.isClosed()) { - throw new IllegalStateException("root client has been closed"); - } - if (clientOptions.webSocketFactory().isPresent()) { - return clientOptions - .webSocketFactory() - .get() - .create(request, this.reconnectingListener); - } else { - return okHttpClient.newWebSocket(request, this.reconnectingListener); - } - }, - clientOptions::isClosed) { + new ReconnectingWebSocketListener(reconnectOpts, () -> { + if (clientOptions.webSocketFactory().isPresent()) { + return clientOptions.webSocketFactory().get().create(request, this.reconnectingListener); + } else { + return okHttpClient.newWebSocket(request, this.reconnectingListener); + } + }) { @Override protected void onWebSocketOpen(WebSocket webSocket, Response response) { readyState = WebSocketReadyState.OPEN; @@ -215,7 +198,6 @@ protected void onWebSocketClosed(WebSocket webSocket, int code, String reason) { } } }; - clientOptions.registerWebSocket(this); reconnectingListener.connect(); return connectionFuture; } @@ -224,10 +206,7 @@ protected void onWebSocketClosed(WebSocket webSocket, int code, String reason) { * Disconnects the WebSocket connection and releases resources. */ public void disconnect() { - clientOptions.unregisterWebSocket(this); - if (reconnectingListener != null) { - reconnectingListener.disconnect(); - } + reconnectingListener.disconnect(); if (timeoutExecutor != null) { timeoutExecutor.shutdownNow(); timeoutExecutor = null; @@ -619,8 +598,11 @@ private void handleIncomingMessage(String json) { return; } } - // The raw frame is already delivered to onMessage(String), so ignore unknown typed - // frames for forward compatibility with newly added server control messages. + if (onErrorHandler != null) { + onErrorHandler.accept(new RuntimeException( + "Unrecognized WebSocket message: " + json.substring(0, Math.min(200, json.length())) + + "... Update your SDK version to support new message types.")); + } } catch (Exception e) { if (onErrorHandler != null) { onErrorHandler.accept(e); diff --git a/src/main/java/com/deepgram/types/DeepgramModel.java b/src/main/java/com/deepgram/types/DeepgramModel.java index 6444d7f..fc7c08c 100644 --- a/src/main/java/com/deepgram/types/DeepgramModel.java +++ b/src/main/java/com/deepgram/types/DeepgramModel.java @@ -13,8 +13,6 @@ public final class DeepgramModel { public static final DeepgramModel FLUX_KELSEY_EN = new DeepgramModel(Value.FLUX_KELSEY_EN, "flux-kelsey-en"); - public static final DeepgramModel FLUX_RENEE_EN = new DeepgramModel(Value.FLUX_RENEE_EN, "flux-renee-en"); - public static final DeepgramModel FLUX_SIENNA_EN = new DeepgramModel(Value.FLUX_SIENNA_EN, "flux-sienna-en"); public static final DeepgramModel AURA2HARMONIA_EN = @@ -253,8 +251,6 @@ public T visit(Visitor visitor) { return visitor.visitAura2HeraEn(); case FLUX_KELSEY_EN: return visitor.visitFluxKelseyEn(); - case FLUX_RENEE_EN: - return visitor.visitFluxReneeEn(); case FLUX_SIENNA_EN: return visitor.visitFluxSiennaEn(); case AURA2HARMONIA_EN: @@ -462,8 +458,6 @@ public static DeepgramModel valueOf(String value) { return AURA2HERA_EN; case "flux-kelsey-en": return FLUX_KELSEY_EN; - case "flux-renee-en": - return FLUX_RENEE_EN; case "flux-sienna-en": return FLUX_SIENNA_EN; case "aura-2-harmonia-en": @@ -846,8 +840,6 @@ public enum Value { FLUX_PRIYA_EN, - FLUX_RENEE_EN, - FLUX_RUFUS_EN, FLUX_SEAN_EN, @@ -1050,8 +1042,6 @@ public interface Visitor { T visitFluxPriyaEn(); - T visitFluxReneeEn(); - T visitFluxRufusEn(); T visitFluxSeanEn(); diff --git a/src/main/java/com/deepgram/types/SharedIntents.java b/src/main/java/com/deepgram/types/SharedIntents.java index 05799c2..c689861 100644 --- a/src/main/java/com/deepgram/types/SharedIntents.java +++ b/src/main/java/com/deepgram/types/SharedIntents.java @@ -13,7 +13,6 @@ import com.fasterxml.jackson.annotation.Nulls; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -21,19 +20,18 @@ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonDeserialize(builder = SharedIntents.Builder.class) public final class SharedIntents { - private final Optional> segments; + private final Optional results; private final Map additionalProperties; - private SharedIntents( - Optional> segments, Map additionalProperties) { - this.segments = segments; + private SharedIntents(Optional results, Map additionalProperties) { + this.results = results; this.additionalProperties = additionalProperties; } - @JsonProperty("segments") - public Optional> getSegments() { - return segments; + @JsonProperty("results") + public Optional getResults() { + return results; } @java.lang.Override @@ -48,12 +46,12 @@ public Map getAdditionalProperties() { } private boolean equalTo(SharedIntents other) { - return segments.equals(other.segments); + return results.equals(other.results); } @java.lang.Override public int hashCode() { - return Objects.hash(this.segments); + return Objects.hash(this.results); } @java.lang.Override @@ -67,7 +65,7 @@ public static Builder builder() { @JsonIgnoreProperties(ignoreUnknown = true) public static final class Builder { - private Optional> segments = Optional.empty(); + private Optional results = Optional.empty(); @JsonAnySetter private Map additionalProperties = new HashMap<>(); @@ -75,23 +73,23 @@ public static final class Builder { private Builder() {} public Builder from(SharedIntents other) { - segments(other.getSegments()); + results(other.getResults()); return this; } - @JsonSetter(value = "segments", nulls = Nulls.SKIP) - public Builder segments(Optional> segments) { - this.segments = segments; + @JsonSetter(value = "results", nulls = Nulls.SKIP) + public Builder results(Optional results) { + this.results = results; return this; } - public Builder segments(List segments) { - this.segments = Optional.ofNullable(segments); + public Builder results(SharedIntentsResults results) { + this.results = Optional.ofNullable(results); return this; } public SharedIntents build() { - return new SharedIntents(segments, additionalProperties); + return new SharedIntents(results, additionalProperties); } public Builder additionalProperty(String key, Object value) { diff --git a/src/main/java/com/deepgram/types/SharedIntentsResults.java b/src/main/java/com/deepgram/types/SharedIntentsResults.java new file mode 100644 index 0000000..44bfe37 --- /dev/null +++ b/src/main/java/com/deepgram/types/SharedIntentsResults.java @@ -0,0 +1,106 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.types; + +import com.deepgram.core.ObjectMappers; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.annotation.Nulls; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonDeserialize(builder = SharedIntentsResults.Builder.class) +public final class SharedIntentsResults { + private final Optional intents; + + private final Map additionalProperties; + + private SharedIntentsResults( + Optional intents, Map additionalProperties) { + this.intents = intents; + this.additionalProperties = additionalProperties; + } + + @JsonProperty("intents") + public Optional getIntents() { + return intents; + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof SharedIntentsResults && equalTo((SharedIntentsResults) other); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + private boolean equalTo(SharedIntentsResults other) { + return intents.equals(other.intents); + } + + @java.lang.Override + public int hashCode() { + return Objects.hash(this.intents); + } + + @java.lang.Override + public String toString() { + return ObjectMappers.stringify(this); + } + + public static Builder builder() { + return new Builder(); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static final class Builder { + private Optional intents = Optional.empty(); + + @JsonAnySetter + private Map additionalProperties = new HashMap<>(); + + private Builder() {} + + public Builder from(SharedIntentsResults other) { + intents(other.getIntents()); + return this; + } + + @JsonSetter(value = "intents", nulls = Nulls.SKIP) + public Builder intents(Optional intents) { + this.intents = intents; + return this; + } + + public Builder intents(SharedIntentsResultsIntents intents) { + this.intents = Optional.ofNullable(intents); + return this; + } + + public SharedIntentsResults build() { + return new SharedIntentsResults(intents, additionalProperties); + } + + public Builder additionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + return this; + } + + public Builder additionalProperties(Map additionalProperties) { + this.additionalProperties.putAll(additionalProperties); + return this; + } + } +} diff --git a/src/main/java/com/deepgram/types/SharedIntentsResultsIntents.java b/src/main/java/com/deepgram/types/SharedIntentsResultsIntents.java new file mode 100644 index 0000000..a5fe89b --- /dev/null +++ b/src/main/java/com/deepgram/types/SharedIntentsResultsIntents.java @@ -0,0 +1,108 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.types; + +import com.deepgram.core.ObjectMappers; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.annotation.Nulls; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonDeserialize(builder = SharedIntentsResultsIntents.Builder.class) +public final class SharedIntentsResultsIntents { + private final Optional> segments; + + private final Map additionalProperties; + + private SharedIntentsResultsIntents( + Optional> segments, + Map additionalProperties) { + this.segments = segments; + this.additionalProperties = additionalProperties; + } + + @JsonProperty("segments") + public Optional> getSegments() { + return segments; + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof SharedIntentsResultsIntents && equalTo((SharedIntentsResultsIntents) other); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + private boolean equalTo(SharedIntentsResultsIntents other) { + return segments.equals(other.segments); + } + + @java.lang.Override + public int hashCode() { + return Objects.hash(this.segments); + } + + @java.lang.Override + public String toString() { + return ObjectMappers.stringify(this); + } + + public static Builder builder() { + return new Builder(); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static final class Builder { + private Optional> segments = Optional.empty(); + + @JsonAnySetter + private Map additionalProperties = new HashMap<>(); + + private Builder() {} + + public Builder from(SharedIntentsResultsIntents other) { + segments(other.getSegments()); + return this; + } + + @JsonSetter(value = "segments", nulls = Nulls.SKIP) + public Builder segments(Optional> segments) { + this.segments = segments; + return this; + } + + public Builder segments(List segments) { + this.segments = Optional.ofNullable(segments); + return this; + } + + public SharedIntentsResultsIntents build() { + return new SharedIntentsResultsIntents(segments, additionalProperties); + } + + public Builder additionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + return this; + } + + public Builder additionalProperties(Map additionalProperties) { + this.additionalProperties.putAll(additionalProperties); + return this; + } + } +} diff --git a/src/main/java/com/deepgram/types/SharedIntentsSegmentsItem.java b/src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItem.java similarity index 78% rename from src/main/java/com/deepgram/types/SharedIntentsSegmentsItem.java rename to src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItem.java index 431b68f..694be4f 100644 --- a/src/main/java/com/deepgram/types/SharedIntentsSegmentsItem.java +++ b/src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItem.java @@ -19,23 +19,23 @@ import java.util.Optional; @JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = SharedIntentsSegmentsItem.Builder.class) -public final class SharedIntentsSegmentsItem { +@JsonDeserialize(builder = SharedIntentsResultsIntentsSegmentsItem.Builder.class) +public final class SharedIntentsResultsIntentsSegmentsItem { private final Optional text; private final Optional startWord; private final Optional endWord; - private final Optional> intents; + private final Optional> intents; private final Map additionalProperties; - private SharedIntentsSegmentsItem( + private SharedIntentsResultsIntentsSegmentsItem( Optional text, Optional startWord, Optional endWord, - Optional> intents, + Optional> intents, Map additionalProperties) { this.text = text; this.startWord = startWord; @@ -60,14 +60,15 @@ public Optional getEndWord() { } @JsonProperty("intents") - public Optional> getIntents() { + public Optional> getIntents() { return intents; } @java.lang.Override public boolean equals(Object other) { if (this == other) return true; - return other instanceof SharedIntentsSegmentsItem && equalTo((SharedIntentsSegmentsItem) other); + return other instanceof SharedIntentsResultsIntentsSegmentsItem + && equalTo((SharedIntentsResultsIntentsSegmentsItem) other); } @JsonAnyGetter @@ -75,7 +76,7 @@ public Map getAdditionalProperties() { return this.additionalProperties; } - private boolean equalTo(SharedIntentsSegmentsItem other) { + private boolean equalTo(SharedIntentsResultsIntentsSegmentsItem other) { return text.equals(other.text) && startWord.equals(other.startWord) && endWord.equals(other.endWord) @@ -104,14 +105,14 @@ public static final class Builder { private Optional endWord = Optional.empty(); - private Optional> intents = Optional.empty(); + private Optional> intents = Optional.empty(); @JsonAnySetter private Map additionalProperties = new HashMap<>(); private Builder() {} - public Builder from(SharedIntentsSegmentsItem other) { + public Builder from(SharedIntentsResultsIntentsSegmentsItem other) { text(other.getText()); startWord(other.getStartWord()); endWord(other.getEndWord()); @@ -153,18 +154,18 @@ public Builder endWord(Double endWord) { } @JsonSetter(value = "intents", nulls = Nulls.SKIP) - public Builder intents(Optional> intents) { + public Builder intents(Optional> intents) { this.intents = intents; return this; } - public Builder intents(List intents) { + public Builder intents(List intents) { this.intents = Optional.ofNullable(intents); return this; } - public SharedIntentsSegmentsItem build() { - return new SharedIntentsSegmentsItem(text, startWord, endWord, intents, additionalProperties); + public SharedIntentsResultsIntentsSegmentsItem build() { + return new SharedIntentsResultsIntentsSegmentsItem(text, startWord, endWord, intents, additionalProperties); } public Builder additionalProperty(String key, Object value) { diff --git a/src/main/java/com/deepgram/types/SharedIntentsSegmentsItemIntentsItem.java b/src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItemIntentsItem.java similarity index 81% rename from src/main/java/com/deepgram/types/SharedIntentsSegmentsItemIntentsItem.java rename to src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItemIntentsItem.java index 9f97c91..d6554e2 100644 --- a/src/main/java/com/deepgram/types/SharedIntentsSegmentsItemIntentsItem.java +++ b/src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItemIntentsItem.java @@ -18,15 +18,15 @@ import java.util.Optional; @JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = SharedIntentsSegmentsItemIntentsItem.Builder.class) -public final class SharedIntentsSegmentsItemIntentsItem { +@JsonDeserialize(builder = SharedIntentsResultsIntentsSegmentsItemIntentsItem.Builder.class) +public final class SharedIntentsResultsIntentsSegmentsItemIntentsItem { private final Optional intent; private final Optional confidenceScore; private final Map additionalProperties; - private SharedIntentsSegmentsItemIntentsItem( + private SharedIntentsResultsIntentsSegmentsItemIntentsItem( Optional intent, Optional confidenceScore, Map additionalProperties) { this.intent = intent; this.confidenceScore = confidenceScore; @@ -46,8 +46,8 @@ public Optional getConfidenceScore() { @java.lang.Override public boolean equals(Object other) { if (this == other) return true; - return other instanceof SharedIntentsSegmentsItemIntentsItem - && equalTo((SharedIntentsSegmentsItemIntentsItem) other); + return other instanceof SharedIntentsResultsIntentsSegmentsItemIntentsItem + && equalTo((SharedIntentsResultsIntentsSegmentsItemIntentsItem) other); } @JsonAnyGetter @@ -55,7 +55,7 @@ public Map getAdditionalProperties() { return this.additionalProperties; } - private boolean equalTo(SharedIntentsSegmentsItemIntentsItem other) { + private boolean equalTo(SharedIntentsResultsIntentsSegmentsItemIntentsItem other) { return intent.equals(other.intent) && confidenceScore.equals(other.confidenceScore); } @@ -84,7 +84,7 @@ public static final class Builder { private Builder() {} - public Builder from(SharedIntentsSegmentsItemIntentsItem other) { + public Builder from(SharedIntentsResultsIntentsSegmentsItemIntentsItem other) { intent(other.getIntent()); confidenceScore(other.getConfidenceScore()); return this; @@ -112,8 +112,9 @@ public Builder confidenceScore(Float confidenceScore) { return this; } - public SharedIntentsSegmentsItemIntentsItem build() { - return new SharedIntentsSegmentsItemIntentsItem(intent, confidenceScore, additionalProperties); + public SharedIntentsResultsIntentsSegmentsItemIntentsItem build() { + return new SharedIntentsResultsIntentsSegmentsItemIntentsItem( + intent, confidenceScore, additionalProperties); } public Builder additionalProperty(String key, Object value) { diff --git a/src/main/java/com/deepgram/types/SharedTopics.java b/src/main/java/com/deepgram/types/SharedTopics.java index 25a75ea..463e84c 100644 --- a/src/main/java/com/deepgram/types/SharedTopics.java +++ b/src/main/java/com/deepgram/types/SharedTopics.java @@ -13,7 +13,6 @@ import com.fasterxml.jackson.annotation.Nulls; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -21,18 +20,18 @@ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonDeserialize(builder = SharedTopics.Builder.class) public final class SharedTopics { - private final Optional> segments; + private final Optional results; private final Map additionalProperties; - private SharedTopics(Optional> segments, Map additionalProperties) { - this.segments = segments; + private SharedTopics(Optional results, Map additionalProperties) { + this.results = results; this.additionalProperties = additionalProperties; } - @JsonProperty("segments") - public Optional> getSegments() { - return segments; + @JsonProperty("results") + public Optional getResults() { + return results; } @java.lang.Override @@ -47,12 +46,12 @@ public Map getAdditionalProperties() { } private boolean equalTo(SharedTopics other) { - return segments.equals(other.segments); + return results.equals(other.results); } @java.lang.Override public int hashCode() { - return Objects.hash(this.segments); + return Objects.hash(this.results); } @java.lang.Override @@ -66,7 +65,7 @@ public static Builder builder() { @JsonIgnoreProperties(ignoreUnknown = true) public static final class Builder { - private Optional> segments = Optional.empty(); + private Optional results = Optional.empty(); @JsonAnySetter private Map additionalProperties = new HashMap<>(); @@ -74,23 +73,23 @@ public static final class Builder { private Builder() {} public Builder from(SharedTopics other) { - segments(other.getSegments()); + results(other.getResults()); return this; } - @JsonSetter(value = "segments", nulls = Nulls.SKIP) - public Builder segments(Optional> segments) { - this.segments = segments; + @JsonSetter(value = "results", nulls = Nulls.SKIP) + public Builder results(Optional results) { + this.results = results; return this; } - public Builder segments(List segments) { - this.segments = Optional.ofNullable(segments); + public Builder results(SharedTopicsResults results) { + this.results = Optional.ofNullable(results); return this; } public SharedTopics build() { - return new SharedTopics(segments, additionalProperties); + return new SharedTopics(results, additionalProperties); } public Builder additionalProperty(String key, Object value) { diff --git a/src/main/java/com/deepgram/types/SharedTopicsResults.java b/src/main/java/com/deepgram/types/SharedTopicsResults.java new file mode 100644 index 0000000..d25c8cc --- /dev/null +++ b/src/main/java/com/deepgram/types/SharedTopicsResults.java @@ -0,0 +1,105 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.types; + +import com.deepgram.core.ObjectMappers; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.annotation.Nulls; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonDeserialize(builder = SharedTopicsResults.Builder.class) +public final class SharedTopicsResults { + private final Optional topics; + + private final Map additionalProperties; + + private SharedTopicsResults(Optional topics, Map additionalProperties) { + this.topics = topics; + this.additionalProperties = additionalProperties; + } + + @JsonProperty("topics") + public Optional getTopics() { + return topics; + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof SharedTopicsResults && equalTo((SharedTopicsResults) other); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + private boolean equalTo(SharedTopicsResults other) { + return topics.equals(other.topics); + } + + @java.lang.Override + public int hashCode() { + return Objects.hash(this.topics); + } + + @java.lang.Override + public String toString() { + return ObjectMappers.stringify(this); + } + + public static Builder builder() { + return new Builder(); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static final class Builder { + private Optional topics = Optional.empty(); + + @JsonAnySetter + private Map additionalProperties = new HashMap<>(); + + private Builder() {} + + public Builder from(SharedTopicsResults other) { + topics(other.getTopics()); + return this; + } + + @JsonSetter(value = "topics", nulls = Nulls.SKIP) + public Builder topics(Optional topics) { + this.topics = topics; + return this; + } + + public Builder topics(SharedTopicsResultsTopics topics) { + this.topics = Optional.ofNullable(topics); + return this; + } + + public SharedTopicsResults build() { + return new SharedTopicsResults(topics, additionalProperties); + } + + public Builder additionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + return this; + } + + public Builder additionalProperties(Map additionalProperties) { + this.additionalProperties.putAll(additionalProperties); + return this; + } + } +} diff --git a/src/main/java/com/deepgram/types/SharedTopicsResultsTopics.java b/src/main/java/com/deepgram/types/SharedTopicsResultsTopics.java new file mode 100644 index 0000000..e3a1cbb --- /dev/null +++ b/src/main/java/com/deepgram/types/SharedTopicsResultsTopics.java @@ -0,0 +1,107 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.types; + +import com.deepgram.core.ObjectMappers; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.annotation.Nulls; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonDeserialize(builder = SharedTopicsResultsTopics.Builder.class) +public final class SharedTopicsResultsTopics { + private final Optional> segments; + + private final Map additionalProperties; + + private SharedTopicsResultsTopics( + Optional> segments, Map additionalProperties) { + this.segments = segments; + this.additionalProperties = additionalProperties; + } + + @JsonProperty("segments") + public Optional> getSegments() { + return segments; + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof SharedTopicsResultsTopics && equalTo((SharedTopicsResultsTopics) other); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + private boolean equalTo(SharedTopicsResultsTopics other) { + return segments.equals(other.segments); + } + + @java.lang.Override + public int hashCode() { + return Objects.hash(this.segments); + } + + @java.lang.Override + public String toString() { + return ObjectMappers.stringify(this); + } + + public static Builder builder() { + return new Builder(); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static final class Builder { + private Optional> segments = Optional.empty(); + + @JsonAnySetter + private Map additionalProperties = new HashMap<>(); + + private Builder() {} + + public Builder from(SharedTopicsResultsTopics other) { + segments(other.getSegments()); + return this; + } + + @JsonSetter(value = "segments", nulls = Nulls.SKIP) + public Builder segments(Optional> segments) { + this.segments = segments; + return this; + } + + public Builder segments(List segments) { + this.segments = Optional.ofNullable(segments); + return this; + } + + public SharedTopicsResultsTopics build() { + return new SharedTopicsResultsTopics(segments, additionalProperties); + } + + public Builder additionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + return this; + } + + public Builder additionalProperties(Map additionalProperties) { + this.additionalProperties.putAll(additionalProperties); + return this; + } + } +} diff --git a/src/main/java/com/deepgram/types/SharedTopicsSegmentsItem.java b/src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItem.java similarity index 78% rename from src/main/java/com/deepgram/types/SharedTopicsSegmentsItem.java rename to src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItem.java index b479076..19cd942 100644 --- a/src/main/java/com/deepgram/types/SharedTopicsSegmentsItem.java +++ b/src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItem.java @@ -19,23 +19,23 @@ import java.util.Optional; @JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = SharedTopicsSegmentsItem.Builder.class) -public final class SharedTopicsSegmentsItem { +@JsonDeserialize(builder = SharedTopicsResultsTopicsSegmentsItem.Builder.class) +public final class SharedTopicsResultsTopicsSegmentsItem { private final Optional text; private final Optional startWord; private final Optional endWord; - private final Optional> topics; + private final Optional> topics; private final Map additionalProperties; - private SharedTopicsSegmentsItem( + private SharedTopicsResultsTopicsSegmentsItem( Optional text, Optional startWord, Optional endWord, - Optional> topics, + Optional> topics, Map additionalProperties) { this.text = text; this.startWord = startWord; @@ -60,14 +60,15 @@ public Optional getEndWord() { } @JsonProperty("topics") - public Optional> getTopics() { + public Optional> getTopics() { return topics; } @java.lang.Override public boolean equals(Object other) { if (this == other) return true; - return other instanceof SharedTopicsSegmentsItem && equalTo((SharedTopicsSegmentsItem) other); + return other instanceof SharedTopicsResultsTopicsSegmentsItem + && equalTo((SharedTopicsResultsTopicsSegmentsItem) other); } @JsonAnyGetter @@ -75,7 +76,7 @@ public Map getAdditionalProperties() { return this.additionalProperties; } - private boolean equalTo(SharedTopicsSegmentsItem other) { + private boolean equalTo(SharedTopicsResultsTopicsSegmentsItem other) { return text.equals(other.text) && startWord.equals(other.startWord) && endWord.equals(other.endWord) @@ -104,14 +105,14 @@ public static final class Builder { private Optional endWord = Optional.empty(); - private Optional> topics = Optional.empty(); + private Optional> topics = Optional.empty(); @JsonAnySetter private Map additionalProperties = new HashMap<>(); private Builder() {} - public Builder from(SharedTopicsSegmentsItem other) { + public Builder from(SharedTopicsResultsTopicsSegmentsItem other) { text(other.getText()); startWord(other.getStartWord()); endWord(other.getEndWord()); @@ -153,18 +154,18 @@ public Builder endWord(Double endWord) { } @JsonSetter(value = "topics", nulls = Nulls.SKIP) - public Builder topics(Optional> topics) { + public Builder topics(Optional> topics) { this.topics = topics; return this; } - public Builder topics(List topics) { + public Builder topics(List topics) { this.topics = Optional.ofNullable(topics); return this; } - public SharedTopicsSegmentsItem build() { - return new SharedTopicsSegmentsItem(text, startWord, endWord, topics, additionalProperties); + public SharedTopicsResultsTopicsSegmentsItem build() { + return new SharedTopicsResultsTopicsSegmentsItem(text, startWord, endWord, topics, additionalProperties); } public Builder additionalProperty(String key, Object value) { diff --git a/src/main/java/com/deepgram/types/SharedTopicsSegmentsItemTopicsItem.java b/src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItemTopicsItem.java similarity index 82% rename from src/main/java/com/deepgram/types/SharedTopicsSegmentsItemTopicsItem.java rename to src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItemTopicsItem.java index 03464d2..3721cd8 100644 --- a/src/main/java/com/deepgram/types/SharedTopicsSegmentsItemTopicsItem.java +++ b/src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItemTopicsItem.java @@ -18,15 +18,15 @@ import java.util.Optional; @JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = SharedTopicsSegmentsItemTopicsItem.Builder.class) -public final class SharedTopicsSegmentsItemTopicsItem { +@JsonDeserialize(builder = SharedTopicsResultsTopicsSegmentsItemTopicsItem.Builder.class) +public final class SharedTopicsResultsTopicsSegmentsItemTopicsItem { private final Optional topic; private final Optional confidenceScore; private final Map additionalProperties; - private SharedTopicsSegmentsItemTopicsItem( + private SharedTopicsResultsTopicsSegmentsItemTopicsItem( Optional topic, Optional confidenceScore, Map additionalProperties) { this.topic = topic; this.confidenceScore = confidenceScore; @@ -46,8 +46,8 @@ public Optional getConfidenceScore() { @java.lang.Override public boolean equals(Object other) { if (this == other) return true; - return other instanceof SharedTopicsSegmentsItemTopicsItem - && equalTo((SharedTopicsSegmentsItemTopicsItem) other); + return other instanceof SharedTopicsResultsTopicsSegmentsItemTopicsItem + && equalTo((SharedTopicsResultsTopicsSegmentsItemTopicsItem) other); } @JsonAnyGetter @@ -55,7 +55,7 @@ public Map getAdditionalProperties() { return this.additionalProperties; } - private boolean equalTo(SharedTopicsSegmentsItemTopicsItem other) { + private boolean equalTo(SharedTopicsResultsTopicsSegmentsItemTopicsItem other) { return topic.equals(other.topic) && confidenceScore.equals(other.confidenceScore); } @@ -84,7 +84,7 @@ public static final class Builder { private Builder() {} - public Builder from(SharedTopicsSegmentsItemTopicsItem other) { + public Builder from(SharedTopicsResultsTopicsSegmentsItemTopicsItem other) { topic(other.getTopic()); confidenceScore(other.getConfidenceScore()); return this; @@ -112,8 +112,8 @@ public Builder confidenceScore(Float confidenceScore) { return this; } - public SharedTopicsSegmentsItemTopicsItem build() { - return new SharedTopicsSegmentsItemTopicsItem(topic, confidenceScore, additionalProperties); + public SharedTopicsResultsTopicsSegmentsItemTopicsItem build() { + return new SharedTopicsResultsTopicsSegmentsItemTopicsItem(topic, confidenceScore, additionalProperties); } public Builder additionalProperty(String key, Object value) { From 1ba658d4c9ada0faf58b9cd0aa8283da5352cb63 Mon Sep 17 00:00:00 2001 From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com> Date: Wed, 14 Oct 2026 10:58:19 +0000 Subject: [PATCH 4/8] SDK regeneration --- .fern/metadata.json | 4 +- .../com/deepgram/AsyncDeepgramApiClient.java | 5 +- .../java/com/deepgram/DeepgramApiClient.java | 5 +- .../java/com/deepgram/core/ClientOptions.java | 67 +++++ .../deepgram/core/OkHttpWebSocketFactory.java | 22 ++ .../core/ReconnectingWebSocketListener.java | 34 ++- .../com/deepgram/core/RetryInterceptor.java | 66 ++++- .../types/AgentV1CustomFromThinkProvider.java | 125 ++++++++ .../types/AgentV1CustomToThinkProvider.java | 125 ++++++++ .../agent/v1/websocket/V1WebSocketClient.java | 65 ++++- .../listen/v1/types/ListenV1Configure.java | 167 +++++++++++ .../listen/v1/types/ListenV1Error.java | 267 ++++++++++++++++++ .../v1/websocket/V1WebSocketClient.java | 65 ++++- .../v2/types/ListenV2ConfigureFailure.java | 100 ++++++- .../listen/v2/types/ListenV2Warning.java | 247 ++++++++++++++++ .../v2/websocket/V2WebSocketClient.java | 57 +++- .../speak/v1/websocket/V1WebSocketClient.java | 29 +- .../v2/audio/requests/SpeakV2Request.java | 14 +- .../v2/types/SpeakV2ConfigureFailure.java | 6 +- .../v2/types/SpeakV2ConfigureFailureCode.java | 11 + .../speak/v2/types/SpeakV2Error.java | 6 +- .../speak/v2/types/SpeakV2Speak.java | 6 +- .../SpeakV2SpeechInterruptedMetadata.java | 6 +- ...echInterruptedMetadataControlsApplied.java | 18 +- .../speak/v2/types/SpeakV2SpeechMetadata.java | 6 +- .../SpeakV2SpeechMetadataControlsApplied.java | 18 +- .../speak/v2/types/SpeakV2Warning.java | 9 +- .../speak/v2/websocket/V2WebSocketClient.java | 29 +- .../com/deepgram/types/SharedIntents.java | 34 +-- .../deepgram/types/SharedIntentsResults.java | 106 ------- .../types/SharedIntentsResultsIntents.java | 108 ------- ...em.java => SharedIntentsSegmentsItem.java} | 29 +- ...SharedIntentsSegmentsItemIntentsItem.java} | 19 +- .../java/com/deepgram/types/SharedTopics.java | 33 +-- .../deepgram/types/SharedTopicsResults.java | 105 ------- .../types/SharedTopicsResultsTopics.java | 107 ------- ...tem.java => SharedTopicsSegmentsItem.java} | 29 +- ...> SharedTopicsSegmentsItemTopicsItem.java} | 18 +- 38 files changed, 1565 insertions(+), 602 deletions(-) create mode 100644 src/main/java/com/deepgram/resources/agent/v1/types/AgentV1CustomFromThinkProvider.java create mode 100644 src/main/java/com/deepgram/resources/agent/v1/types/AgentV1CustomToThinkProvider.java create mode 100644 src/main/java/com/deepgram/resources/listen/v1/types/ListenV1Configure.java create mode 100644 src/main/java/com/deepgram/resources/listen/v1/types/ListenV1Error.java create mode 100644 src/main/java/com/deepgram/resources/listen/v2/types/ListenV2Warning.java delete mode 100644 src/main/java/com/deepgram/types/SharedIntentsResults.java delete mode 100644 src/main/java/com/deepgram/types/SharedIntentsResultsIntents.java rename src/main/java/com/deepgram/types/{SharedIntentsResultsIntentsSegmentsItem.java => SharedIntentsSegmentsItem.java} (78%) rename src/main/java/com/deepgram/types/{SharedIntentsResultsIntentsSegmentsItemIntentsItem.java => SharedIntentsSegmentsItemIntentsItem.java} (81%) delete mode 100644 src/main/java/com/deepgram/types/SharedTopicsResults.java delete mode 100644 src/main/java/com/deepgram/types/SharedTopicsResultsTopics.java rename src/main/java/com/deepgram/types/{SharedTopicsResultsTopicsSegmentsItem.java => SharedTopicsSegmentsItem.java} (78%) rename src/main/java/com/deepgram/types/{SharedTopicsResultsTopicsSegmentsItemTopicsItem.java => SharedTopicsSegmentsItemTopicsItem.java} (82%) diff --git a/.fern/metadata.json b/.fern/metadata.json index 65cffab..d4e496a 100644 --- a/.fern/metadata.json +++ b/.fern/metadata.json @@ -1,7 +1,7 @@ { "cliVersion": "5.95.1", "generatorName": "fernapi/fern-java-sdk", - "generatorVersion": "4.21.0", + "generatorVersion": "4.23.1", "generatorConfig": { "package-prefix": "com.deepgram", "base-api-exception-class-name": "DeepgramHttpException", @@ -12,7 +12,7 @@ "enable-wire-tests": true, "runtime-version": true }, - "originGitCommit": "97e7b8ba56fdf31596232836ed4849148d72813e", + "originGitCommit": "59a99c27e5f91158072fc98b3567fc88c3315f67", "originGitCommitIsDirty": true, "invokedBy": "manual", "sdkVersion": "0.11.2" diff --git a/src/main/java/com/deepgram/AsyncDeepgramApiClient.java b/src/main/java/com/deepgram/AsyncDeepgramApiClient.java index c2aa87e..0ae6c11 100644 --- a/src/main/java/com/deepgram/AsyncDeepgramApiClient.java +++ b/src/main/java/com/deepgram/AsyncDeepgramApiClient.java @@ -79,8 +79,9 @@ public AsyncVoiceAgentClient voiceAgent() { } /** - * Releases resources owned by this client. See {@code ClientOptions.close()} for what is - * and is not released. + * Releases resources owned by this client: any WebSocket clients still connected through + * it are disconnected first, then the SDK-owned HTTP client is shut down. See + * {@code ClientOptions.close()} for what is and is not released. */ @Override public void close() { diff --git a/src/main/java/com/deepgram/DeepgramApiClient.java b/src/main/java/com/deepgram/DeepgramApiClient.java index ccb0d4a..a67528f 100644 --- a/src/main/java/com/deepgram/DeepgramApiClient.java +++ b/src/main/java/com/deepgram/DeepgramApiClient.java @@ -79,8 +79,9 @@ public VoiceAgentClient voiceAgent() { } /** - * Releases resources owned by this client. See {@code ClientOptions.close()} for what is - * and is not released. + * Releases resources owned by this client: any WebSocket clients still connected through + * it are disconnected first, then the SDK-owned HTTP client is shut down. See + * {@code ClientOptions.close()} for what is and is not released. */ @Override public void close() { diff --git a/src/main/java/com/deepgram/core/ClientOptions.java b/src/main/java/com/deepgram/core/ClientOptions.java index 0c075cc..e0ad853 100644 --- a/src/main/java/com/deepgram/core/ClientOptions.java +++ b/src/main/java/com/deepgram/core/ClientOptions.java @@ -3,10 +3,14 @@ */ package com.deepgram.core; +import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Optional; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; import okhttp3.OkHttpClient; @@ -21,6 +25,10 @@ public final class ClientOptions { private final boolean ownsHttpClient; + private final AtomicBoolean closed; + + private final Set openWebSockets; + private final int timeout; private final int maxRetries; @@ -41,6 +49,8 @@ private ClientOptions( Map> headerSuppliers, OkHttpClient httpClient, boolean ownsHttpClient, + AtomicBoolean closed, + Set openWebSockets, int timeout, int maxRetries, Optional initialRetryDelayMillis, @@ -62,6 +72,8 @@ private ClientOptions( this.headerSuppliers = headerSuppliers; this.httpClient = httpClient; this.ownsHttpClient = ownsHttpClient; + this.closed = closed; + this.openWebSockets = openWebSockets; this.timeout = timeout; this.maxRetries = maxRetries; this.initialRetryDelayMillis = initialRetryDelayMillis; @@ -141,8 +153,24 @@ public Optional retryJitterFactor() { * returns fails with a {@code RejectedExecutionException}. Options derived from this one via * {@code Builder.from(...)} share the same dispatcher and connection pool, so closing either * releases them for both. Calling this method more than once has no further effect. + *

+ * WebSocket clients created from this client that are still connected are disconnected + * first (whether or not the OkHttpClient is owned), so they stop reconnecting before the + * dispatcher goes away. Any WebSocket connect or reconnect attempted afterwards fails with + * an {@code IllegalStateException} explaining that the client has been closed. */ public void close() { + if (!this.closed.compareAndSet(false, true)) { + return; + } + for (AutoCloseable webSocket : new ArrayList<>(this.openWebSockets)) { + try { + webSocket.close(); + } catch (Exception e) { + // best effort; keep closing the remaining sockets and the HTTP client + } + } + this.openWebSockets.clear(); if (!this.ownsHttpClient) { return; } @@ -150,6 +178,33 @@ public void close() { this.httpClient.connectionPool().evictAll(); } + /** + * Returns whether {@link #close()} has been called on this client. + */ + public boolean isClosed() { + return this.closed.get(); + } + + /** + * Tracks a connected WebSocket client so that {@link #close()} disconnects it. + * + * @throws IllegalStateException if this client has already been closed + */ + public void registerWebSocket(AutoCloseable webSocket) { + this.openWebSockets.add(webSocket); + if (this.closed.get()) { + this.openWebSockets.remove(webSocket); + throw new IllegalStateException("root client has been closed"); + } + } + + /** + * Stops tracking a WebSocket client that has been disconnected. + */ + public void unregisterWebSocket(AutoCloseable webSocket) { + this.openWebSockets.remove(webSocket); + } + public Optional webSocketFactory() { return this.webSocketFactory; } @@ -183,6 +238,10 @@ public static class Builder { private boolean ownsHttpClient = true; + private AtomicBoolean closed; + + private Set openWebSockets; + private Optional logging = Optional.empty(); private Optional webSocketFactory = Optional.empty(); @@ -308,12 +367,18 @@ public ClientOptions build() { this.httpClient = httpClientBuilder.build(); this.timeout = Optional.of(httpClient.callTimeoutMillis() / 1000); + AtomicBoolean closedToUse = this.closed != null ? this.closed : new AtomicBoolean(false); + Set openWebSocketsToUse = + this.openWebSockets != null ? this.openWebSockets : ConcurrentHashMap.newKeySet(); + return new ClientOptions( environment, headers, headerSuppliers, httpClient, this.ownsHttpClient, + closedToUse, + openWebSocketsToUse, this.timeout.get(), this.maxRetries, this.initialRetryDelayMillis, @@ -332,6 +397,8 @@ public static Builder from(ClientOptions clientOptions) { builder.timeout = Optional.of(clientOptions.timeout(null)); builder.httpClient = clientOptions.httpClient(); builder.ownsHttpClient = clientOptions.ownsHttpClient; + builder.closed = clientOptions.closed; + builder.openWebSockets = clientOptions.openWebSockets; builder.headers.putAll(clientOptions.headers); builder.headerSuppliers.putAll(clientOptions.headerSuppliers); builder.maxRetries = clientOptions.maxRetries(); diff --git a/src/main/java/com/deepgram/core/OkHttpWebSocketFactory.java b/src/main/java/com/deepgram/core/OkHttpWebSocketFactory.java index 70e6c86..30653bc 100644 --- a/src/main/java/com/deepgram/core/OkHttpWebSocketFactory.java +++ b/src/main/java/com/deepgram/core/OkHttpWebSocketFactory.java @@ -3,6 +3,7 @@ */ package com.deepgram.core; +import java.util.function.BooleanSupplier; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.WebSocket; @@ -15,17 +16,38 @@ public final class OkHttpWebSocketFactory implements WebSocketFactory { private final OkHttpClient okHttpClient; + private final BooleanSupplier closedCheck; + /** * Creates a new OkHttpWebSocketFactory with the specified OkHttpClient. * * @param okHttpClient The OkHttpClient instance to use for creating WebSockets */ public OkHttpWebSocketFactory(OkHttpClient okHttpClient) { + this(okHttpClient, () -> false); + } + + /** + * Creates a new OkHttpWebSocketFactory that refuses to open WebSockets once the owning + * client has been closed. + * + * @param okHttpClient The OkHttpClient instance to use for creating WebSockets + * @param closedCheck Returns true once the owning client has been closed (e.g. + * {@code clientOptions::isClosed}) + */ + public OkHttpWebSocketFactory(OkHttpClient okHttpClient, BooleanSupplier closedCheck) { this.okHttpClient = okHttpClient; + this.closedCheck = closedCheck; } + /** + * @throws IllegalStateException if the owning client has been closed + */ @Override public WebSocket create(Request request, WebSocketListener listener) { + if (closedCheck.getAsBoolean()) { + throw new IllegalStateException("root client has been closed"); + } return okHttpClient.newWebSocket(request, listener); } } diff --git a/src/main/java/com/deepgram/core/ReconnectingWebSocketListener.java b/src/main/java/com/deepgram/core/ReconnectingWebSocketListener.java index c6a2ebc..dc32da2 100644 --- a/src/main/java/com/deepgram/core/ReconnectingWebSocketListener.java +++ b/src/main/java/com/deepgram/core/ReconnectingWebSocketListener.java @@ -14,6 +14,7 @@ import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.BooleanSupplier; import java.util.function.Consumer; import java.util.function.Supplier; import okhttp3.Response; @@ -54,6 +55,8 @@ public abstract class ReconnectingWebSocketListener extends WebSocketListener { private final Supplier connectionSupplier; + private final BooleanSupplier closedCheck; + /** * Creates a new reconnecting WebSocket listener. * @@ -62,12 +65,29 @@ public abstract class ReconnectingWebSocketListener extends WebSocketListener { */ public ReconnectingWebSocketListener( ReconnectingWebSocketListener.ReconnectOptions options, Supplier connectionSupplier) { + this(options, connectionSupplier, () -> false); + } + + /** + * Creates a new reconnecting WebSocket listener. + * + * @param options Reconnection configuration options + * @param connectionSupplier Supplier that creates new WebSocket connections + * @param closedCheck Returns true once the owning client has been closed; connect and + * reconnect attempts made after that point fail with an {@link IllegalStateException} + * instead of being retried + */ + public ReconnectingWebSocketListener( + ReconnectingWebSocketListener.ReconnectOptions options, + Supplier connectionSupplier, + BooleanSupplier closedCheck) { this.minReconnectionDelayMs = options.minReconnectionDelayMs; this.maxReconnectionDelayMs = options.maxReconnectionDelayMs; this.reconnectionDelayGrowFactor = options.reconnectionDelayGrowFactor; this.maxRetries = options.maxRetries; this.maxEnqueuedMessages = options.maxEnqueuedMessages; this.connectionSupplier = connectionSupplier; + this.closedCheck = closedCheck; } /** @@ -82,11 +102,18 @@ public ReconnectingWebSocketListener( * - TimeoutException: Includes retry attempt context * - InterruptedException: Preserves thread interruption status * - ExecutionException: Extracts actual cause and adds context + * - Owning client closed: reports an IllegalStateException once and stops reconnecting */ public void connect() { if (!connectLock.compareAndSet(false, true)) { return; } + if (closedCheck.getAsBoolean()) { + shouldReconnect.set(false); + connectLock.set(false); + onWebSocketFailure(null, new IllegalStateException("root client has been closed"), null); + return; + } if (retryCount.get() >= maxRetries) { connectLock.set(false); return; @@ -100,7 +127,7 @@ public void connect() { TimeoutException timeoutError = new TimeoutException("WebSocket connection timeout after " + 4000 + " milliseconds" + (retryCount.get() > 0 - ? " (retry attempt #" + retryCount.get() + ? " (retry attempt #" + retryCount.get() + ")" : " (initial connection attempt)")); onWebSocketFailure(null, timeoutError, null); if (shouldReconnect.get()) { @@ -397,8 +424,13 @@ private long getNextDelay() { /** * Schedules a reconnection attempt with appropriate delay. * Increments retry count and uses exponential backoff. + * Does nothing once the owning client has been closed. */ private void scheduleReconnect() { + if (closedCheck.getAsBoolean()) { + shouldReconnect.set(false); + return; + } retryCount.incrementAndGet(); long delay = getNextDelay(); reconnectExecutor.schedule(this::connect, delay, MILLISECONDS); diff --git a/src/main/java/com/deepgram/core/RetryInterceptor.java b/src/main/java/com/deepgram/core/RetryInterceptor.java index a0959bb..aad032c 100644 --- a/src/main/java/com/deepgram/core/RetryInterceptor.java +++ b/src/main/java/com/deepgram/core/RetryInterceptor.java @@ -10,9 +10,13 @@ import java.time.format.DateTimeParseException; import java.util.Optional; import java.util.Random; +import okhttp3.Call; import okhttp3.Interceptor; import okhttp3.Request; import okhttp3.Response; +import okhttp3.ResponseBody; +import okio.AsyncTimeout; +import okio.Timeout; public class RetryInterceptor implements Interceptor { @@ -78,13 +82,28 @@ private Response retryChain(Response response, Chain chain, int maxRetries) thro ExponentialBackoff backoff = new ExponentialBackoff(maxRetries); Optional nextBackoff = backoff.nextBackoff(response); while (nextBackoff.isPresent()) { + response = bufferResponse(response); + Optional callTimeout = suspendCallTimeout(chain); try { Thread.sleep(nextBackoff.get().toMillis()); } catch (InterruptedException e) { + response.close(); throw new IOException("Interrupted while trying request", e); + } finally { + callTimeout.ifPresent(AsyncTimeout::enter); + } + Response nextResponse; + try { + nextResponse = chain.proceed(chain.request()); + } catch (IOException e) { + // A retry attempt failed with a transport error (connection reset, unreachable host, ...). The + // error is intentionally dropped: the response already received from the API is more actionable. + // Note that a call-timeout expiry or an explicit cancel() also ends up here, but OkHttp then + // discards whatever the interceptor chain returns and reports the cancellation itself. + return response; } response.close(); - response = chain.proceed(chain.request()); + response = nextResponse; if (shouldRetry(response.code())) { nextBackoff = backoff.nextBackoff(response); } else { @@ -95,6 +114,51 @@ private Response retryChain(Response response, Chain chain, int maxRetries) thro return response; } + /** + * Pauses the OkHttp call timeout so that it applies to each attempt individually rather than to the whole + * retry loop: the backoff wait (e.g. a {@code Retry-After} the size of the call timeout) does not consume the + * budget of the next attempt, and each attempt starts with a fresh budget once {@link AsyncTimeout#enter()} + * is called again. + * + *

{@link AsyncTimeout#exit()} and {@link AsyncTimeout#enter()} must stay strictly paired: {@code exit()} on + * a timeout that is not armed is a no-op, but {@code enter()} on one that is already armed throws + * {@code IllegalStateException}. Every caller must re-enter the returned timeout exactly once, on all paths. + */ + private static Optional suspendCallTimeout(Chain chain) { + Call call = chain.call(); + if (call == null) { + return Optional.empty(); + } + Timeout timeout = call.timeout(); + if (!(timeout instanceof AsyncTimeout)) { + return Optional.empty(); + } + AsyncTimeout callTimeout = (AsyncTimeout) timeout; + callTimeout.exit(); + return Optional.of(callTimeout); + } + + /** + * Reads the body into memory so the response stays usable after the underlying connection + * is released or cancelled by a later attempt. + */ + private static Response bufferResponse(Response response) { + ResponseBody body = response.body(); + if (body == null) { + return response; + } + try { + byte[] bytes = body.bytes(); + Response buffered = response.newBuilder() + .body(ResponseBody.create(bytes, body.contentType())) + .build(); + response.close(); + return buffered; + } catch (IOException e) { + return response; + } + } + /** * Calculates the retry delay from response headers, with fallback to exponential backoff. * Priority: Retry-After > X-RateLimit-Reset > Exponential Backoff diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1CustomFromThinkProvider.java b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1CustomFromThinkProvider.java new file mode 100644 index 0000000..777078c --- /dev/null +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1CustomFromThinkProvider.java @@ -0,0 +1,125 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.resources.agent.v1.types; + +import com.deepgram.core.ObjectMappers; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonDeserialize(builder = AgentV1CustomFromThinkProvider.Builder.class) +public final class AgentV1CustomFromThinkProvider { + private final Object content; + + private final Map additionalProperties; + + private AgentV1CustomFromThinkProvider(Object content, Map additionalProperties) { + this.content = content; + this.additionalProperties = additionalProperties; + } + + /** + * @return Message type identifier for a custom payload returned by the think provider + */ + @JsonProperty("type") + public String getType() { + return "__customFromThinkProvider"; + } + + @JsonProperty("content") + public Object getContent() { + return content; + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof AgentV1CustomFromThinkProvider && equalTo((AgentV1CustomFromThinkProvider) other); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + private boolean equalTo(AgentV1CustomFromThinkProvider other) { + return content.equals(other.content); + } + + @java.lang.Override + public int hashCode() { + return Objects.hash(this.content); + } + + @java.lang.Override + public String toString() { + return ObjectMappers.stringify(this); + } + + public static ContentStage builder() { + return new Builder(); + } + + public interface ContentStage { + _FinalStage content(Object content); + + Builder from(AgentV1CustomFromThinkProvider other); + } + + public interface _FinalStage { + AgentV1CustomFromThinkProvider build(); + + _FinalStage additionalProperty(String key, Object value); + + _FinalStage additionalProperties(Map additionalProperties); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static final class Builder implements ContentStage, _FinalStage { + private Object content; + + @JsonAnySetter + private Map additionalProperties = new HashMap<>(); + + private Builder() {} + + @java.lang.Override + public Builder from(AgentV1CustomFromThinkProvider other) { + content(other.getContent()); + return this; + } + + @java.lang.Override + @JsonSetter("content") + public _FinalStage content(Object content) { + this.content = content; + return this; + } + + @java.lang.Override + public AgentV1CustomFromThinkProvider build() { + return new AgentV1CustomFromThinkProvider(content, additionalProperties); + } + + @java.lang.Override + public Builder additionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + return this; + } + + @java.lang.Override + public Builder additionalProperties(Map additionalProperties) { + this.additionalProperties.putAll(additionalProperties); + return this; + } + } +} diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1CustomToThinkProvider.java b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1CustomToThinkProvider.java new file mode 100644 index 0000000..5dc5b4b --- /dev/null +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1CustomToThinkProvider.java @@ -0,0 +1,125 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.resources.agent.v1.types; + +import com.deepgram.core.ObjectMappers; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonDeserialize(builder = AgentV1CustomToThinkProvider.Builder.class) +public final class AgentV1CustomToThinkProvider { + private final Object content; + + private final Map additionalProperties; + + private AgentV1CustomToThinkProvider(Object content, Map additionalProperties) { + this.content = content; + this.additionalProperties = additionalProperties; + } + + /** + * @return Message type identifier for sending a custom payload to the think provider + */ + @JsonProperty("type") + public String getType() { + return "__customToThinkProvider"; + } + + @JsonProperty("content") + public Object getContent() { + return content; + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof AgentV1CustomToThinkProvider && equalTo((AgentV1CustomToThinkProvider) other); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + private boolean equalTo(AgentV1CustomToThinkProvider other) { + return content.equals(other.content); + } + + @java.lang.Override + public int hashCode() { + return Objects.hash(this.content); + } + + @java.lang.Override + public String toString() { + return ObjectMappers.stringify(this); + } + + public static ContentStage builder() { + return new Builder(); + } + + public interface ContentStage { + _FinalStage content(Object content); + + Builder from(AgentV1CustomToThinkProvider other); + } + + public interface _FinalStage { + AgentV1CustomToThinkProvider build(); + + _FinalStage additionalProperty(String key, Object value); + + _FinalStage additionalProperties(Map additionalProperties); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static final class Builder implements ContentStage, _FinalStage { + private Object content; + + @JsonAnySetter + private Map additionalProperties = new HashMap<>(); + + private Builder() {} + + @java.lang.Override + public Builder from(AgentV1CustomToThinkProvider other) { + content(other.getContent()); + return this; + } + + @java.lang.Override + @JsonSetter("content") + public _FinalStage content(Object content) { + this.content = content; + return this; + } + + @java.lang.Override + public AgentV1CustomToThinkProvider build() { + return new AgentV1CustomToThinkProvider(content, additionalProperties); + } + + @java.lang.Override + public Builder additionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + return this; + } + + @java.lang.Override + public Builder additionalProperties(Map additionalProperties) { + this.additionalProperties.putAll(additionalProperties); + return this; + } + } +} diff --git a/src/main/java/com/deepgram/resources/agent/v1/websocket/V1WebSocketClient.java b/src/main/java/com/deepgram/resources/agent/v1/websocket/V1WebSocketClient.java index 1a5c224..1aa1b9d 100644 --- a/src/main/java/com/deepgram/resources/agent/v1/websocket/V1WebSocketClient.java +++ b/src/main/java/com/deepgram/resources/agent/v1/websocket/V1WebSocketClient.java @@ -13,6 +13,8 @@ import com.deepgram.resources.agent.v1.types.AgentV1AgentStartedSpeaking; import com.deepgram.resources.agent.v1.types.AgentV1AgentThinking; import com.deepgram.resources.agent.v1.types.AgentV1ConversationText; +import com.deepgram.resources.agent.v1.types.AgentV1CustomFromThinkProvider; +import com.deepgram.resources.agent.v1.types.AgentV1CustomToThinkProvider; import com.deepgram.resources.agent.v1.types.AgentV1Error; import com.deepgram.resources.agent.v1.types.AgentV1ForceEndTurn; import com.deepgram.resources.agent.v1.types.AgentV1FunctionCallCancelled; @@ -111,6 +113,8 @@ public class V1WebSocketClient implements AutoCloseable { private volatile Consumer agentAudioDoneHandler; + private volatile Consumer customFromThinkProviderHandler; + private volatile Consumer errorHandler; private volatile Consumer warningHandler; @@ -160,13 +164,22 @@ public CompletableFuture connect() { ? this.reconnectOptions : ReconnectingWebSocketListener.ReconnectOptions.builder().build(); this.reconnectingListener = - new ReconnectingWebSocketListener(reconnectOpts, () -> { - if (clientOptions.webSocketFactory().isPresent()) { - return clientOptions.webSocketFactory().get().create(request, this.reconnectingListener); - } else { - return okHttpClient.newWebSocket(request, this.reconnectingListener); - } - }) { + new ReconnectingWebSocketListener( + reconnectOpts, + () -> { + if (clientOptions.isClosed()) { + throw new IllegalStateException("root client has been closed"); + } + if (clientOptions.webSocketFactory().isPresent()) { + return clientOptions + .webSocketFactory() + .get() + .create(request, this.reconnectingListener); + } else { + return okHttpClient.newWebSocket(request, this.reconnectingListener); + } + }, + clientOptions::isClosed) { @Override protected void onWebSocketOpen(WebSocket webSocket, Response response) { readyState = WebSocketReadyState.OPEN; @@ -205,6 +218,7 @@ protected void onWebSocketClosed(WebSocket webSocket, int code, String reason) { } } }; + clientOptions.registerWebSocket(this); reconnectingListener.connect(); return connectionFuture; } @@ -213,7 +227,10 @@ protected void onWebSocketClosed(WebSocket webSocket, int code, String reason) { * Disconnects the WebSocket connection and releases resources. */ public void disconnect() { - reconnectingListener.disconnect(); + clientOptions.unregisterWebSocket(this); + if (reconnectingListener != null) { + reconnectingListener.disconnect(); + } if (timeoutExecutor != null) { timeoutExecutor.shutdownNow(); timeoutExecutor = null; @@ -321,6 +338,15 @@ public CompletableFuture sendForceEndTurn(AgentV1ForceEndTurn message) { return sendMessage(message); } + /** + * Sends an AgentV1CustomToThinkProvider message to the server asynchronously. + * @param message the message to send + * @return a CompletableFuture that completes when the message is sent + */ + public CompletableFuture sendCustomToThinkProvider(AgentV1CustomToThinkProvider message) { + return sendMessage(message); + } + /** * Sends an AgentV1Media message to the server asynchronously. * @param message the message to send @@ -467,6 +493,14 @@ public void onAgentAudioDone(Consumer handler) { this.agentAudioDoneHandler = handler; } + /** + * Registers a handler for AgentV1CustomFromThinkProvider messages from the server. + * @param handler the handler to invoke when a message is received + */ + public void onCustomFromThinkProvider(Consumer handler) { + this.customFromThinkProviderHandler = handler; + } + /** * Registers a handler for AgentV1Error messages from the server. * @param handler the handler to invoke when a message is received @@ -735,6 +769,21 @@ private void handleIncomingMessage(String json) { return; } } + if (node.has("content") + && "__customFromThinkProvider".equals(node.path("type").asText())) { + AgentV1CustomFromThinkProvider customFromThinkProviderHandlerEvent = null; + try { + customFromThinkProviderHandlerEvent = + objectMapper.treeToValue(node, AgentV1CustomFromThinkProvider.class); + } catch (Exception e) { + } + if (customFromThinkProviderHandlerEvent != null) { + if (customFromThinkProviderHandler != null) { + customFromThinkProviderHandler.accept(customFromThinkProviderHandlerEvent); + } + return; + } + } if ("ListenUpdated".equals(node.path("type").asText())) { AgentV1ListenUpdated listenUpdatedHandlerEvent = null; try { diff --git a/src/main/java/com/deepgram/resources/listen/v1/types/ListenV1Configure.java b/src/main/java/com/deepgram/resources/listen/v1/types/ListenV1Configure.java new file mode 100644 index 0000000..4232f3f --- /dev/null +++ b/src/main/java/com/deepgram/resources/listen/v1/types/ListenV1Configure.java @@ -0,0 +1,167 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.resources.listen.v1.types; + +import com.deepgram.core.ObjectMappers; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.annotation.Nulls; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonDeserialize(builder = ListenV1Configure.Builder.class) +public final class ListenV1Configure { + private final Optional> keyterms; + + private final Optional> features; + + private final Map additionalProperties; + + private ListenV1Configure( + Optional> keyterms, + Optional> features, + Map additionalProperties) { + this.keyterms = keyterms; + this.features = features; + this.additionalProperties = additionalProperties; + } + + /** + * @return Message type identifier + */ + @JsonProperty("type") + public String getType() { + return "Configure"; + } + + /** + * @return Replaces the stream's keyterms. Compatible with all Nova-3 models, monolingual and multilingual; on other + * models the server returns an Error with code KeytermsNotSupported. Each array replaces the entire list, + * including keyterms set with the keyterm query parameter. Send an empty array to clear all keyterms. Omit + * the field, or set it to null, to keep the current keyterms. + *

Each entry is a plain term or phrase with no weights or intensifiers. The 500-token keyterm limit that + * applies to the keyterm query parameter also applies to each update. An over-limit update currently stops + * transcription without an Error; after about 30 seconds, the server closes the stream with 1011 + * (NET-0000). Keep each list under the limit and check its size before sending.

+ */ + @JsonProperty("keyterms") + public Optional> getKeyterms() { + return keyterms; + } + + /** + * @return Turns formatting features on or off. Each key is a feature name and each value is a boolean, for + * example {"numerals": true}. + */ + @JsonProperty("features") + public Optional> getFeatures() { + return features; + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof ListenV1Configure && equalTo((ListenV1Configure) other); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + private boolean equalTo(ListenV1Configure other) { + return keyterms.equals(other.keyterms) && features.equals(other.features); + } + + @java.lang.Override + public int hashCode() { + return Objects.hash(this.keyterms, this.features); + } + + @java.lang.Override + public String toString() { + return ObjectMappers.stringify(this); + } + + public static Builder builder() { + return new Builder(); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static final class Builder { + private Optional> keyterms = Optional.empty(); + + private Optional> features = Optional.empty(); + + @JsonAnySetter + private Map additionalProperties = new HashMap<>(); + + private Builder() {} + + public Builder from(ListenV1Configure other) { + keyterms(other.getKeyterms()); + features(other.getFeatures()); + return this; + } + + /** + *

Replaces the stream's keyterms. Compatible with all Nova-3 models, monolingual and multilingual; on other + * models the server returns an Error with code KeytermsNotSupported. Each array replaces the entire list, + * including keyterms set with the keyterm query parameter. Send an empty array to clear all keyterms. Omit + * the field, or set it to null, to keep the current keyterms.

+ *

Each entry is a plain term or phrase with no weights or intensifiers. The 500-token keyterm limit that + * applies to the keyterm query parameter also applies to each update. An over-limit update currently stops + * transcription without an Error; after about 30 seconds, the server closes the stream with 1011 + * (NET-0000). Keep each list under the limit and check its size before sending.

+ */ + @JsonSetter(value = "keyterms", nulls = Nulls.SKIP) + public Builder keyterms(Optional> keyterms) { + this.keyterms = keyterms; + return this; + } + + public Builder keyterms(List keyterms) { + this.keyterms = Optional.ofNullable(keyterms); + return this; + } + + /** + *

Turns formatting features on or off. Each key is a feature name and each value is a boolean, for + * example {"numerals": true}.

+ */ + @JsonSetter(value = "features", nulls = Nulls.SKIP) + public Builder features(Optional> features) { + this.features = features; + return this; + } + + public Builder features(Map features) { + this.features = Optional.ofNullable(features); + return this; + } + + public ListenV1Configure build() { + return new ListenV1Configure(keyterms, features, additionalProperties); + } + + public Builder additionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + return this; + } + + public Builder additionalProperties(Map additionalProperties) { + this.additionalProperties.putAll(additionalProperties); + return this; + } + } +} diff --git a/src/main/java/com/deepgram/resources/listen/v1/types/ListenV1Error.java b/src/main/java/com/deepgram/resources/listen/v1/types/ListenV1Error.java new file mode 100644 index 0000000..fd0a4e0 --- /dev/null +++ b/src/main/java/com/deepgram/resources/listen/v1/types/ListenV1Error.java @@ -0,0 +1,267 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.resources.listen.v1.types; + +import com.deepgram.core.ObjectMappers; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.annotation.Nulls; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import org.jetbrains.annotations.NotNull; + +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonDeserialize(builder = ListenV1Error.Builder.class) +public final class ListenV1Error { + private final String variant; + + private final String description; + + private final Optional code; + + private final Optional message; + + private final Map additionalProperties; + + private ListenV1Error( + String variant, + String description, + Optional code, + Optional message, + Map additionalProperties) { + this.variant = variant; + this.description = description; + this.code = code; + this.message = message; + this.additionalProperties = additionalProperties; + } + + /** + * @return Message type identifier for error responses + */ + @JsonProperty("type") + public String getType() { + return "Error"; + } + + /** + * @return The error category. SchemaError means the server could not parse a client text message. + * InvalidConfigureMessage means the server rejected a Configure message. + */ + @JsonProperty("variant") + public String getVariant() { + return variant; + } + + /** + * @return A human-readable description of what went wrong + */ + @JsonProperty("description") + public String getDescription() { + return description; + } + + /** + * @return Identifies the reason for an InvalidConfigureMessage error, for example KeytermsNotSupported + * when keyterms are sent on a model other than Nova-3. + */ + @JsonProperty("code") + public Optional getCode() { + return code; + } + + /** + * @return For SchemaError, the original client message that could not be parsed + */ + @JsonProperty("message") + public Optional getMessage() { + return message; + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof ListenV1Error && equalTo((ListenV1Error) other); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + private boolean equalTo(ListenV1Error other) { + return variant.equals(other.variant) + && description.equals(other.description) + && code.equals(other.code) + && message.equals(other.message); + } + + @java.lang.Override + public int hashCode() { + return Objects.hash(this.variant, this.description, this.code, this.message); + } + + @java.lang.Override + public String toString() { + return ObjectMappers.stringify(this); + } + + public static VariantStage builder() { + return new Builder(); + } + + public interface VariantStage { + /** + *

The error category. SchemaError means the server could not parse a client text message. + * InvalidConfigureMessage means the server rejected a Configure message.

+ */ + DescriptionStage variant(@NotNull String variant); + + Builder from(ListenV1Error other); + } + + public interface DescriptionStage { + /** + *

A human-readable description of what went wrong

+ */ + _FinalStage description(@NotNull String description); + } + + public interface _FinalStage { + ListenV1Error build(); + + _FinalStage additionalProperty(String key, Object value); + + _FinalStage additionalProperties(Map additionalProperties); + + /** + *

Identifies the reason for an InvalidConfigureMessage error, for example KeytermsNotSupported + * when keyterms are sent on a model other than Nova-3.

+ */ + _FinalStage code(Optional code); + + _FinalStage code(String code); + + /** + *

For SchemaError, the original client message that could not be parsed

+ */ + _FinalStage message(Optional message); + + _FinalStage message(String message); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static final class Builder implements VariantStage, DescriptionStage, _FinalStage { + private String variant; + + private String description; + + private Optional message = Optional.empty(); + + private Optional code = Optional.empty(); + + @JsonAnySetter + private Map additionalProperties = new HashMap<>(); + + private Builder() {} + + @java.lang.Override + public Builder from(ListenV1Error other) { + variant(other.getVariant()); + description(other.getDescription()); + code(other.getCode()); + message(other.getMessage()); + return this; + } + + /** + *

The error category. SchemaError means the server could not parse a client text message. + * InvalidConfigureMessage means the server rejected a Configure message.

+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + @JsonSetter("variant") + public DescriptionStage variant(@NotNull String variant) { + this.variant = Objects.requireNonNull(variant, "variant must not be null"); + return this; + } + + /** + *

A human-readable description of what went wrong

+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + @JsonSetter("description") + public _FinalStage description(@NotNull String description) { + this.description = Objects.requireNonNull(description, "description must not be null"); + return this; + } + + /** + *

For SchemaError, the original client message that could not be parsed

+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + public _FinalStage message(String message) { + this.message = Optional.ofNullable(message); + return this; + } + + /** + *

For SchemaError, the original client message that could not be parsed

+ */ + @java.lang.Override + @JsonSetter(value = "message", nulls = Nulls.SKIP) + public _FinalStage message(Optional message) { + this.message = message; + return this; + } + + /** + *

Identifies the reason for an InvalidConfigureMessage error, for example KeytermsNotSupported + * when keyterms are sent on a model other than Nova-3.

+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + public _FinalStage code(String code) { + this.code = Optional.ofNullable(code); + return this; + } + + /** + *

Identifies the reason for an InvalidConfigureMessage error, for example KeytermsNotSupported + * when keyterms are sent on a model other than Nova-3.

+ */ + @java.lang.Override + @JsonSetter(value = "code", nulls = Nulls.SKIP) + public _FinalStage code(Optional code) { + this.code = code; + return this; + } + + @java.lang.Override + public ListenV1Error build() { + return new ListenV1Error(variant, description, code, message, additionalProperties); + } + + @java.lang.Override + public Builder additionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + return this; + } + + @java.lang.Override + public Builder additionalProperties(Map additionalProperties) { + this.additionalProperties.putAll(additionalProperties); + return this; + } + } +} diff --git a/src/main/java/com/deepgram/resources/listen/v1/websocket/V1WebSocketClient.java b/src/main/java/com/deepgram/resources/listen/v1/websocket/V1WebSocketClient.java index 4952808..a91c4e1 100644 --- a/src/main/java/com/deepgram/resources/listen/v1/websocket/V1WebSocketClient.java +++ b/src/main/java/com/deepgram/resources/listen/v1/websocket/V1WebSocketClient.java @@ -10,6 +10,8 @@ import com.deepgram.core.RequestOptions; import com.deepgram.core.WebSocketReadyState; import com.deepgram.resources.listen.v1.types.ListenV1CloseStream; +import com.deepgram.resources.listen.v1.types.ListenV1Configure; +import com.deepgram.resources.listen.v1.types.ListenV1Error; import com.deepgram.resources.listen.v1.types.ListenV1Finalize; import com.deepgram.resources.listen.v1.types.ListenV1KeepAlive; import com.deepgram.resources.listen.v1.types.ListenV1Metadata; @@ -65,6 +67,8 @@ public class V1WebSocketClient implements AutoCloseable { private volatile Consumer speechStartedHandler; + private volatile Consumer errorHandler; + /** * Creates a new async WebSocket client for the v1 channel. */ @@ -224,13 +228,22 @@ public CompletableFuture connect(V1ConnectOptions options) { ? this.reconnectOptions : ReconnectingWebSocketListener.ReconnectOptions.builder().build(); this.reconnectingListener = - new ReconnectingWebSocketListener(reconnectOpts, () -> { - if (clientOptions.webSocketFactory().isPresent()) { - return clientOptions.webSocketFactory().get().create(request, this.reconnectingListener); - } else { - return okHttpClient.newWebSocket(request, this.reconnectingListener); - } - }) { + new ReconnectingWebSocketListener( + reconnectOpts, + () -> { + if (clientOptions.isClosed()) { + throw new IllegalStateException("root client has been closed"); + } + if (clientOptions.webSocketFactory().isPresent()) { + return clientOptions + .webSocketFactory() + .get() + .create(request, this.reconnectingListener); + } else { + return okHttpClient.newWebSocket(request, this.reconnectingListener); + } + }, + clientOptions::isClosed) { @Override protected void onWebSocketOpen(WebSocket webSocket, Response response) { readyState = WebSocketReadyState.OPEN; @@ -265,6 +278,7 @@ protected void onWebSocketClosed(WebSocket webSocket, int code, String reason) { } } }; + clientOptions.registerWebSocket(this); reconnectingListener.connect(); return connectionFuture; } @@ -273,7 +287,10 @@ protected void onWebSocketClosed(WebSocket webSocket, int code, String reason) { * Disconnects the WebSocket connection and releases resources. */ public void disconnect() { - reconnectingListener.disconnect(); + clientOptions.unregisterWebSocket(this); + if (reconnectingListener != null) { + reconnectingListener.disconnect(); + } if (timeoutExecutor != null) { timeoutExecutor.shutdownNow(); timeoutExecutor = null; @@ -336,6 +353,15 @@ public CompletableFuture sendKeepAlive(ListenV1KeepAlive message) { return sendMessage(message); } + /** + * Sends a ListenV1Configure message to the server asynchronously. + * @param message the message to send + * @return a CompletableFuture that completes when the message is sent + */ + public CompletableFuture sendConfigure(ListenV1Configure message) { + return sendMessage(message); + } + /** * Registers a handler for ListenV1Results messages from the server. * @param handler the handler to invoke when a message is received @@ -368,6 +394,14 @@ public void onSpeechStarted(Consumer handler) { this.speechStartedHandler = handler; } + /** + * Registers a handler for ListenV1Error messages from the server. + * @param handler the handler to invoke when a message is received + */ + public void onErrorMessage(Consumer handler) { + this.errorHandler = handler; + } + /** * Registers a handler called when the connection is established. * @param handler the handler to invoke when connected @@ -524,6 +558,21 @@ private void handleIncomingMessage(String json) { return; } } + if (node.has("variant") + && node.has("description") + && "Error".equals(node.path("type").asText())) { + ListenV1Error errorHandlerEvent = null; + try { + errorHandlerEvent = objectMapper.treeToValue(node, ListenV1Error.class); + } catch (Exception e) { + } + if (errorHandlerEvent != null) { + if (errorHandler != null) { + errorHandler.accept(errorHandlerEvent); + } + return; + } + } if (onErrorHandler != null) { onErrorHandler.accept(new RuntimeException( "Unrecognized WebSocket message: " + json.substring(0, Math.min(200, json.length())) diff --git a/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ConfigureFailure.java b/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ConfigureFailure.java index 478307b..a48faac 100644 --- a/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ConfigureFailure.java +++ b/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ConfigureFailure.java @@ -10,10 +10,12 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.annotation.Nulls; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import java.util.HashMap; import java.util.Map; import java.util.Objects; +import java.util.Optional; import org.jetbrains.annotations.NotNull; @JsonInclude(JsonInclude.Include.NON_ABSENT) @@ -23,11 +25,22 @@ public final class ListenV2ConfigureFailure { private final int sequenceId; + private final Optional code; + + private final Optional description; + private final Map additionalProperties; - private ListenV2ConfigureFailure(String requestId, int sequenceId, Map additionalProperties) { + private ListenV2ConfigureFailure( + String requestId, + int sequenceId, + Optional code, + Optional description, + Map additionalProperties) { this.requestId = requestId; this.sequenceId = sequenceId; + this.code = code; + this.description = description; this.additionalProperties = additionalProperties; } @@ -57,6 +70,22 @@ public int getSequenceId() { return sequenceId; } + /** + * @return Failure code identifying the rejected configuration + */ + @JsonProperty("code") + public Optional getCode() { + return code; + } + + /** + * @return A human-readable description of the configuration failure + */ + @JsonProperty("description") + public Optional getDescription() { + return description; + } + @java.lang.Override public boolean equals(Object other) { if (this == other) return true; @@ -69,12 +98,15 @@ public Map getAdditionalProperties() { } private boolean equalTo(ListenV2ConfigureFailure other) { - return requestId.equals(other.requestId) && sequenceId == other.sequenceId; + return requestId.equals(other.requestId) + && sequenceId == other.sequenceId + && code.equals(other.code) + && description.equals(other.description); } @java.lang.Override public int hashCode() { - return Objects.hash(this.requestId, this.sequenceId); + return Objects.hash(this.requestId, this.sequenceId, this.code, this.description); } @java.lang.Override @@ -110,6 +142,20 @@ public interface _FinalStage { _FinalStage additionalProperty(String key, Object value); _FinalStage additionalProperties(Map additionalProperties); + + /** + *

Failure code identifying the rejected configuration

+ */ + _FinalStage code(Optional code); + + _FinalStage code(String code); + + /** + *

A human-readable description of the configuration failure

+ */ + _FinalStage description(Optional description); + + _FinalStage description(String description); } @JsonIgnoreProperties(ignoreUnknown = true) @@ -118,6 +164,10 @@ public static final class Builder implements RequestIdStage, SequenceIdStage, _F private int sequenceId; + private Optional description = Optional.empty(); + + private Optional code = Optional.empty(); + @JsonAnySetter private Map additionalProperties = new HashMap<>(); @@ -127,6 +177,8 @@ private Builder() {} public Builder from(ListenV2ConfigureFailure other) { requestId(other.getRequestId()); sequenceId(other.getSequenceId()); + code(other.getCode()); + description(other.getDescription()); return this; } @@ -154,9 +206,49 @@ public _FinalStage sequenceId(int sequenceId) { return this; } + /** + *

A human-readable description of the configuration failure

+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + public _FinalStage description(String description) { + this.description = Optional.ofNullable(description); + return this; + } + + /** + *

A human-readable description of the configuration failure

+ */ + @java.lang.Override + @JsonSetter(value = "description", nulls = Nulls.SKIP) + public _FinalStage description(Optional description) { + this.description = description; + return this; + } + + /** + *

Failure code identifying the rejected configuration

+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + public _FinalStage code(String code) { + this.code = Optional.ofNullable(code); + return this; + } + + /** + *

Failure code identifying the rejected configuration

+ */ + @java.lang.Override + @JsonSetter(value = "code", nulls = Nulls.SKIP) + public _FinalStage code(Optional code) { + this.code = code; + return this; + } + @java.lang.Override public ListenV2ConfigureFailure build() { - return new ListenV2ConfigureFailure(requestId, sequenceId, additionalProperties); + return new ListenV2ConfigureFailure(requestId, sequenceId, code, description, additionalProperties); } @java.lang.Override diff --git a/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2Warning.java b/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2Warning.java new file mode 100644 index 0000000..4eed2fb --- /dev/null +++ b/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2Warning.java @@ -0,0 +1,247 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.deepgram.resources.listen.v2.types; + +import com.deepgram.core.ObjectMappers; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import org.jetbrains.annotations.NotNull; + +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonDeserialize(builder = ListenV2Warning.Builder.class) +public final class ListenV2Warning { + private final String requestId; + + private final int sequenceId; + + private final String code; + + private final String description; + + private final Map additionalProperties; + + private ListenV2Warning( + String requestId, + int sequenceId, + String code, + String description, + Map additionalProperties) { + this.requestId = requestId; + this.sequenceId = sequenceId; + this.code = code; + this.description = description; + this.additionalProperties = additionalProperties; + } + + /** + * @return Message type identifier + */ + @JsonProperty("type") + public String getType() { + return "Warning"; + } + + /** + * @return The unique identifier of the request + */ + @JsonProperty("request_id") + public String getRequestId() { + return requestId; + } + + /** + * @return Starts at 0 and increments for each message the server sends + * to the client. This includes messages of other types, like + * TurnInfo messages. + */ + @JsonProperty("sequence_id") + public int getSequenceId() { + return sequenceId; + } + + /** + * @return Warning code identifying the condition, in SCREAMING_SNAKE_CASE + */ + @JsonProperty("code") + public String getCode() { + return code; + } + + /** + * @return A human-readable description of the warning + */ + @JsonProperty("description") + public String getDescription() { + return description; + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof ListenV2Warning && equalTo((ListenV2Warning) other); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + private boolean equalTo(ListenV2Warning other) { + return requestId.equals(other.requestId) + && sequenceId == other.sequenceId + && code.equals(other.code) + && description.equals(other.description); + } + + @java.lang.Override + public int hashCode() { + return Objects.hash(this.requestId, this.sequenceId, this.code, this.description); + } + + @java.lang.Override + public String toString() { + return ObjectMappers.stringify(this); + } + + public static RequestIdStage builder() { + return new Builder(); + } + + public interface RequestIdStage { + /** + *

The unique identifier of the request

+ */ + SequenceIdStage requestId(@NotNull String requestId); + + Builder from(ListenV2Warning other); + } + + public interface SequenceIdStage { + /** + *

Starts at 0 and increments for each message the server sends + * to the client. This includes messages of other types, like + * TurnInfo messages.

+ */ + CodeStage sequenceId(int sequenceId); + } + + public interface CodeStage { + /** + *

Warning code identifying the condition, in SCREAMING_SNAKE_CASE

+ */ + DescriptionStage code(@NotNull String code); + } + + public interface DescriptionStage { + /** + *

A human-readable description of the warning

+ */ + _FinalStage description(@NotNull String description); + } + + public interface _FinalStage { + ListenV2Warning build(); + + _FinalStage additionalProperty(String key, Object value); + + _FinalStage additionalProperties(Map additionalProperties); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static final class Builder + implements RequestIdStage, SequenceIdStage, CodeStage, DescriptionStage, _FinalStage { + private String requestId; + + private int sequenceId; + + private String code; + + private String description; + + @JsonAnySetter + private Map additionalProperties = new HashMap<>(); + + private Builder() {} + + @java.lang.Override + public Builder from(ListenV2Warning other) { + requestId(other.getRequestId()); + sequenceId(other.getSequenceId()); + code(other.getCode()); + description(other.getDescription()); + return this; + } + + /** + *

The unique identifier of the request

+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + @JsonSetter("request_id") + public SequenceIdStage requestId(@NotNull String requestId) { + this.requestId = Objects.requireNonNull(requestId, "requestId must not be null"); + return this; + } + + /** + *

Starts at 0 and increments for each message the server sends + * to the client. This includes messages of other types, like + * TurnInfo messages.

+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + @JsonSetter("sequence_id") + public CodeStage sequenceId(int sequenceId) { + this.sequenceId = sequenceId; + return this; + } + + /** + *

Warning code identifying the condition, in SCREAMING_SNAKE_CASE

+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + @JsonSetter("code") + public DescriptionStage code(@NotNull String code) { + this.code = Objects.requireNonNull(code, "code must not be null"); + return this; + } + + /** + *

A human-readable description of the warning

+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + @JsonSetter("description") + public _FinalStage description(@NotNull String description) { + this.description = Objects.requireNonNull(description, "description must not be null"); + return this; + } + + @java.lang.Override + public ListenV2Warning build() { + return new ListenV2Warning(requestId, sequenceId, code, description, additionalProperties); + } + + @java.lang.Override + public Builder additionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + return this; + } + + @java.lang.Override + public Builder additionalProperties(Map additionalProperties) { + this.additionalProperties.putAll(additionalProperties); + return this; + } + } +} diff --git a/src/main/java/com/deepgram/resources/listen/v2/websocket/V2WebSocketClient.java b/src/main/java/com/deepgram/resources/listen/v2/websocket/V2WebSocketClient.java index 0e1535b..84bf5df 100644 --- a/src/main/java/com/deepgram/resources/listen/v2/websocket/V2WebSocketClient.java +++ b/src/main/java/com/deepgram/resources/listen/v2/websocket/V2WebSocketClient.java @@ -17,6 +17,7 @@ import com.deepgram.resources.listen.v2.types.ListenV2FatalError; import com.deepgram.resources.listen.v2.types.ListenV2ForceEndTurn; import com.deepgram.resources.listen.v2.types.ListenV2TurnInfo; +import com.deepgram.resources.listen.v2.types.ListenV2Warning; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.concurrent.CompletableFuture; @@ -66,6 +67,8 @@ public class V2WebSocketClient implements AutoCloseable { private volatile Consumer configureFailureHandler; + private volatile Consumer warningHandler; + private volatile Consumer errorHandler; /** @@ -161,13 +164,22 @@ public CompletableFuture connect(V2ConnectOptions options) { ? this.reconnectOptions : ReconnectingWebSocketListener.ReconnectOptions.builder().build(); this.reconnectingListener = - new ReconnectingWebSocketListener(reconnectOpts, () -> { - if (clientOptions.webSocketFactory().isPresent()) { - return clientOptions.webSocketFactory().get().create(request, this.reconnectingListener); - } else { - return okHttpClient.newWebSocket(request, this.reconnectingListener); - } - }) { + new ReconnectingWebSocketListener( + reconnectOpts, + () -> { + if (clientOptions.isClosed()) { + throw new IllegalStateException("root client has been closed"); + } + if (clientOptions.webSocketFactory().isPresent()) { + return clientOptions + .webSocketFactory() + .get() + .create(request, this.reconnectingListener); + } else { + return okHttpClient.newWebSocket(request, this.reconnectingListener); + } + }, + clientOptions::isClosed) { @Override protected void onWebSocketOpen(WebSocket webSocket, Response response) { readyState = WebSocketReadyState.OPEN; @@ -202,6 +214,7 @@ protected void onWebSocketClosed(WebSocket webSocket, int code, String reason) { } } }; + clientOptions.registerWebSocket(this); reconnectingListener.connect(); return connectionFuture; } @@ -210,7 +223,10 @@ protected void onWebSocketClosed(WebSocket webSocket, int code, String reason) { * Disconnects the WebSocket connection and releases resources. */ public void disconnect() { - reconnectingListener.disconnect(); + clientOptions.unregisterWebSocket(this); + if (reconnectingListener != null) { + reconnectingListener.disconnect(); + } if (timeoutExecutor != null) { timeoutExecutor.shutdownNow(); timeoutExecutor = null; @@ -305,6 +321,14 @@ public void onConfigureFailure(Consumer handler) { this.configureFailureHandler = handler; } + /** + * Registers a handler for ListenV2Warning messages from the server. + * @param handler the handler to invoke when a message is received + */ + public void onWarning(Consumer handler) { + this.warningHandler = handler; + } + /** * Registers a handler for ListenV2FatalError messages from the server. * @param handler the handler to invoke when a message is received @@ -441,6 +465,23 @@ private void handleIncomingMessage(String json) { return; } } + if (node.has("request_id") + && node.has("sequence_id") + && node.has("code") + && node.has("description") + && "Warning".equals(node.path("type").asText())) { + ListenV2Warning warningHandlerEvent = null; + try { + warningHandlerEvent = objectMapper.treeToValue(node, ListenV2Warning.class); + } catch (Exception e) { + } + if (warningHandlerEvent != null) { + if (warningHandler != null) { + warningHandler.accept(warningHandlerEvent); + } + return; + } + } if (node.has("sequence_id") && node.has("code") && node.has("description") diff --git a/src/main/java/com/deepgram/resources/speak/v1/websocket/V1WebSocketClient.java b/src/main/java/com/deepgram/resources/speak/v1/websocket/V1WebSocketClient.java index 8af4275..6dd298a 100644 --- a/src/main/java/com/deepgram/resources/speak/v1/websocket/V1WebSocketClient.java +++ b/src/main/java/com/deepgram/resources/speak/v1/websocket/V1WebSocketClient.java @@ -130,13 +130,22 @@ public CompletableFuture connect(V1ConnectOptions options) { ? this.reconnectOptions : ReconnectingWebSocketListener.ReconnectOptions.builder().build(); this.reconnectingListener = - new ReconnectingWebSocketListener(reconnectOpts, () -> { - if (clientOptions.webSocketFactory().isPresent()) { - return clientOptions.webSocketFactory().get().create(request, this.reconnectingListener); - } else { - return okHttpClient.newWebSocket(request, this.reconnectingListener); - } - }) { + new ReconnectingWebSocketListener( + reconnectOpts, + () -> { + if (clientOptions.isClosed()) { + throw new IllegalStateException("root client has been closed"); + } + if (clientOptions.webSocketFactory().isPresent()) { + return clientOptions + .webSocketFactory() + .get() + .create(request, this.reconnectingListener); + } else { + return okHttpClient.newWebSocket(request, this.reconnectingListener); + } + }, + clientOptions::isClosed) { @Override protected void onWebSocketOpen(WebSocket webSocket, Response response) { readyState = WebSocketReadyState.OPEN; @@ -175,6 +184,7 @@ protected void onWebSocketClosed(WebSocket webSocket, int code, String reason) { } } }; + clientOptions.registerWebSocket(this); reconnectingListener.connect(); return connectionFuture; } @@ -191,7 +201,10 @@ public CompletableFuture connect() { * Disconnects the WebSocket connection and releases resources. */ public void disconnect() { - reconnectingListener.disconnect(); + clientOptions.unregisterWebSocket(this); + if (reconnectingListener != null) { + reconnectingListener.disconnect(); + } if (timeoutExecutor != null) { timeoutExecutor.shutdownNow(); timeoutExecutor = null; diff --git a/src/main/java/com/deepgram/resources/speak/v2/audio/requests/SpeakV2Request.java b/src/main/java/com/deepgram/resources/speak/v2/audio/requests/SpeakV2Request.java index bc3fb63..d1a3d82 100644 --- a/src/main/java/com/deepgram/resources/speak/v2/audio/requests/SpeakV2Request.java +++ b/src/main/java/com/deepgram/resources/speak/v2/audio/requests/SpeakV2Request.java @@ -167,7 +167,7 @@ public Optional getSampleRate() { } /** - * @return Speaking rate multiplier that adjusts the pace of generated speech while preserving natural prosody and voice quality. Accepted values run 0.5 to 1.5 in 0.05 increments. Not yet supported in all languages. + * @return Speaking rate multiplier that adjusts the pace of generated speech while preserving natural prosody and voice quality. Accepted values run 0.5 to 1.5 in 0.05 increments. Not yet supported in all languages. When the text contains an inline pause marker, speed is capped at 1.15 (PAUSE_SPEED_CAP_EXCEEDED above that). A value other than 1.0 cannot be combined with inline pronunciation controls (CONTROL_COMBINATION_INVALID). */ @JsonIgnore public Optional getSpeed() { @@ -183,7 +183,7 @@ public Optional getPriority() { } /** - * @return The text content to be converted to speech. The server normalizes and preprocesses the text before synthesis. Inline pause and pronunciation controls are not yet applied; they are stripped from the text before synthesis. + * @return The text content to be converted to speech. The server normalizes and preprocesses the text before synthesis. May contain inline pause controls (\{pause:500ms\}, 500-3000 ms in 100 ms steps, at most 8 per request) and inline pronunciation controls (\{"word": "...", "pronounce": "<IPA>"\}, Early Access). Pronunciation cannot be combined with pause or with a speed other than 1.0, and speed is capped at 1.15 when a pause is present. See Speed, Pause, Pronunciation. */ @JsonProperty("text") public String getText() { @@ -255,7 +255,7 @@ public interface ModelStage { public interface TextStage { /** - *

The text content to be converted to speech. The server normalizes and preprocesses the text before synthesis. Inline pause and pronunciation controls are not yet applied; they are stripped from the text before synthesis.

+ *

The text content to be converted to speech. The server normalizes and preprocesses the text before synthesis. May contain inline pause controls (\{pause:500ms\}, 500-3000 ms in 100 ms steps, at most 8 per request) and inline pronunciation controls (\{"word": "...", "pronounce": "<IPA>"\}, Early Access). Pronunciation cannot be combined with pause or with a speed other than 1.0, and speed is capped at 1.15 when a pause is present. See Speed, Pause, Pronunciation.

*/ _FinalStage text(@NotNull String text); } @@ -333,7 +333,7 @@ public interface _FinalStage { _FinalStage sampleRate(Integer sampleRate); /** - *

Speaking rate multiplier that adjusts the pace of generated speech while preserving natural prosody and voice quality. Accepted values run 0.5 to 1.5 in 0.05 increments. Not yet supported in all languages.

+ *

Speaking rate multiplier that adjusts the pace of generated speech while preserving natural prosody and voice quality. Accepted values run 0.5 to 1.5 in 0.05 increments. Not yet supported in all languages. When the text contains an inline pause marker, speed is capped at 1.15 (PAUSE_SPEED_CAP_EXCEEDED above that). A value other than 1.0 cannot be combined with inline pronunciation controls (CONTROL_COMBINATION_INVALID).

*/ _FinalStage speed(Optional speed); @@ -410,7 +410,7 @@ public TextStage model(@NotNull String model) { } /** - *

The text content to be converted to speech. The server normalizes and preprocesses the text before synthesis. Inline pause and pronunciation controls are not yet applied; they are stripped from the text before synthesis.

+ *

The text content to be converted to speech. The server normalizes and preprocesses the text before synthesis. May contain inline pause controls (\{pause:500ms\}, 500-3000 ms in 100 ms steps, at most 8 per request) and inline pronunciation controls (\{"word": "...", "pronounce": "<IPA>"\}, Early Access). Pronunciation cannot be combined with pause or with a speed other than 1.0, and speed is capped at 1.15 when a pause is present. See Speed, Pause, Pronunciation.

* @return Reference to {@code this} so that method calls can be chained together. */ @java.lang.Override @@ -441,7 +441,7 @@ public _FinalStage priority(Optional priority) { } /** - *

Speaking rate multiplier that adjusts the pace of generated speech while preserving natural prosody and voice quality. Accepted values run 0.5 to 1.5 in 0.05 increments. Not yet supported in all languages.

+ *

Speaking rate multiplier that adjusts the pace of generated speech while preserving natural prosody and voice quality. Accepted values run 0.5 to 1.5 in 0.05 increments. Not yet supported in all languages. When the text contains an inline pause marker, speed is capped at 1.15 (PAUSE_SPEED_CAP_EXCEEDED above that). A value other than 1.0 cannot be combined with inline pronunciation controls (CONTROL_COMBINATION_INVALID).

* @return Reference to {@code this} so that method calls can be chained together. */ @java.lang.Override @@ -451,7 +451,7 @@ public _FinalStage speed(Double speed) { } /** - *

Speaking rate multiplier that adjusts the pace of generated speech while preserving natural prosody and voice quality. Accepted values run 0.5 to 1.5 in 0.05 increments. Not yet supported in all languages.

+ *

Speaking rate multiplier that adjusts the pace of generated speech while preserving natural prosody and voice quality. Accepted values run 0.5 to 1.5 in 0.05 increments. Not yet supported in all languages. When the text contains an inline pause marker, speed is capped at 1.15 (PAUSE_SPEED_CAP_EXCEEDED above that). A value other than 1.0 cannot be combined with inline pronunciation controls (CONTROL_COMBINATION_INVALID).

*/ @java.lang.Override @JsonSetter(value = "speed", nulls = Nulls.SKIP) diff --git a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2ConfigureFailure.java b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2ConfigureFailure.java index e43c252..7970232 100644 --- a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2ConfigureFailure.java +++ b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2ConfigureFailure.java @@ -53,7 +53,7 @@ public String getType() { } /** - * @return Failure code, in SCREAMING_SNAKE_CASE. SPEED_OUT_OF_RANGE: outside the range the model publishes. SPEED_INCREMENT_INVALID: inside the published range but off the 0.05 increment. SPEED_NOT_SUPPORTED: this model or language has no runtime speed control at all. INTERNAL_ERROR: the configuration was acceptable but the server could not apply it — unlike the others, a server-side failure rather than a statement about the request. + * @return Failure code, in SCREAMING_SNAKE_CASE. SPEED_OUT_OF_RANGE: outside the range the model publishes. SPEED_INCREMENT_INVALID: inside the published range but off the 0.05 increment. SPEED_NOT_SUPPORTED: this model or language has no runtime speed control at all. CONTROL_COMBINATION_INVALID: speed was set while a turn buffered behind the active one still carries a pronunciation control; pronunciation and speed cannot be combined, so flush that turn before setting speed (pronunciations in the active turn do not block the change). INTERNAL_ERROR: the configuration was acceptable but the server could not apply it — unlike the others, a server-side failure rather than a statement about the request. */ @JsonProperty("code") public SpeakV2ConfigureFailureCode getCode() { @@ -118,7 +118,7 @@ public static CodeStage builder() { public interface CodeStage { /** - *

Failure code, in SCREAMING_SNAKE_CASE. SPEED_OUT_OF_RANGE: outside the range the model publishes. SPEED_INCREMENT_INVALID: inside the published range but off the 0.05 increment. SPEED_NOT_SUPPORTED: this model or language has no runtime speed control at all. INTERNAL_ERROR: the configuration was acceptable but the server could not apply it — unlike the others, a server-side failure rather than a statement about the request.

+ *

Failure code, in SCREAMING_SNAKE_CASE. SPEED_OUT_OF_RANGE: outside the range the model publishes. SPEED_INCREMENT_INVALID: inside the published range but off the 0.05 increment. SPEED_NOT_SUPPORTED: this model or language has no runtime speed control at all. CONTROL_COMBINATION_INVALID: speed was set while a turn buffered behind the active one still carries a pronunciation control; pronunciation and speed cannot be combined, so flush that turn before setting speed (pronunciations in the active turn do not block the change). INTERNAL_ERROR: the configuration was acceptable but the server could not apply it — unlike the others, a server-side failure rather than a statement about the request.

*/ DescriptionStage code(@NotNull SpeakV2ConfigureFailureCode code); @@ -179,7 +179,7 @@ public Builder from(SpeakV2ConfigureFailure other) { } /** - *

Failure code, in SCREAMING_SNAKE_CASE. SPEED_OUT_OF_RANGE: outside the range the model publishes. SPEED_INCREMENT_INVALID: inside the published range but off the 0.05 increment. SPEED_NOT_SUPPORTED: this model or language has no runtime speed control at all. INTERNAL_ERROR: the configuration was acceptable but the server could not apply it — unlike the others, a server-side failure rather than a statement about the request.

+ *

Failure code, in SCREAMING_SNAKE_CASE. SPEED_OUT_OF_RANGE: outside the range the model publishes. SPEED_INCREMENT_INVALID: inside the published range but off the 0.05 increment. SPEED_NOT_SUPPORTED: this model or language has no runtime speed control at all. CONTROL_COMBINATION_INVALID: speed was set while a turn buffered behind the active one still carries a pronunciation control; pronunciation and speed cannot be combined, so flush that turn before setting speed (pronunciations in the active turn do not block the change). INTERNAL_ERROR: the configuration was acceptable but the server could not apply it — unlike the others, a server-side failure rather than a statement about the request.

* @return Reference to {@code this} so that method calls can be chained together. */ @java.lang.Override diff --git a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2ConfigureFailureCode.java b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2ConfigureFailureCode.java index 7d02bce..63ec45a 100644 --- a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2ConfigureFailureCode.java +++ b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2ConfigureFailureCode.java @@ -7,6 +7,9 @@ import com.fasterxml.jackson.annotation.JsonValue; public final class SpeakV2ConfigureFailureCode { + public static final SpeakV2ConfigureFailureCode CONTROL_COMBINATION_INVALID = + new SpeakV2ConfigureFailureCode(Value.CONTROL_COMBINATION_INVALID, "CONTROL_COMBINATION_INVALID"); + public static final SpeakV2ConfigureFailureCode SPEED_OUT_OF_RANGE = new SpeakV2ConfigureFailureCode(Value.SPEED_OUT_OF_RANGE, "SPEED_OUT_OF_RANGE"); @@ -52,6 +55,8 @@ public int hashCode() { public T visit(Visitor visitor) { switch (value) { + case CONTROL_COMBINATION_INVALID: + return visitor.visitControlCombinationInvalid(); case SPEED_OUT_OF_RANGE: return visitor.visitSpeedOutOfRange(); case SPEED_INCREMENT_INVALID: @@ -69,6 +74,8 @@ public T visit(Visitor visitor) { @JsonCreator(mode = JsonCreator.Mode.DELEGATING) public static SpeakV2ConfigureFailureCode valueOf(String value) { switch (value) { + case "CONTROL_COMBINATION_INVALID": + return CONTROL_COMBINATION_INVALID; case "SPEED_OUT_OF_RANGE": return SPEED_OUT_OF_RANGE; case "SPEED_INCREMENT_INVALID": @@ -89,6 +96,8 @@ public enum Value { SPEED_NOT_SUPPORTED, + CONTROL_COMBINATION_INVALID, + INTERNAL_ERROR, UNKNOWN @@ -101,6 +110,8 @@ public interface Visitor { T visitSpeedNotSupported(); + T visitControlCombinationInvalid(); + T visitInternalError(); T visitUnknown(String unknownType); diff --git a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Error.java b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Error.java index 343cfa7..0a82847 100644 --- a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Error.java +++ b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Error.java @@ -40,7 +40,7 @@ public String getType() { } /** - * @return A code identifying the error, e.g. MESSAGE-0000 or NET-0000. + * @return A code identifying the error, e.g. MESSAGE-0000 or NET-0000. DATA-0002 covers invalid inline controls and speed, including an inline pause marker (pause is batch-only) and a pronunciation control combined with a speed other than 1.0; description names the specific rule. */ @JsonProperty("code") public SpeakV2ErrorCode getCode() { @@ -86,7 +86,7 @@ public static CodeStage builder() { public interface CodeStage { /** - *

A code identifying the error, e.g. MESSAGE-0000 or NET-0000.

+ *

A code identifying the error, e.g. MESSAGE-0000 or NET-0000. DATA-0002 covers invalid inline controls and speed, including an inline pause marker (pause is batch-only) and a pronunciation control combined with a speed other than 1.0; description names the specific rule.

*/ DescriptionStage code(@NotNull SpeakV2ErrorCode code); @@ -127,7 +127,7 @@ public Builder from(SpeakV2Error other) { } /** - *

A code identifying the error, e.g. MESSAGE-0000 or NET-0000.

+ *

A code identifying the error, e.g. MESSAGE-0000 or NET-0000. DATA-0002 covers invalid inline controls and speed, including an inline pause marker (pause is batch-only) and a pronunciation control combined with a speed other than 1.0; description names the specific rule.

* @return Reference to {@code this} so that method calls can be chained together. */ @java.lang.Override diff --git a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Speak.java b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Speak.java index 16150bf..8c8e563 100644 --- a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Speak.java +++ b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Speak.java @@ -37,7 +37,7 @@ public String getType() { } /** - * @return The input text to synthesize. Inline pause and pronunciation controls are not yet applied; they are stripped from the text before synthesis. + * @return The input text to synthesize. May contain inline pronunciation controls (\{"word": "...", "pronounce": "<IPA>"\}), which are in Early Access. Inline pause controls are supported on the batch (REST) transport only; a pause marker sent over the WebSocket fails the connection with DATA-0002. Pronunciation cannot be combined with a speed other than 1.0: text carrying a pronunciation control on a session opened with speed, or after a Configure that set it, also fails the connection with DATA-0002. See Speed, Pause, Pronunciation. */ @JsonProperty("text") public String getText() { @@ -75,7 +75,7 @@ public static TextStage builder() { public interface TextStage { /** - *

The input text to synthesize. Inline pause and pronunciation controls are not yet applied; they are stripped from the text before synthesis.

+ *

The input text to synthesize. May contain inline pronunciation controls (\{"word": "...", "pronounce": "<IPA>"\}), which are in Early Access. Inline pause controls are supported on the batch (REST) transport only; a pause marker sent over the WebSocket fails the connection with DATA-0002. Pronunciation cannot be combined with a speed other than 1.0: text carrying a pronunciation control on a session opened with speed, or after a Configure that set it, also fails the connection with DATA-0002. See Speed, Pause, Pronunciation.

*/ _FinalStage text(@NotNull String text); @@ -106,7 +106,7 @@ public Builder from(SpeakV2Speak other) { } /** - *

The input text to synthesize. Inline pause and pronunciation controls are not yet applied; they are stripped from the text before synthesis.

+ *

The input text to synthesize. May contain inline pronunciation controls (\{"word": "...", "pronounce": "<IPA>"\}), which are in Early Access. Inline pause controls are supported on the batch (REST) transport only; a pause marker sent over the WebSocket fails the connection with DATA-0002. Pronunciation cannot be combined with a speed other than 1.0: text carrying a pronunciation control on a session opened with speed, or after a Configure that set it, also fails the connection with DATA-0002. See Speed, Pause, Pronunciation.

* @return Reference to {@code this} so that method calls can be chained together. */ @java.lang.Override diff --git a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechInterruptedMetadata.java b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechInterruptedMetadata.java index da24995..586f3c2 100644 --- a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechInterruptedMetadata.java +++ b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechInterruptedMetadata.java @@ -79,7 +79,7 @@ public int getBillableCharacterCount() { } /** - * @return Counts of the inline controls the server acted on during the turn. Inline pause and pronunciation controls are not applied at launch — support is coming soon — so every count is currently 0. + * @return Counts of the inline controls the server acted on during the turn. A pronunciation override that triggers an IPA warning is still applied best-effort and counted in pronunciations_applied; the warning is reported separately through a Warning and pronunciation_warnings. */ @JsonProperty("controls_applied") public SpeakV2SpeechInterruptedMetadataControlsApplied getControlsApplied() { @@ -156,7 +156,7 @@ public interface BillableCharacterCountStage { public interface ControlsAppliedStage { /** - *

Counts of the inline controls the server acted on during the turn. Inline pause and pronunciation controls are not applied at launch — support is coming soon — so every count is currently 0.

+ *

Counts of the inline controls the server acted on during the turn. A pronunciation override that triggers an IPA warning is still applied best-effort and counted in pronunciations_applied; the warning is reported separately through a Warning and pronunciation_warnings.

*/ _FinalStage controlsApplied(@NotNull SpeakV2SpeechInterruptedMetadataControlsApplied controlsApplied); } @@ -247,7 +247,7 @@ public ControlsAppliedStage billableCharacterCount(int billableCharacterCount) { } /** - *

Counts of the inline controls the server acted on during the turn. Inline pause and pronunciation controls are not applied at launch — support is coming soon — so every count is currently 0.

+ *

Counts of the inline controls the server acted on during the turn. A pronunciation override that triggers an IPA warning is still applied best-effort and counted in pronunciations_applied; the warning is reported separately through a Warning and pronunciation_warnings.

* @return Reference to {@code this} so that method calls can be chained together. */ @java.lang.Override diff --git a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechInterruptedMetadataControlsApplied.java b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechInterruptedMetadataControlsApplied.java index 85000d9..0d0e0dc 100644 --- a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechInterruptedMetadataControlsApplied.java +++ b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechInterruptedMetadataControlsApplied.java @@ -38,7 +38,7 @@ private SpeakV2SpeechInterruptedMetadataControlsApplied( } /** - * @return Pronunciation overrides successfully applied. Mirrors the Aura-2 dg-pronunciations-applied REST header. Currently always 0. + * @return Pronunciation overrides successfully applied. Mirrors the Aura-2 dg-pronunciations-applied REST header. */ @JsonProperty("pronunciations_applied") public int getPronunciationsApplied() { @@ -46,7 +46,7 @@ public int getPronunciationsApplied() { } /** - * @return Pause (break) controls successfully applied. Mirrors the Aura-2 dg-breaks-applied REST header. Currently always 0. + * @return Pause (break) controls successfully applied. Mirrors the Aura-2 dg-breaks-applied REST header. Always 0 on the WebSocket, where inline pause controls are not supported. */ @JsonProperty("breaks_applied") public int getBreaksApplied() { @@ -54,7 +54,7 @@ public int getBreaksApplied() { } /** - * @return Pronunciation entries that triggered a warning (invalid IPA, word too long). Mirrors the Aura-2 dg-pronunciation-warnings REST header. Currently always 0. + * @return Pronunciation entries that triggered a warning (invalid IPA, word too long). On batch requests the corresponding PRON-NNN codes are returned in the dg-warnings response header. */ @JsonProperty("pronunciation_warnings") public int getPronunciationWarnings() { @@ -95,7 +95,7 @@ public static PronunciationsAppliedStage builder() { public interface PronunciationsAppliedStage { /** - *

Pronunciation overrides successfully applied. Mirrors the Aura-2 dg-pronunciations-applied REST header. Currently always 0.

+ *

Pronunciation overrides successfully applied. Mirrors the Aura-2 dg-pronunciations-applied REST header.

*/ BreaksAppliedStage pronunciationsApplied(int pronunciationsApplied); @@ -104,14 +104,14 @@ public interface PronunciationsAppliedStage { public interface BreaksAppliedStage { /** - *

Pause (break) controls successfully applied. Mirrors the Aura-2 dg-breaks-applied REST header. Currently always 0.

+ *

Pause (break) controls successfully applied. Mirrors the Aura-2 dg-breaks-applied REST header. Always 0 on the WebSocket, where inline pause controls are not supported.

*/ PronunciationWarningsStage breaksApplied(int breaksApplied); } public interface PronunciationWarningsStage { /** - *

Pronunciation entries that triggered a warning (invalid IPA, word too long). Mirrors the Aura-2 dg-pronunciation-warnings REST header. Currently always 0.

+ *

Pronunciation entries that triggered a warning (invalid IPA, word too long). On batch requests the corresponding PRON-NNN codes are returned in the dg-warnings response header.

*/ _FinalStage pronunciationWarnings(int pronunciationWarnings); } @@ -147,7 +147,7 @@ public Builder from(SpeakV2SpeechInterruptedMetadataControlsApplied other) { } /** - *

Pronunciation overrides successfully applied. Mirrors the Aura-2 dg-pronunciations-applied REST header. Currently always 0.

+ *

Pronunciation overrides successfully applied. Mirrors the Aura-2 dg-pronunciations-applied REST header.

* @return Reference to {@code this} so that method calls can be chained together. */ @java.lang.Override @@ -158,7 +158,7 @@ public BreaksAppliedStage pronunciationsApplied(int pronunciationsApplied) { } /** - *

Pause (break) controls successfully applied. Mirrors the Aura-2 dg-breaks-applied REST header. Currently always 0.

+ *

Pause (break) controls successfully applied. Mirrors the Aura-2 dg-breaks-applied REST header. Always 0 on the WebSocket, where inline pause controls are not supported.

* @return Reference to {@code this} so that method calls can be chained together. */ @java.lang.Override @@ -169,7 +169,7 @@ public PronunciationWarningsStage breaksApplied(int breaksApplied) { } /** - *

Pronunciation entries that triggered a warning (invalid IPA, word too long). Mirrors the Aura-2 dg-pronunciation-warnings REST header. Currently always 0.

+ *

Pronunciation entries that triggered a warning (invalid IPA, word too long). On batch requests the corresponding PRON-NNN codes are returned in the dg-warnings response header.

* @return Reference to {@code this} so that method calls can be chained together. */ @java.lang.Override diff --git a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechMetadata.java b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechMetadata.java index d982b95..be1ab9f 100644 --- a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechMetadata.java +++ b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechMetadata.java @@ -87,7 +87,7 @@ public int getBillableCharacterCount() { } /** - * @return Counts of the inline controls the server acted on during the turn. Inline pause and pronunciation controls are not applied at launch — support is coming soon — so every count is currently 0. + * @return Counts of the inline controls the server acted on during the turn. A pronunciation override that triggers an IPA warning is still applied best-effort and counted in pronunciations_applied; the warning is reported separately through a Warning and pronunciation_warnings. */ @JsonProperty("controls_applied") public SpeakV2SpeechMetadataControlsApplied getControlsApplied() { @@ -164,7 +164,7 @@ public interface BillableCharacterCountStage { public interface ControlsAppliedStage { /** - *

Counts of the inline controls the server acted on during the turn. Inline pause and pronunciation controls are not applied at launch — support is coming soon — so every count is currently 0.

+ *

Counts of the inline controls the server acted on during the turn. A pronunciation override that triggers an IPA warning is still applied best-effort and counted in pronunciations_applied; the warning is reported separately through a Warning and pronunciation_warnings.

*/ _FinalStage controlsApplied(@NotNull SpeakV2SpeechMetadataControlsApplied controlsApplied); } @@ -255,7 +255,7 @@ public ControlsAppliedStage billableCharacterCount(int billableCharacterCount) { } /** - *

Counts of the inline controls the server acted on during the turn. Inline pause and pronunciation controls are not applied at launch — support is coming soon — so every count is currently 0.

+ *

Counts of the inline controls the server acted on during the turn. A pronunciation override that triggers an IPA warning is still applied best-effort and counted in pronunciations_applied; the warning is reported separately through a Warning and pronunciation_warnings.

* @return Reference to {@code this} so that method calls can be chained together. */ @java.lang.Override diff --git a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechMetadataControlsApplied.java b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechMetadataControlsApplied.java index b258f91..ddf185a 100644 --- a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechMetadataControlsApplied.java +++ b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2SpeechMetadataControlsApplied.java @@ -38,7 +38,7 @@ private SpeakV2SpeechMetadataControlsApplied( } /** - * @return Pronunciation overrides successfully applied. Mirrors the Aura-2 dg-pronunciations-applied REST header. Currently always 0. + * @return Pronunciation overrides successfully applied. Mirrors the Aura-2 dg-pronunciations-applied REST header. */ @JsonProperty("pronunciations_applied") public int getPronunciationsApplied() { @@ -46,7 +46,7 @@ public int getPronunciationsApplied() { } /** - * @return Pause (break) controls successfully applied. Mirrors the Aura-2 dg-breaks-applied REST header. Currently always 0. + * @return Pause (break) controls successfully applied. Mirrors the Aura-2 dg-breaks-applied REST header. Always 0 on the WebSocket, where inline pause controls are not supported. */ @JsonProperty("breaks_applied") public int getBreaksApplied() { @@ -54,7 +54,7 @@ public int getBreaksApplied() { } /** - * @return Pronunciation entries that triggered a warning (invalid IPA, word too long). Mirrors the Aura-2 dg-pronunciation-warnings REST header. Currently always 0. + * @return Pronunciation entries that triggered a warning (invalid IPA, word too long). On batch requests the corresponding PRON-NNN codes are returned in the dg-warnings response header. */ @JsonProperty("pronunciation_warnings") public int getPronunciationWarnings() { @@ -95,7 +95,7 @@ public static PronunciationsAppliedStage builder() { public interface PronunciationsAppliedStage { /** - *

Pronunciation overrides successfully applied. Mirrors the Aura-2 dg-pronunciations-applied REST header. Currently always 0.

+ *

Pronunciation overrides successfully applied. Mirrors the Aura-2 dg-pronunciations-applied REST header.

*/ BreaksAppliedStage pronunciationsApplied(int pronunciationsApplied); @@ -104,14 +104,14 @@ public interface PronunciationsAppliedStage { public interface BreaksAppliedStage { /** - *

Pause (break) controls successfully applied. Mirrors the Aura-2 dg-breaks-applied REST header. Currently always 0.

+ *

Pause (break) controls successfully applied. Mirrors the Aura-2 dg-breaks-applied REST header. Always 0 on the WebSocket, where inline pause controls are not supported.

*/ PronunciationWarningsStage breaksApplied(int breaksApplied); } public interface PronunciationWarningsStage { /** - *

Pronunciation entries that triggered a warning (invalid IPA, word too long). Mirrors the Aura-2 dg-pronunciation-warnings REST header. Currently always 0.

+ *

Pronunciation entries that triggered a warning (invalid IPA, word too long). On batch requests the corresponding PRON-NNN codes are returned in the dg-warnings response header.

*/ _FinalStage pronunciationWarnings(int pronunciationWarnings); } @@ -147,7 +147,7 @@ public Builder from(SpeakV2SpeechMetadataControlsApplied other) { } /** - *

Pronunciation overrides successfully applied. Mirrors the Aura-2 dg-pronunciations-applied REST header. Currently always 0.

+ *

Pronunciation overrides successfully applied. Mirrors the Aura-2 dg-pronunciations-applied REST header.

* @return Reference to {@code this} so that method calls can be chained together. */ @java.lang.Override @@ -158,7 +158,7 @@ public BreaksAppliedStage pronunciationsApplied(int pronunciationsApplied) { } /** - *

Pause (break) controls successfully applied. Mirrors the Aura-2 dg-breaks-applied REST header. Currently always 0.

+ *

Pause (break) controls successfully applied. Mirrors the Aura-2 dg-breaks-applied REST header. Always 0 on the WebSocket, where inline pause controls are not supported.

* @return Reference to {@code this} so that method calls can be chained together. */ @java.lang.Override @@ -169,7 +169,7 @@ public PronunciationWarningsStage breaksApplied(int breaksApplied) { } /** - *

Pronunciation entries that triggered a warning (invalid IPA, word too long). Mirrors the Aura-2 dg-pronunciation-warnings REST header. Currently always 0.

+ *

Pronunciation entries that triggered a warning (invalid IPA, word too long). On batch requests the corresponding PRON-NNN codes are returned in the dg-warnings response header.

* @return Reference to {@code this} so that method calls can be chained together. */ @java.lang.Override diff --git a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Warning.java b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Warning.java index 0eb0b3c..84332f9 100644 --- a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Warning.java +++ b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Warning.java @@ -42,7 +42,8 @@ public String getType() { /** * @return Warning code identifying the condition, in SCREAMING_SNAKE_CASE. *

Turn-scoped codes: NO_ACTIVE_SPEECH (a speech-scoped message arrived with no active turn), NO_SYNTHESIZABLE_TEXT (the turn's text was entirely whitespace or punctuation, so it produced no audio and is completed with a zero-duration SpeechMetadata), and SYNTHESIS_RETRYING (a synthesis request failed and is being retried).

- *

Inline-control codes are reserved and not currently emitted, because inline pause and pronunciation controls are not yet applied: BREAKS_LIMIT_EXCEEDED (too many pause controls, or two pauses with no intervening text), BREAK_TOKENS_OUT_OF_RANGE (pause durations outside the range the model supports), BREAK_TOKENS_WITH_INVALID_INCREMENTS (pause durations off the model's supported increment), PRONUNCIATION_WARNINGS (a pronunciation override contained invalid IPA), PRONUNCIATION_TOO_LONG (an IPA string exceeded the length limit), PRONUNCIATIONS_LIMIT_EXCEEDED (too many pronunciation controls in one turn).

+ *

Pronunciation codes: PRONUNCIATION_WARNINGS (a pronunciation override contained invalid IPA; it is still applied best-effort and counted in pronunciations_applied), PRONUNCIATION_TOO_LONG (an IPA string exceeded the length limit), PRONUNCIATIONS_LIMIT_EXCEEDED (too many pronunciation controls in one turn).

+ *

Pause codes (BREAKS_LIMIT_EXCEEDED, BREAK_TOKENS_OUT_OF_RANGE, BREAK_TOKENS_WITH_INVALID_INCREMENTS) are reserved and not emitted: inline pause controls are batch-only, and a pause marker on the WebSocket fails the connection instead.

*

Interrupt-scoped codes, each meaning the Interrupt was ignored: NO_AUDIO_GENERATED (the session has produced no audio yet, so there is nothing to interrupt), INTERRUPT_IN_PROGRESS (an earlier Interrupt is still being processed — at most one is handled at a time), INVALID_INTERRUPT_OFFSET (the playback_offset did not advance past the position a prior interrupt established).

*/ @JsonProperty("code") @@ -91,7 +92,8 @@ public interface CodeStage { /** *

Warning code identifying the condition, in SCREAMING_SNAKE_CASE.

*

Turn-scoped codes: NO_ACTIVE_SPEECH (a speech-scoped message arrived with no active turn), NO_SYNTHESIZABLE_TEXT (the turn's text was entirely whitespace or punctuation, so it produced no audio and is completed with a zero-duration SpeechMetadata), and SYNTHESIS_RETRYING (a synthesis request failed and is being retried).

- *

Inline-control codes are reserved and not currently emitted, because inline pause and pronunciation controls are not yet applied: BREAKS_LIMIT_EXCEEDED (too many pause controls, or two pauses with no intervening text), BREAK_TOKENS_OUT_OF_RANGE (pause durations outside the range the model supports), BREAK_TOKENS_WITH_INVALID_INCREMENTS (pause durations off the model's supported increment), PRONUNCIATION_WARNINGS (a pronunciation override contained invalid IPA), PRONUNCIATION_TOO_LONG (an IPA string exceeded the length limit), PRONUNCIATIONS_LIMIT_EXCEEDED (too many pronunciation controls in one turn).

+ *

Pronunciation codes: PRONUNCIATION_WARNINGS (a pronunciation override contained invalid IPA; it is still applied best-effort and counted in pronunciations_applied), PRONUNCIATION_TOO_LONG (an IPA string exceeded the length limit), PRONUNCIATIONS_LIMIT_EXCEEDED (too many pronunciation controls in one turn).

+ *

Pause codes (BREAKS_LIMIT_EXCEEDED, BREAK_TOKENS_OUT_OF_RANGE, BREAK_TOKENS_WITH_INVALID_INCREMENTS) are reserved and not emitted: inline pause controls are batch-only, and a pause marker on the WebSocket fails the connection instead.

*

Interrupt-scoped codes, each meaning the Interrupt was ignored: NO_AUDIO_GENERATED (the session has produced no audio yet, so there is nothing to interrupt), INTERRUPT_IN_PROGRESS (an earlier Interrupt is still being processed — at most one is handled at a time), INVALID_INTERRUPT_OFFSET (the playback_offset did not advance past the position a prior interrupt established).

*/ DescriptionStage code(@NotNull String code); @@ -135,7 +137,8 @@ public Builder from(SpeakV2Warning other) { /** *

Warning code identifying the condition, in SCREAMING_SNAKE_CASE.

*

Turn-scoped codes: NO_ACTIVE_SPEECH (a speech-scoped message arrived with no active turn), NO_SYNTHESIZABLE_TEXT (the turn's text was entirely whitespace or punctuation, so it produced no audio and is completed with a zero-duration SpeechMetadata), and SYNTHESIS_RETRYING (a synthesis request failed and is being retried).

- *

Inline-control codes are reserved and not currently emitted, because inline pause and pronunciation controls are not yet applied: BREAKS_LIMIT_EXCEEDED (too many pause controls, or two pauses with no intervening text), BREAK_TOKENS_OUT_OF_RANGE (pause durations outside the range the model supports), BREAK_TOKENS_WITH_INVALID_INCREMENTS (pause durations off the model's supported increment), PRONUNCIATION_WARNINGS (a pronunciation override contained invalid IPA), PRONUNCIATION_TOO_LONG (an IPA string exceeded the length limit), PRONUNCIATIONS_LIMIT_EXCEEDED (too many pronunciation controls in one turn).

+ *

Pronunciation codes: PRONUNCIATION_WARNINGS (a pronunciation override contained invalid IPA; it is still applied best-effort and counted in pronunciations_applied), PRONUNCIATION_TOO_LONG (an IPA string exceeded the length limit), PRONUNCIATIONS_LIMIT_EXCEEDED (too many pronunciation controls in one turn).

+ *

Pause codes (BREAKS_LIMIT_EXCEEDED, BREAK_TOKENS_OUT_OF_RANGE, BREAK_TOKENS_WITH_INVALID_INCREMENTS) are reserved and not emitted: inline pause controls are batch-only, and a pause marker on the WebSocket fails the connection instead.

*

Interrupt-scoped codes, each meaning the Interrupt was ignored: NO_AUDIO_GENERATED (the session has produced no audio yet, so there is nothing to interrupt), INTERRUPT_IN_PROGRESS (an earlier Interrupt is still being processed — at most one is handled at a time), INVALID_INTERRUPT_OFFSET (the playback_offset did not advance past the position a prior interrupt established).

* @return Reference to {@code this} so that method calls can be chained together. */ diff --git a/src/main/java/com/deepgram/resources/speak/v2/websocket/V2WebSocketClient.java b/src/main/java/com/deepgram/resources/speak/v2/websocket/V2WebSocketClient.java index 3e032b1..07f6c36 100644 --- a/src/main/java/com/deepgram/resources/speak/v2/websocket/V2WebSocketClient.java +++ b/src/main/java/com/deepgram/resources/speak/v2/websocket/V2WebSocketClient.java @@ -153,13 +153,22 @@ public CompletableFuture connect(V2ConnectOptions options) { ? this.reconnectOptions : ReconnectingWebSocketListener.ReconnectOptions.builder().build(); this.reconnectingListener = - new ReconnectingWebSocketListener(reconnectOpts, () -> { - if (clientOptions.webSocketFactory().isPresent()) { - return clientOptions.webSocketFactory().get().create(request, this.reconnectingListener); - } else { - return okHttpClient.newWebSocket(request, this.reconnectingListener); - } - }) { + new ReconnectingWebSocketListener( + reconnectOpts, + () -> { + if (clientOptions.isClosed()) { + throw new IllegalStateException("root client has been closed"); + } + if (clientOptions.webSocketFactory().isPresent()) { + return clientOptions + .webSocketFactory() + .get() + .create(request, this.reconnectingListener); + } else { + return okHttpClient.newWebSocket(request, this.reconnectingListener); + } + }, + clientOptions::isClosed) { @Override protected void onWebSocketOpen(WebSocket webSocket, Response response) { readyState = WebSocketReadyState.OPEN; @@ -198,6 +207,7 @@ protected void onWebSocketClosed(WebSocket webSocket, int code, String reason) { } } }; + clientOptions.registerWebSocket(this); reconnectingListener.connect(); return connectionFuture; } @@ -206,7 +216,10 @@ protected void onWebSocketClosed(WebSocket webSocket, int code, String reason) { * Disconnects the WebSocket connection and releases resources. */ public void disconnect() { - reconnectingListener.disconnect(); + clientOptions.unregisterWebSocket(this); + if (reconnectingListener != null) { + reconnectingListener.disconnect(); + } if (timeoutExecutor != null) { timeoutExecutor.shutdownNow(); timeoutExecutor = null; diff --git a/src/main/java/com/deepgram/types/SharedIntents.java b/src/main/java/com/deepgram/types/SharedIntents.java index c689861..05799c2 100644 --- a/src/main/java/com/deepgram/types/SharedIntents.java +++ b/src/main/java/com/deepgram/types/SharedIntents.java @@ -13,6 +13,7 @@ import com.fasterxml.jackson.annotation.Nulls; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -20,18 +21,19 @@ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonDeserialize(builder = SharedIntents.Builder.class) public final class SharedIntents { - private final Optional results; + private final Optional> segments; private final Map additionalProperties; - private SharedIntents(Optional results, Map additionalProperties) { - this.results = results; + private SharedIntents( + Optional> segments, Map additionalProperties) { + this.segments = segments; this.additionalProperties = additionalProperties; } - @JsonProperty("results") - public Optional getResults() { - return results; + @JsonProperty("segments") + public Optional> getSegments() { + return segments; } @java.lang.Override @@ -46,12 +48,12 @@ public Map getAdditionalProperties() { } private boolean equalTo(SharedIntents other) { - return results.equals(other.results); + return segments.equals(other.segments); } @java.lang.Override public int hashCode() { - return Objects.hash(this.results); + return Objects.hash(this.segments); } @java.lang.Override @@ -65,7 +67,7 @@ public static Builder builder() { @JsonIgnoreProperties(ignoreUnknown = true) public static final class Builder { - private Optional results = Optional.empty(); + private Optional> segments = Optional.empty(); @JsonAnySetter private Map additionalProperties = new HashMap<>(); @@ -73,23 +75,23 @@ public static final class Builder { private Builder() {} public Builder from(SharedIntents other) { - results(other.getResults()); + segments(other.getSegments()); return this; } - @JsonSetter(value = "results", nulls = Nulls.SKIP) - public Builder results(Optional results) { - this.results = results; + @JsonSetter(value = "segments", nulls = Nulls.SKIP) + public Builder segments(Optional> segments) { + this.segments = segments; return this; } - public Builder results(SharedIntentsResults results) { - this.results = Optional.ofNullable(results); + public Builder segments(List segments) { + this.segments = Optional.ofNullable(segments); return this; } public SharedIntents build() { - return new SharedIntents(results, additionalProperties); + return new SharedIntents(segments, additionalProperties); } public Builder additionalProperty(String key, Object value) { diff --git a/src/main/java/com/deepgram/types/SharedIntentsResults.java b/src/main/java/com/deepgram/types/SharedIntentsResults.java deleted file mode 100644 index 44bfe37..0000000 --- a/src/main/java/com/deepgram/types/SharedIntentsResults.java +++ /dev/null @@ -1,106 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.types; - -import com.deepgram.core.ObjectMappers; -import com.fasterxml.jackson.annotation.JsonAnyGetter; -import com.fasterxml.jackson.annotation.JsonAnySetter; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonSetter; -import com.fasterxml.jackson.annotation.Nulls; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; - -@JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = SharedIntentsResults.Builder.class) -public final class SharedIntentsResults { - private final Optional intents; - - private final Map additionalProperties; - - private SharedIntentsResults( - Optional intents, Map additionalProperties) { - this.intents = intents; - this.additionalProperties = additionalProperties; - } - - @JsonProperty("intents") - public Optional getIntents() { - return intents; - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof SharedIntentsResults && equalTo((SharedIntentsResults) other); - } - - @JsonAnyGetter - public Map getAdditionalProperties() { - return this.additionalProperties; - } - - private boolean equalTo(SharedIntentsResults other) { - return intents.equals(other.intents); - } - - @java.lang.Override - public int hashCode() { - return Objects.hash(this.intents); - } - - @java.lang.Override - public String toString() { - return ObjectMappers.stringify(this); - } - - public static Builder builder() { - return new Builder(); - } - - @JsonIgnoreProperties(ignoreUnknown = true) - public static final class Builder { - private Optional intents = Optional.empty(); - - @JsonAnySetter - private Map additionalProperties = new HashMap<>(); - - private Builder() {} - - public Builder from(SharedIntentsResults other) { - intents(other.getIntents()); - return this; - } - - @JsonSetter(value = "intents", nulls = Nulls.SKIP) - public Builder intents(Optional intents) { - this.intents = intents; - return this; - } - - public Builder intents(SharedIntentsResultsIntents intents) { - this.intents = Optional.ofNullable(intents); - return this; - } - - public SharedIntentsResults build() { - return new SharedIntentsResults(intents, additionalProperties); - } - - public Builder additionalProperty(String key, Object value) { - this.additionalProperties.put(key, value); - return this; - } - - public Builder additionalProperties(Map additionalProperties) { - this.additionalProperties.putAll(additionalProperties); - return this; - } - } -} diff --git a/src/main/java/com/deepgram/types/SharedIntentsResultsIntents.java b/src/main/java/com/deepgram/types/SharedIntentsResultsIntents.java deleted file mode 100644 index a5fe89b..0000000 --- a/src/main/java/com/deepgram/types/SharedIntentsResultsIntents.java +++ /dev/null @@ -1,108 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.types; - -import com.deepgram.core.ObjectMappers; -import com.fasterxml.jackson.annotation.JsonAnyGetter; -import com.fasterxml.jackson.annotation.JsonAnySetter; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonSetter; -import com.fasterxml.jackson.annotation.Nulls; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; - -@JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = SharedIntentsResultsIntents.Builder.class) -public final class SharedIntentsResultsIntents { - private final Optional> segments; - - private final Map additionalProperties; - - private SharedIntentsResultsIntents( - Optional> segments, - Map additionalProperties) { - this.segments = segments; - this.additionalProperties = additionalProperties; - } - - @JsonProperty("segments") - public Optional> getSegments() { - return segments; - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof SharedIntentsResultsIntents && equalTo((SharedIntentsResultsIntents) other); - } - - @JsonAnyGetter - public Map getAdditionalProperties() { - return this.additionalProperties; - } - - private boolean equalTo(SharedIntentsResultsIntents other) { - return segments.equals(other.segments); - } - - @java.lang.Override - public int hashCode() { - return Objects.hash(this.segments); - } - - @java.lang.Override - public String toString() { - return ObjectMappers.stringify(this); - } - - public static Builder builder() { - return new Builder(); - } - - @JsonIgnoreProperties(ignoreUnknown = true) - public static final class Builder { - private Optional> segments = Optional.empty(); - - @JsonAnySetter - private Map additionalProperties = new HashMap<>(); - - private Builder() {} - - public Builder from(SharedIntentsResultsIntents other) { - segments(other.getSegments()); - return this; - } - - @JsonSetter(value = "segments", nulls = Nulls.SKIP) - public Builder segments(Optional> segments) { - this.segments = segments; - return this; - } - - public Builder segments(List segments) { - this.segments = Optional.ofNullable(segments); - return this; - } - - public SharedIntentsResultsIntents build() { - return new SharedIntentsResultsIntents(segments, additionalProperties); - } - - public Builder additionalProperty(String key, Object value) { - this.additionalProperties.put(key, value); - return this; - } - - public Builder additionalProperties(Map additionalProperties) { - this.additionalProperties.putAll(additionalProperties); - return this; - } - } -} diff --git a/src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItem.java b/src/main/java/com/deepgram/types/SharedIntentsSegmentsItem.java similarity index 78% rename from src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItem.java rename to src/main/java/com/deepgram/types/SharedIntentsSegmentsItem.java index 694be4f..431b68f 100644 --- a/src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItem.java +++ b/src/main/java/com/deepgram/types/SharedIntentsSegmentsItem.java @@ -19,23 +19,23 @@ import java.util.Optional; @JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = SharedIntentsResultsIntentsSegmentsItem.Builder.class) -public final class SharedIntentsResultsIntentsSegmentsItem { +@JsonDeserialize(builder = SharedIntentsSegmentsItem.Builder.class) +public final class SharedIntentsSegmentsItem { private final Optional text; private final Optional startWord; private final Optional endWord; - private final Optional> intents; + private final Optional> intents; private final Map additionalProperties; - private SharedIntentsResultsIntentsSegmentsItem( + private SharedIntentsSegmentsItem( Optional text, Optional startWord, Optional endWord, - Optional> intents, + Optional> intents, Map additionalProperties) { this.text = text; this.startWord = startWord; @@ -60,15 +60,14 @@ public Optional getEndWord() { } @JsonProperty("intents") - public Optional> getIntents() { + public Optional> getIntents() { return intents; } @java.lang.Override public boolean equals(Object other) { if (this == other) return true; - return other instanceof SharedIntentsResultsIntentsSegmentsItem - && equalTo((SharedIntentsResultsIntentsSegmentsItem) other); + return other instanceof SharedIntentsSegmentsItem && equalTo((SharedIntentsSegmentsItem) other); } @JsonAnyGetter @@ -76,7 +75,7 @@ public Map getAdditionalProperties() { return this.additionalProperties; } - private boolean equalTo(SharedIntentsResultsIntentsSegmentsItem other) { + private boolean equalTo(SharedIntentsSegmentsItem other) { return text.equals(other.text) && startWord.equals(other.startWord) && endWord.equals(other.endWord) @@ -105,14 +104,14 @@ public static final class Builder { private Optional endWord = Optional.empty(); - private Optional> intents = Optional.empty(); + private Optional> intents = Optional.empty(); @JsonAnySetter private Map additionalProperties = new HashMap<>(); private Builder() {} - public Builder from(SharedIntentsResultsIntentsSegmentsItem other) { + public Builder from(SharedIntentsSegmentsItem other) { text(other.getText()); startWord(other.getStartWord()); endWord(other.getEndWord()); @@ -154,18 +153,18 @@ public Builder endWord(Double endWord) { } @JsonSetter(value = "intents", nulls = Nulls.SKIP) - public Builder intents(Optional> intents) { + public Builder intents(Optional> intents) { this.intents = intents; return this; } - public Builder intents(List intents) { + public Builder intents(List intents) { this.intents = Optional.ofNullable(intents); return this; } - public SharedIntentsResultsIntentsSegmentsItem build() { - return new SharedIntentsResultsIntentsSegmentsItem(text, startWord, endWord, intents, additionalProperties); + public SharedIntentsSegmentsItem build() { + return new SharedIntentsSegmentsItem(text, startWord, endWord, intents, additionalProperties); } public Builder additionalProperty(String key, Object value) { diff --git a/src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItemIntentsItem.java b/src/main/java/com/deepgram/types/SharedIntentsSegmentsItemIntentsItem.java similarity index 81% rename from src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItemIntentsItem.java rename to src/main/java/com/deepgram/types/SharedIntentsSegmentsItemIntentsItem.java index d6554e2..9f97c91 100644 --- a/src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItemIntentsItem.java +++ b/src/main/java/com/deepgram/types/SharedIntentsSegmentsItemIntentsItem.java @@ -18,15 +18,15 @@ import java.util.Optional; @JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = SharedIntentsResultsIntentsSegmentsItemIntentsItem.Builder.class) -public final class SharedIntentsResultsIntentsSegmentsItemIntentsItem { +@JsonDeserialize(builder = SharedIntentsSegmentsItemIntentsItem.Builder.class) +public final class SharedIntentsSegmentsItemIntentsItem { private final Optional intent; private final Optional confidenceScore; private final Map additionalProperties; - private SharedIntentsResultsIntentsSegmentsItemIntentsItem( + private SharedIntentsSegmentsItemIntentsItem( Optional intent, Optional confidenceScore, Map additionalProperties) { this.intent = intent; this.confidenceScore = confidenceScore; @@ -46,8 +46,8 @@ public Optional getConfidenceScore() { @java.lang.Override public boolean equals(Object other) { if (this == other) return true; - return other instanceof SharedIntentsResultsIntentsSegmentsItemIntentsItem - && equalTo((SharedIntentsResultsIntentsSegmentsItemIntentsItem) other); + return other instanceof SharedIntentsSegmentsItemIntentsItem + && equalTo((SharedIntentsSegmentsItemIntentsItem) other); } @JsonAnyGetter @@ -55,7 +55,7 @@ public Map getAdditionalProperties() { return this.additionalProperties; } - private boolean equalTo(SharedIntentsResultsIntentsSegmentsItemIntentsItem other) { + private boolean equalTo(SharedIntentsSegmentsItemIntentsItem other) { return intent.equals(other.intent) && confidenceScore.equals(other.confidenceScore); } @@ -84,7 +84,7 @@ public static final class Builder { private Builder() {} - public Builder from(SharedIntentsResultsIntentsSegmentsItemIntentsItem other) { + public Builder from(SharedIntentsSegmentsItemIntentsItem other) { intent(other.getIntent()); confidenceScore(other.getConfidenceScore()); return this; @@ -112,9 +112,8 @@ public Builder confidenceScore(Float confidenceScore) { return this; } - public SharedIntentsResultsIntentsSegmentsItemIntentsItem build() { - return new SharedIntentsResultsIntentsSegmentsItemIntentsItem( - intent, confidenceScore, additionalProperties); + public SharedIntentsSegmentsItemIntentsItem build() { + return new SharedIntentsSegmentsItemIntentsItem(intent, confidenceScore, additionalProperties); } public Builder additionalProperty(String key, Object value) { diff --git a/src/main/java/com/deepgram/types/SharedTopics.java b/src/main/java/com/deepgram/types/SharedTopics.java index 463e84c..25a75ea 100644 --- a/src/main/java/com/deepgram/types/SharedTopics.java +++ b/src/main/java/com/deepgram/types/SharedTopics.java @@ -13,6 +13,7 @@ import com.fasterxml.jackson.annotation.Nulls; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -20,18 +21,18 @@ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonDeserialize(builder = SharedTopics.Builder.class) public final class SharedTopics { - private final Optional results; + private final Optional> segments; private final Map additionalProperties; - private SharedTopics(Optional results, Map additionalProperties) { - this.results = results; + private SharedTopics(Optional> segments, Map additionalProperties) { + this.segments = segments; this.additionalProperties = additionalProperties; } - @JsonProperty("results") - public Optional getResults() { - return results; + @JsonProperty("segments") + public Optional> getSegments() { + return segments; } @java.lang.Override @@ -46,12 +47,12 @@ public Map getAdditionalProperties() { } private boolean equalTo(SharedTopics other) { - return results.equals(other.results); + return segments.equals(other.segments); } @java.lang.Override public int hashCode() { - return Objects.hash(this.results); + return Objects.hash(this.segments); } @java.lang.Override @@ -65,7 +66,7 @@ public static Builder builder() { @JsonIgnoreProperties(ignoreUnknown = true) public static final class Builder { - private Optional results = Optional.empty(); + private Optional> segments = Optional.empty(); @JsonAnySetter private Map additionalProperties = new HashMap<>(); @@ -73,23 +74,23 @@ public static final class Builder { private Builder() {} public Builder from(SharedTopics other) { - results(other.getResults()); + segments(other.getSegments()); return this; } - @JsonSetter(value = "results", nulls = Nulls.SKIP) - public Builder results(Optional results) { - this.results = results; + @JsonSetter(value = "segments", nulls = Nulls.SKIP) + public Builder segments(Optional> segments) { + this.segments = segments; return this; } - public Builder results(SharedTopicsResults results) { - this.results = Optional.ofNullable(results); + public Builder segments(List segments) { + this.segments = Optional.ofNullable(segments); return this; } public SharedTopics build() { - return new SharedTopics(results, additionalProperties); + return new SharedTopics(segments, additionalProperties); } public Builder additionalProperty(String key, Object value) { diff --git a/src/main/java/com/deepgram/types/SharedTopicsResults.java b/src/main/java/com/deepgram/types/SharedTopicsResults.java deleted file mode 100644 index d25c8cc..0000000 --- a/src/main/java/com/deepgram/types/SharedTopicsResults.java +++ /dev/null @@ -1,105 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.types; - -import com.deepgram.core.ObjectMappers; -import com.fasterxml.jackson.annotation.JsonAnyGetter; -import com.fasterxml.jackson.annotation.JsonAnySetter; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonSetter; -import com.fasterxml.jackson.annotation.Nulls; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; - -@JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = SharedTopicsResults.Builder.class) -public final class SharedTopicsResults { - private final Optional topics; - - private final Map additionalProperties; - - private SharedTopicsResults(Optional topics, Map additionalProperties) { - this.topics = topics; - this.additionalProperties = additionalProperties; - } - - @JsonProperty("topics") - public Optional getTopics() { - return topics; - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof SharedTopicsResults && equalTo((SharedTopicsResults) other); - } - - @JsonAnyGetter - public Map getAdditionalProperties() { - return this.additionalProperties; - } - - private boolean equalTo(SharedTopicsResults other) { - return topics.equals(other.topics); - } - - @java.lang.Override - public int hashCode() { - return Objects.hash(this.topics); - } - - @java.lang.Override - public String toString() { - return ObjectMappers.stringify(this); - } - - public static Builder builder() { - return new Builder(); - } - - @JsonIgnoreProperties(ignoreUnknown = true) - public static final class Builder { - private Optional topics = Optional.empty(); - - @JsonAnySetter - private Map additionalProperties = new HashMap<>(); - - private Builder() {} - - public Builder from(SharedTopicsResults other) { - topics(other.getTopics()); - return this; - } - - @JsonSetter(value = "topics", nulls = Nulls.SKIP) - public Builder topics(Optional topics) { - this.topics = topics; - return this; - } - - public Builder topics(SharedTopicsResultsTopics topics) { - this.topics = Optional.ofNullable(topics); - return this; - } - - public SharedTopicsResults build() { - return new SharedTopicsResults(topics, additionalProperties); - } - - public Builder additionalProperty(String key, Object value) { - this.additionalProperties.put(key, value); - return this; - } - - public Builder additionalProperties(Map additionalProperties) { - this.additionalProperties.putAll(additionalProperties); - return this; - } - } -} diff --git a/src/main/java/com/deepgram/types/SharedTopicsResultsTopics.java b/src/main/java/com/deepgram/types/SharedTopicsResultsTopics.java deleted file mode 100644 index e3a1cbb..0000000 --- a/src/main/java/com/deepgram/types/SharedTopicsResultsTopics.java +++ /dev/null @@ -1,107 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.types; - -import com.deepgram.core.ObjectMappers; -import com.fasterxml.jackson.annotation.JsonAnyGetter; -import com.fasterxml.jackson.annotation.JsonAnySetter; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonSetter; -import com.fasterxml.jackson.annotation.Nulls; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; - -@JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = SharedTopicsResultsTopics.Builder.class) -public final class SharedTopicsResultsTopics { - private final Optional> segments; - - private final Map additionalProperties; - - private SharedTopicsResultsTopics( - Optional> segments, Map additionalProperties) { - this.segments = segments; - this.additionalProperties = additionalProperties; - } - - @JsonProperty("segments") - public Optional> getSegments() { - return segments; - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof SharedTopicsResultsTopics && equalTo((SharedTopicsResultsTopics) other); - } - - @JsonAnyGetter - public Map getAdditionalProperties() { - return this.additionalProperties; - } - - private boolean equalTo(SharedTopicsResultsTopics other) { - return segments.equals(other.segments); - } - - @java.lang.Override - public int hashCode() { - return Objects.hash(this.segments); - } - - @java.lang.Override - public String toString() { - return ObjectMappers.stringify(this); - } - - public static Builder builder() { - return new Builder(); - } - - @JsonIgnoreProperties(ignoreUnknown = true) - public static final class Builder { - private Optional> segments = Optional.empty(); - - @JsonAnySetter - private Map additionalProperties = new HashMap<>(); - - private Builder() {} - - public Builder from(SharedTopicsResultsTopics other) { - segments(other.getSegments()); - return this; - } - - @JsonSetter(value = "segments", nulls = Nulls.SKIP) - public Builder segments(Optional> segments) { - this.segments = segments; - return this; - } - - public Builder segments(List segments) { - this.segments = Optional.ofNullable(segments); - return this; - } - - public SharedTopicsResultsTopics build() { - return new SharedTopicsResultsTopics(segments, additionalProperties); - } - - public Builder additionalProperty(String key, Object value) { - this.additionalProperties.put(key, value); - return this; - } - - public Builder additionalProperties(Map additionalProperties) { - this.additionalProperties.putAll(additionalProperties); - return this; - } - } -} diff --git a/src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItem.java b/src/main/java/com/deepgram/types/SharedTopicsSegmentsItem.java similarity index 78% rename from src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItem.java rename to src/main/java/com/deepgram/types/SharedTopicsSegmentsItem.java index 19cd942..b479076 100644 --- a/src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItem.java +++ b/src/main/java/com/deepgram/types/SharedTopicsSegmentsItem.java @@ -19,23 +19,23 @@ import java.util.Optional; @JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = SharedTopicsResultsTopicsSegmentsItem.Builder.class) -public final class SharedTopicsResultsTopicsSegmentsItem { +@JsonDeserialize(builder = SharedTopicsSegmentsItem.Builder.class) +public final class SharedTopicsSegmentsItem { private final Optional text; private final Optional startWord; private final Optional endWord; - private final Optional> topics; + private final Optional> topics; private final Map additionalProperties; - private SharedTopicsResultsTopicsSegmentsItem( + private SharedTopicsSegmentsItem( Optional text, Optional startWord, Optional endWord, - Optional> topics, + Optional> topics, Map additionalProperties) { this.text = text; this.startWord = startWord; @@ -60,15 +60,14 @@ public Optional getEndWord() { } @JsonProperty("topics") - public Optional> getTopics() { + public Optional> getTopics() { return topics; } @java.lang.Override public boolean equals(Object other) { if (this == other) return true; - return other instanceof SharedTopicsResultsTopicsSegmentsItem - && equalTo((SharedTopicsResultsTopicsSegmentsItem) other); + return other instanceof SharedTopicsSegmentsItem && equalTo((SharedTopicsSegmentsItem) other); } @JsonAnyGetter @@ -76,7 +75,7 @@ public Map getAdditionalProperties() { return this.additionalProperties; } - private boolean equalTo(SharedTopicsResultsTopicsSegmentsItem other) { + private boolean equalTo(SharedTopicsSegmentsItem other) { return text.equals(other.text) && startWord.equals(other.startWord) && endWord.equals(other.endWord) @@ -105,14 +104,14 @@ public static final class Builder { private Optional endWord = Optional.empty(); - private Optional> topics = Optional.empty(); + private Optional> topics = Optional.empty(); @JsonAnySetter private Map additionalProperties = new HashMap<>(); private Builder() {} - public Builder from(SharedTopicsResultsTopicsSegmentsItem other) { + public Builder from(SharedTopicsSegmentsItem other) { text(other.getText()); startWord(other.getStartWord()); endWord(other.getEndWord()); @@ -154,18 +153,18 @@ public Builder endWord(Double endWord) { } @JsonSetter(value = "topics", nulls = Nulls.SKIP) - public Builder topics(Optional> topics) { + public Builder topics(Optional> topics) { this.topics = topics; return this; } - public Builder topics(List topics) { + public Builder topics(List topics) { this.topics = Optional.ofNullable(topics); return this; } - public SharedTopicsResultsTopicsSegmentsItem build() { - return new SharedTopicsResultsTopicsSegmentsItem(text, startWord, endWord, topics, additionalProperties); + public SharedTopicsSegmentsItem build() { + return new SharedTopicsSegmentsItem(text, startWord, endWord, topics, additionalProperties); } public Builder additionalProperty(String key, Object value) { diff --git a/src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItemTopicsItem.java b/src/main/java/com/deepgram/types/SharedTopicsSegmentsItemTopicsItem.java similarity index 82% rename from src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItemTopicsItem.java rename to src/main/java/com/deepgram/types/SharedTopicsSegmentsItemTopicsItem.java index 3721cd8..03464d2 100644 --- a/src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItemTopicsItem.java +++ b/src/main/java/com/deepgram/types/SharedTopicsSegmentsItemTopicsItem.java @@ -18,15 +18,15 @@ import java.util.Optional; @JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = SharedTopicsResultsTopicsSegmentsItemTopicsItem.Builder.class) -public final class SharedTopicsResultsTopicsSegmentsItemTopicsItem { +@JsonDeserialize(builder = SharedTopicsSegmentsItemTopicsItem.Builder.class) +public final class SharedTopicsSegmentsItemTopicsItem { private final Optional topic; private final Optional confidenceScore; private final Map additionalProperties; - private SharedTopicsResultsTopicsSegmentsItemTopicsItem( + private SharedTopicsSegmentsItemTopicsItem( Optional topic, Optional confidenceScore, Map additionalProperties) { this.topic = topic; this.confidenceScore = confidenceScore; @@ -46,8 +46,8 @@ public Optional getConfidenceScore() { @java.lang.Override public boolean equals(Object other) { if (this == other) return true; - return other instanceof SharedTopicsResultsTopicsSegmentsItemTopicsItem - && equalTo((SharedTopicsResultsTopicsSegmentsItemTopicsItem) other); + return other instanceof SharedTopicsSegmentsItemTopicsItem + && equalTo((SharedTopicsSegmentsItemTopicsItem) other); } @JsonAnyGetter @@ -55,7 +55,7 @@ public Map getAdditionalProperties() { return this.additionalProperties; } - private boolean equalTo(SharedTopicsResultsTopicsSegmentsItemTopicsItem other) { + private boolean equalTo(SharedTopicsSegmentsItemTopicsItem other) { return topic.equals(other.topic) && confidenceScore.equals(other.confidenceScore); } @@ -84,7 +84,7 @@ public static final class Builder { private Builder() {} - public Builder from(SharedTopicsResultsTopicsSegmentsItemTopicsItem other) { + public Builder from(SharedTopicsSegmentsItemTopicsItem other) { topic(other.getTopic()); confidenceScore(other.getConfidenceScore()); return this; @@ -112,8 +112,8 @@ public Builder confidenceScore(Float confidenceScore) { return this; } - public SharedTopicsResultsTopicsSegmentsItemTopicsItem build() { - return new SharedTopicsResultsTopicsSegmentsItemTopicsItem(topic, confidenceScore, additionalProperties); + public SharedTopicsSegmentsItemTopicsItem build() { + return new SharedTopicsSegmentsItemTopicsItem(topic, confidenceScore, additionalProperties); } public Builder additionalProperty(String key, Object value) { From 5d4abb78ad56c7dc62d89a2fb958ae676f80aabd Mon Sep 17 00:00:00 2001 From: Greg Holmes Date: Wed, 14 Oct 2026 12:11:15 +0100 Subject: [PATCH 5/8] chore: re-apply manual patches after regen --- .fernignore | 63 +- AGENTS.md | 2 + .../java/com/deepgram/core/ClientOptions.java | 9 +- .../com/deepgram/core/ClientOptions.java.bak | 408 ------- .../core/ReconnectingWebSocketListener.java | 61 +- .../ReconnectingWebSocketListener.java.bak | 622 ---------- .../agent/v1/types/AgentV1AgentAudioDone.java | 5 + .../v1/types/AgentV1AgentAudioDone.java.bak | 83 -- .../agent/v1/types/AgentV1ForceEndTurn.java | 5 + .../v1/types/AgentV1ForceEndTurn.java.bak | 83 -- .../agent/v1/types/AgentV1KeepAlive.java | 5 + .../agent/v1/types/AgentV1KeepAlive.java.bak | 83 -- .../agent/v1/types/AgentV1ListenUpdated.java | 5 + .../v1/types/AgentV1ListenUpdated.java.bak | 83 -- .../agent/v1/types/AgentV1PromptUpdated.java | 5 + .../v1/types/AgentV1PromptUpdated.java.bak | 83 -- ...tV1SettingsAgentContextListenProvider.java | 2 +- ...ettingsAgentContextListenProvider.java.bak | 224 ---- .../AgentV1SettingsAgentListenProvider.java | 2 +- ...gentV1SettingsAgentListenProvider.java.bak | 224 ---- .../v1/types/AgentV1SettingsApplied.java | 5 + .../v1/types/AgentV1SettingsApplied.java.bak | 83 -- .../agent/v1/types/AgentV1SpeakUpdated.java | 5 + .../v1/types/AgentV1SpeakUpdated.java.bak | 83 -- .../agent/v1/types/AgentV1ThinkUpdated.java | 5 + .../v1/types/AgentV1ThinkUpdated.java.bak | 83 -- .../AgentV1UpdateListenListenProvider.java | 2 +- ...AgentV1UpdateListenListenProvider.java.bak | 224 ---- .../v1/types/AgentV1UserStartedSpeaking.java | 5 + .../types/AgentV1UserStartedSpeaking.java.bak | 83 -- .../v1/websocket/V1WebSocketClient.java | 27 +- .../v1/websocket/V1WebSocketClient.java.bak | 592 --------- .../listen/v2/types/ListenV2CloseStream.java | 5 + .../v2/types/ListenV2CloseStream.java.bak | 83 -- .../listen/v2/types/ListenV2ForceEndTurn.java | 5 + .../v2/types/ListenV2ForceEndTurn.java.bak | 83 -- .../v2/websocket/V2WebSocketClient.java | 47 +- .../v2/websocket/V2WebSocketClient.java.bak | 563 --------- .../speak/v1/websocket/V1WebSocketClient.java | 8 + .../v1/websocket/V1WebSocketClient.java.bak | 467 ------- .../speak/v2/types/SpeakV2Close.java | 5 + .../speak/v2/types/SpeakV2Close.java.bak | 83 -- .../v2/types/SpeakV2ConfigureFailureCode.java | 4 +- .../speak/v2/types/SpeakV2Flush.java | 5 + .../speak/v2/types/SpeakV2Flush.java.bak | 83 -- .../speak/v2/websocket/V2WebSocketClient.java | 17 +- .../v2/websocket/V2WebSocketClient.java.bak | 630 ---------- .../com/deepgram/types/DeepgramModel.java | 14 + .../com/deepgram/types/DeepgramModel.java.bak | 1071 ----------------- .../com/deepgram/types/SharedIntents.java | 27 + .../deepgram/types/SharedIntentsResults.java | 56 + .../types/SharedIntentsResultsIntents.java | 64 + ...aredIntentsResultsIntentsSegmentsItem.java | 106 ++ ...ResultsIntentsSegmentsItemIntentsItem.java | 77 ++ .../java/com/deepgram/types/SharedTopics.java | 27 + .../deepgram/types/SharedTopicsResults.java | 56 + .../types/SharedTopicsResultsTopics.java | 64 + ...SharedTopicsResultsTopicsSegmentsItem.java | 106 ++ ...csResultsTopicsSegmentsItemTopicsItem.java | 110 ++ .../java/com/deepgram/RegenTypesTest.java | 76 +- 60 files changed, 1007 insertions(+), 6189 deletions(-) delete mode 100644 src/main/java/com/deepgram/core/ClientOptions.java.bak delete mode 100644 src/main/java/com/deepgram/core/ReconnectingWebSocketListener.java.bak delete mode 100644 src/main/java/com/deepgram/resources/agent/v1/types/AgentV1AgentAudioDone.java.bak delete mode 100644 src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ForceEndTurn.java.bak delete mode 100644 src/main/java/com/deepgram/resources/agent/v1/types/AgentV1KeepAlive.java.bak delete mode 100644 src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ListenUpdated.java.bak delete mode 100644 src/main/java/com/deepgram/resources/agent/v1/types/AgentV1PromptUpdated.java.bak delete mode 100644 src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentContextListenProvider.java.bak delete mode 100644 src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentListenProvider.java.bak delete mode 100644 src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsApplied.java.bak delete mode 100644 src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SpeakUpdated.java.bak delete mode 100644 src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ThinkUpdated.java.bak delete mode 100644 src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UpdateListenListenProvider.java.bak delete mode 100644 src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UserStartedSpeaking.java.bak delete mode 100644 src/main/java/com/deepgram/resources/listen/v1/websocket/V1WebSocketClient.java.bak delete mode 100644 src/main/java/com/deepgram/resources/listen/v2/types/ListenV2CloseStream.java.bak delete mode 100644 src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ForceEndTurn.java.bak delete mode 100644 src/main/java/com/deepgram/resources/listen/v2/websocket/V2WebSocketClient.java.bak delete mode 100644 src/main/java/com/deepgram/resources/speak/v1/websocket/V1WebSocketClient.java.bak delete mode 100644 src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Close.java.bak delete mode 100644 src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Flush.java.bak delete mode 100644 src/main/java/com/deepgram/resources/speak/v2/websocket/V2WebSocketClient.java.bak delete mode 100644 src/main/java/com/deepgram/types/DeepgramModel.java.bak create mode 100644 src/main/java/com/deepgram/types/SharedIntentsResults.java create mode 100644 src/main/java/com/deepgram/types/SharedIntentsResultsIntents.java create mode 100644 src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItem.java create mode 100644 src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItemIntentsItem.java create mode 100644 src/main/java/com/deepgram/types/SharedTopicsResults.java create mode 100644 src/main/java/com/deepgram/types/SharedTopicsResultsTopics.java create mode 100644 src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItem.java create mode 100644 src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItemTopicsItem.java diff --git a/.fernignore b/.fernignore index e8b7713..672b6b1 100644 --- a/.fernignore +++ b/.fernignore @@ -16,7 +16,7 @@ src/main/java/com/deepgram/AsyncDeepgramClientBuilder.java # Fern regen overwrites these with incorrect SDK names and strips the markers. # Fern 4.22.1 closes tracked WebSockets before SDK-owned OkHttp resources; retain that lifecycle behavior while # reapplying only these headers. -src/main/java/com/deepgram/core/ClientOptions.java.bak +src/main/java/com/deepgram/core/ClientOptions.java # Transport abstraction (pluggable transport for SageMaker, etc.) src/main/java/com/deepgram/core/transport/ @@ -29,7 +29,7 @@ src/main/java/com/deepgram/resources/listen/v1/websocket/ListenV1ErrorException. # Bug fixes for maxRetries(0) semantics ("connect once, don't retry") and a # configurable connectionTimeoutMs on ReconnectOptions (was hardcoded 4000ms). # Pull this back out once the fixes are upstreamed into the Fern generator. -src/main/java/com/deepgram/core/ReconnectingWebSocketListener.java.bak +src/main/java/com/deepgram/core/ReconnectingWebSocketListener.java # Forward-compat patch: Fern's generated dispatcher routes any unrecognized message # type to the error handler ("Update your SDK version..."), which makes benign new @@ -39,8 +39,8 @@ src/main/java/com/deepgram/core/ReconnectingWebSocketListener.java.bak # NOTE: the listen v2 and speak v2 clients below also carry the streaming query-param patches # (multi-value serialization + the additionalProperties escape hatch) documented lower down — # keep them frozen until those fixes are upstreamed too. -src/main/java/com/deepgram/resources/speak/v2/websocket/V2WebSocketClient.java.bak -src/main/java/com/deepgram/resources/listen/v2/websocket/V2WebSocketClient.java.bak +src/main/java/com/deepgram/resources/speak/v2/websocket/V2WebSocketClient.java +src/main/java/com/deepgram/resources/listen/v2/websocket/V2WebSocketClient.java # Streaming query-param patches on the generated WS connect() builders. Two fixes: # (1) Multi-value serialization: array-valued params (listen: keyterm, keywords, replace, search, @@ -54,8 +54,8 @@ src/main/java/com/deepgram/resources/listen/v2/websocket/V2WebSocketClient.java. # listen v2 and speak v2 clients are frozen above; freeze the listen v1 and speak v1 clients here too # so the fixes survive regen. Re-apply after regen; unfreeze once the generator emits array params as # repeats and serializes additionalProperties on the WS connect path (tracked as an upstream Fern request). -src/main/java/com/deepgram/resources/listen/v1/websocket/V1WebSocketClient.java.bak -src/main/java/com/deepgram/resources/speak/v1/websocket/V1WebSocketClient.java.bak +src/main/java/com/deepgram/resources/listen/v1/websocket/V1WebSocketClient.java +src/main/java/com/deepgram/resources/speak/v1/websocket/V1WebSocketClient.java # Restores the FLUX_RENEE_EN constant that generator 4.18.0 dropped. The voice is live: # POST /v2/speak?model=flux-renee-en returns 200 with valid audio, and the name resolves in the @@ -67,25 +67,25 @@ src/main/java/com/deepgram/resources/speak/v1/websocket/V1WebSocketClient.java.b # changes -- 4.18.0 alone added 25 constants. On the next regen do NOT restore the .bak wholesale: # diff it against the newly generated file, carry forward every new voice, and re-apply only the # FLUX_RENEE_EN touchpoints (constant, Value enum, visit() case, valueOf() case, Visitor method). -src/main/java/com/deepgram/types/DeepgramModel.java.bak +src/main/java/com/deepgram/types/DeepgramModel.java # Manual equals/hashCode contract fix: Fern generates equals() (all instances equal) but no # hashCode() for fields-less message types, violating the Object contract. We add a consistent # hashCode() to each. Unfreeze and drop these patches once the generator emits a matching # equals/hashCode pair for fields-less types (tracked as an upstream Fern request). -src/main/java/com/deepgram/resources/listen/v2/types/ListenV2CloseStream.java.bak -src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ForceEndTurn.java.bak -src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Close.java.bak -src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Flush.java.bak -src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ListenUpdated.java.bak -src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SpeakUpdated.java.bak -src/main/java/com/deepgram/resources/agent/v1/types/AgentV1AgentAudioDone.java.bak -src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsApplied.java.bak -src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UserStartedSpeaking.java.bak -src/main/java/com/deepgram/resources/agent/v1/types/AgentV1KeepAlive.java.bak -src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ThinkUpdated.java.bak -src/main/java/com/deepgram/resources/agent/v1/types/AgentV1PromptUpdated.java.bak -src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ForceEndTurn.java.bak +src/main/java/com/deepgram/resources/listen/v2/types/ListenV2CloseStream.java +src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ForceEndTurn.java +src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Close.java +src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Flush.java +src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ListenUpdated.java +src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SpeakUpdated.java +src/main/java/com/deepgram/resources/agent/v1/types/AgentV1AgentAudioDone.java +src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsApplied.java +src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UserStartedSpeaking.java +src/main/java/com/deepgram/resources/agent/v1/types/AgentV1KeepAlive.java +src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ThinkUpdated.java +src/main/java/com/deepgram/resources/agent/v1/types/AgentV1PromptUpdated.java +src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ForceEndTurn.java # Union default-variant fix (STOPGAP). The agent listen-provider unions declare `version` as an # optional discriminator, so a provider payload without it is valid (and is what 0.7.x emits). Fern @@ -94,9 +94,26 @@ src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ForceEndTurn.java.bak # {"provider":null}, silently dropping the caller's provider on the wire. Patched to # defaultImpl = V2Value on each. Guarded by AgentSettingsProviderDefaultTest. Unfreeze and drop once # the generator stops defaulting unions to the empty _UnknownValue (tracked as an upstream Fern request). -src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UpdateListenListenProvider.java.bak -src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentListenProvider.java.bak -src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentContextListenProvider.java.bak +src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UpdateListenListenProvider.java +src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentListenProvider.java +src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentContextListenProvider.java + +# Backward-compatible Topics/Intents results facades preserve the removed traversal and +# renamed item types while the generated response models continue to use direct segments. +src/main/java/com/deepgram/types/SharedTopics.java +src/main/java/com/deepgram/types/SharedTopicsResults.java +src/main/java/com/deepgram/types/SharedTopicsResultsTopics.java +src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItem.java +src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItemTopicsItem.java +src/main/java/com/deepgram/types/SharedIntents.java +src/main/java/com/deepgram/types/SharedIntentsResults.java +src/main/java/com/deepgram/types/SharedIntentsResultsIntents.java +src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItem.java +src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItemIntentsItem.java + +# Preserve binary-compatible Visitor implementations from before this generated enum added +# CONTROL_COMBINATION_INVALID. The default method routes old visitors through visitUnknown. +src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2ConfigureFailureCode.java # Build and project configuration build.gradle diff --git a/AGENTS.md b/AGENTS.md index ea1c345..33fd192 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -55,6 +55,8 @@ Current temporarily frozen files: - Fields-less message types carrying a manual `hashCode()` patch (Fern generates `equals()` but no `hashCode()` for these, violating the Object contract): `src/main/java/com/deepgram/resources/listen/v2/types/ListenV2CloseStream.java`, `src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ForceEndTurn.java`, `src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Close.java`, `src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Flush.java`, and the `AgentV1*` event types `src/main/java/com/deepgram/resources/agent/v1/types/{AgentV1ListenUpdated,AgentV1SpeakUpdated,AgentV1AgentAudioDone,AgentV1SettingsApplied,AgentV1UserStartedSpeaking,AgentV1KeepAlive,AgentV1ThinkUpdated,AgentV1PromptUpdated,AgentV1ForceEndTurn}.java`. Use the standard `.bak` swap/restore workflow during regen review; drop the patches and unfreeze all of them once the generator emits a matching equals/hashCode pair for fields-less types (tracked as an upstream Fern request). - `src/main/java/com/deepgram/types/DeepgramModel.java` - restores the `FLUX_RENEE_EN` constant that generator 4.18.0 dropped. The voice is live: `POST /v2/speak?model=flux-renee-en` returns 200 with valid audio, and the name resolves in the server's model registry (an invented `flux-*` name is rejected with `INVALID_QUERY_PARAMETER`), so the removal is a spec regression rather than a retirement, and dropping the constant would break 0.8.0 callers for nothing. Five touchpoints: the constant, the `Value` enum entry, the `visit()` case, the `valueOf()` case, and the `Visitor` method. **This file is unlike the other temporarily frozen ones — it receives frequent additive spec changes (4.18.0 alone added 25 constants), so on the next regen do NOT restore the `.bak` wholesale.** Diff the `.bak` against the newly generated file, carry forward every new voice, and re-apply only the `FLUX_RENEE_EN` touchpoints. Drop the patch and unfreeze once the spec lists the voice again (tracked as an upstream spec request). - Union default-variant fix on the agent listen-provider unions: `src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UpdateListenListenProvider.java`, `src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentListenProvider.java`, `src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentContextListenProvider.java`. `version` is an optional discriminator, so a provider payload without it is valid (and is what 0.7.x emits), but Fern points `@JsonTypeInfo` `defaultImpl` at the empty-bodied `_UnknownValue`, so such a payload deserializes to an unknown variant carrying `null` — `getProvider()` returns `null` and re-serialization emits `{"provider":null}`, silently dropping the provider on the wire. Patched to `defaultImpl = V2Value` on each; guarded by `src/test/java/com/deepgram/AgentSettingsProviderDefaultTest.java`. Use the standard `.bak` swap/restore workflow during regen review; drop the patches and unfreeze once the generator stops defaulting unions to the empty `_UnknownValue` (tracked as an upstream Fern request). +- `src/main/java/com/deepgram/types/SharedTopics.java`, `SharedIntents.java`, and the eight `Shared{Topics,Intents}Results...` facade types preserve the pre-0.11 `results.*.segments` traversal and renamed item classes while retaining the generated direct `segments` payload model. The facades translate legacy builders and accessors to the current generated types and are deliberately excluded from JSON serialization. Guarded by `src/test/java/com/deepgram/RegenTypesTest.java`. Keep these frozen until the next major release. +- `src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2ConfigureFailureCode.java` makes `Visitor.visitControlCombinationInvalid()` a default method that delegates to `visitUnknown("CONTROL_COMBINATION_INVALID")`. This preserves source compatibility for visitors compiled against the pre-controls API while retaining the new generated enum value. Guarded by `src/test/java/com/deepgram/RegenTypesTest.java`. Keep frozen until the next major release. ### Prepare repo for regeneration diff --git a/src/main/java/com/deepgram/core/ClientOptions.java b/src/main/java/com/deepgram/core/ClientOptions.java index e0ad853..b20db7f 100644 --- a/src/main/java/com/deepgram/core/ClientOptions.java +++ b/src/main/java/com/deepgram/core/ClientOptions.java @@ -63,10 +63,10 @@ private ClientOptions( this.headers.putAll(headers); this.headers.putAll(new HashMap() { { - put("User-Agent", "com.deepgram.deepgram-java-sdk/" + getSdkVersion()); + put("User-Agent", "com.deepgram:deepgram-java-sdk/0.11.2"); // x-release-please-version put("X-Fern-Language", "JAVA"); put("X-Fern-SDK-Name", "com.deepgram:deepgram-java-sdk"); - put("X-Fern-SDK-Version", getSdkVersion()); + put("X-Fern-SDK-Version", "0.11.2"); // x-release-please-version } }); this.headerSuppliers = headerSuppliers; @@ -98,11 +98,6 @@ public Map headers(RequestOptions requestOptions) { return values; } - private static String getSdkVersion() { - String version = ClientOptions.class.getPackage().getImplementationVersion(); - return version != null ? version : "0.11.2"; - } - public int timeout(RequestOptions requestOptions) { if (requestOptions == null) { return this.timeout; diff --git a/src/main/java/com/deepgram/core/ClientOptions.java.bak b/src/main/java/com/deepgram/core/ClientOptions.java.bak deleted file mode 100644 index b2c87ee..0000000 --- a/src/main/java/com/deepgram/core/ClientOptions.java.bak +++ /dev/null @@ -1,408 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.core; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Supplier; -import okhttp3.OkHttpClient; - -public final class ClientOptions { - private final Environment environment; - - private final Map headers; - - private final Map> headerSuppliers; - - private final OkHttpClient httpClient; - - private final boolean ownsHttpClient; - - private final AtomicBoolean closed; - - private final Set openWebSockets; - - private final int timeout; - - private final int maxRetries; - - private final Optional initialRetryDelayMillis; - - private final Optional maxRetryDelayMillis; - - private final Optional retryJitterFactor; - - private final Optional webSocketFactory; - - private final Optional logging; - - private ClientOptions( - Environment environment, - Map headers, - Map> headerSuppliers, - OkHttpClient httpClient, - boolean ownsHttpClient, - AtomicBoolean closed, - Set openWebSockets, - int timeout, - int maxRetries, - Optional initialRetryDelayMillis, - Optional maxRetryDelayMillis, - Optional retryJitterFactor, - Optional webSocketFactory, - Optional logging) { - this.environment = environment; - this.headers = new HashMap<>(); - this.headers.putAll(headers); - this.headers.putAll(new HashMap() { - { - put("User-Agent", "com.deepgram:deepgram-java-sdk/0.11.1"); // x-release-please-version - put("X-Fern-Language", "JAVA"); - put("X-Fern-SDK-Name", "com.deepgram:deepgram-java-sdk"); - put("X-Fern-SDK-Version", "0.11.1"); // x-release-please-version - } - }); - this.headerSuppliers = headerSuppliers; - this.httpClient = httpClient; - this.ownsHttpClient = ownsHttpClient; - this.closed = closed; - this.openWebSockets = openWebSockets; - this.timeout = timeout; - this.maxRetries = maxRetries; - this.initialRetryDelayMillis = initialRetryDelayMillis; - this.maxRetryDelayMillis = maxRetryDelayMillis; - this.retryJitterFactor = retryJitterFactor; - this.webSocketFactory = webSocketFactory; - this.logging = logging; - } - - public Environment environment() { - return this.environment; - } - - public Map headers(RequestOptions requestOptions) { - Map values = new HashMap<>(this.headers); - headerSuppliers.forEach((key, supplier) -> { - values.put(key, supplier.get()); - }); - if (requestOptions != null) { - values.putAll(requestOptions.getHeaders()); - } - return values; - } - - public int timeout(RequestOptions requestOptions) { - if (requestOptions == null) { - return this.timeout; - } - return requestOptions.getTimeout().orElse(this.timeout); - } - - public OkHttpClient httpClient() { - return this.httpClient; - } - - public OkHttpClient httpClientWithTimeout(RequestOptions requestOptions) { - if (requestOptions == null) { - return this.httpClient; - } - return this.httpClient - .newBuilder() - .callTimeout(requestOptions.getTimeout().get(), requestOptions.getTimeoutTimeUnit()) - .connectTimeout(0, TimeUnit.SECONDS) - .writeTimeout(0, TimeUnit.SECONDS) - .readTimeout(0, TimeUnit.SECONDS) - .build(); - } - - public int maxRetries() { - return this.maxRetries; - } - - public Optional initialRetryDelayMillis() { - return this.initialRetryDelayMillis; - } - - public Optional maxRetryDelayMillis() { - return this.maxRetryDelayMillis; - } - - public Optional retryJitterFactor() { - return this.retryJitterFactor; - } - - /** - * Releases resources owned by this client. Only shuts down the underlying OkHttpClient's - * dispatcher executor and evicts its connection pool when this client created that - * OkHttpClient itself; an OkHttpClient supplied via httpClient is left running, since the - * caller owns its lifecycle. - *

- * In-flight calls are not cancelled or awaited. When this client owns its OkHttpClient, later - * asynchronous HTTP requests can fail when the dispatcher rejects work, while synchronous - * requests may still run. An OkHttpClient supplied through {@code httpClient(...)} remains - * caller-owned and running. Options derived via {@code Builder.from(...)} share lifecycle - * state; calling this method more than once has no further effect. - *

- * WebSocket clients created from this client that are still connected are disconnected - * first (whether or not the OkHttpClient is owned), so they stop reconnecting before the - * dispatcher goes away. Any WebSocket connect or reconnect attempted afterwards fails with - * an {@code IllegalStateException} explaining that the client has been closed. - */ - public void close() { - if (!this.closed.compareAndSet(false, true)) { - return; - } - for (AutoCloseable webSocket : new ArrayList<>(this.openWebSockets)) { - try { - webSocket.close(); - } catch (Exception e) { - // best effort; keep closing the remaining sockets and the HTTP client - } - } - this.openWebSockets.clear(); - if (!this.ownsHttpClient) { - return; - } - this.httpClient.dispatcher().executorService().shutdown(); - this.httpClient.connectionPool().evictAll(); - } - - /** - * Returns whether {@link #close()} has been called on this client. - */ - public boolean isClosed() { - return this.closed.get(); - } - - /** - * Tracks a connected WebSocket client so that {@link #close()} disconnects it. - * - * @throws IllegalStateException if this client has already been closed - */ - public void registerWebSocket(AutoCloseable webSocket) { - this.openWebSockets.add(webSocket); - if (this.closed.get()) { - this.openWebSockets.remove(webSocket); - throw new IllegalStateException("root client has been closed"); - } - } - - /** - * Stops tracking a WebSocket client that has been disconnected. - */ - public void unregisterWebSocket(AutoCloseable webSocket) { - this.openWebSockets.remove(webSocket); - } - - public Optional webSocketFactory() { - return this.webSocketFactory; - } - - public Optional logging() { - return this.logging; - } - - public static Builder builder() { - return new Builder(); - } - - public static class Builder { - private Environment environment; - - private final Map headers = new HashMap<>(); - - private final Map> headerSuppliers = new HashMap<>(); - - private int maxRetries = 2; - - private Optional initialRetryDelayMillis = Optional.empty(); - - private Optional maxRetryDelayMillis = Optional.empty(); - - private Optional retryJitterFactor = Optional.empty(); - - private Optional timeout = Optional.empty(); - - private OkHttpClient httpClient = null; - - private boolean ownsHttpClient = true; - - private AtomicBoolean closed; - - private Set openWebSockets; - - private Optional logging = Optional.empty(); - - private Optional webSocketFactory = Optional.empty(); - - public Builder environment(Environment environment) { - this.environment = environment; - return this; - } - - public Builder addHeader(String key, String value) { - if (value != null) { - this.headers.put(key, value); - } - return this; - } - - public Builder addHeader(String key, Supplier value) { - this.headerSuppliers.put(key, value); - return this; - } - - /** - * Override the timeout in seconds. Defaults to 60 seconds. - */ - public Builder timeout(int timeout) { - this.timeout = Optional.of(timeout); - return this; - } - - /** - * Override the timeout in seconds. Defaults to 60 seconds. - */ - public Builder timeout(Optional timeout) { - this.timeout = timeout; - return this; - } - - /** - * Override the maximum number of retries. Defaults to 2 retries. - */ - public Builder maxRetries(int maxRetries) { - this.maxRetries = maxRetries; - return this; - } - - /** - * Override the initial delay (in milliseconds) used for exponential backoff between retries. Defaults to 1000 milliseconds. - */ - public Builder initialRetryDelayMillis(long initialRetryDelayMillis) { - this.initialRetryDelayMillis = Optional.of(initialRetryDelayMillis); - return this; - } - - /** - * Override the maximum delay (in milliseconds) between retries. Defaults to 60000 milliseconds. - */ - public Builder maxRetryDelayMillis(long maxRetryDelayMillis) { - this.maxRetryDelayMillis = Optional.of(maxRetryDelayMillis); - return this; - } - - /** - * Override the jitter factor (between 0 and 1) applied to retry delays. Defaults to 0.2. - */ - public Builder retryJitterFactor(double retryJitterFactor) { - this.retryJitterFactor = Optional.of(retryJitterFactor); - return this; - } - - /** - * Sets the underlying OkHttp client. The caller retains ownership of its lifecycle: - * close() will not shut down its dispatcher executor or evict its connection pool. - */ - public Builder httpClient(OkHttpClient httpClient) { - this.httpClient = httpClient; - this.ownsHttpClient = httpClient == null; - return this; - } - - /** - * Set a custom WebSocketFactory for creating WebSocket connections. - */ - public Builder webSocketFactory(WebSocketFactory webSocketFactory) { - this.webSocketFactory = Optional.of(webSocketFactory); - return this; - } - - /** - * Configure logging for the SDK. Silent by default — no log output unless explicitly configured. - */ - public Builder logging(LogConfig logging) { - this.logging = Optional.of(logging); - return this; - } - - public ClientOptions build() { - OkHttpClient.Builder httpClientBuilder = - this.httpClient != null ? this.httpClient.newBuilder() : new OkHttpClient.Builder(); - - if (this.httpClient != null) { - timeout.ifPresent(timeout -> httpClientBuilder - .callTimeout(timeout, TimeUnit.SECONDS) - .connectTimeout(0, TimeUnit.SECONDS) - .writeTimeout(0, TimeUnit.SECONDS) - .readTimeout(0, TimeUnit.SECONDS)); - } else { - httpClientBuilder - .callTimeout(this.timeout.orElse(60), TimeUnit.SECONDS) - .connectTimeout(0, TimeUnit.SECONDS) - .writeTimeout(0, TimeUnit.SECONDS) - .readTimeout(0, TimeUnit.SECONDS) - .addInterceptor(new RetryInterceptor( - this.maxRetries, - this.initialRetryDelayMillis, - this.maxRetryDelayMillis, - this.retryJitterFactor)); - } - - Logger logger = Logger.from(this.logging); - httpClientBuilder.addInterceptor(new LoggingInterceptor(logger)); - httpClientBuilder.addInterceptor(new ResponseDecompressionInterceptor()); - - this.httpClient = httpClientBuilder.build(); - this.timeout = Optional.of(httpClient.callTimeoutMillis() / 1000); - - AtomicBoolean closedToUse = this.closed != null ? this.closed : new AtomicBoolean(false); - Set openWebSocketsToUse = - this.openWebSockets != null ? this.openWebSockets : ConcurrentHashMap.newKeySet(); - - return new ClientOptions( - environment, - headers, - headerSuppliers, - httpClient, - this.ownsHttpClient, - closedToUse, - openWebSocketsToUse, - this.timeout.get(), - this.maxRetries, - this.initialRetryDelayMillis, - this.maxRetryDelayMillis, - this.retryJitterFactor, - this.webSocketFactory, - this.logging); - } - - /** - * Create a new Builder initialized with values from an existing ClientOptions - */ - public static Builder from(ClientOptions clientOptions) { - Builder builder = new Builder(); - builder.environment = clientOptions.environment(); - builder.timeout = Optional.of(clientOptions.timeout(null)); - builder.httpClient = clientOptions.httpClient(); - builder.ownsHttpClient = clientOptions.ownsHttpClient; - builder.closed = clientOptions.closed; - builder.openWebSockets = clientOptions.openWebSockets; - builder.headers.putAll(clientOptions.headers); - builder.headerSuppliers.putAll(clientOptions.headerSuppliers); - builder.maxRetries = clientOptions.maxRetries(); - builder.initialRetryDelayMillis = clientOptions.initialRetryDelayMillis(); - builder.maxRetryDelayMillis = clientOptions.maxRetryDelayMillis(); - builder.retryJitterFactor = clientOptions.retryJitterFactor(); - builder.logging = clientOptions.logging(); - return builder; - } - } -} diff --git a/src/main/java/com/deepgram/core/ReconnectingWebSocketListener.java b/src/main/java/com/deepgram/core/ReconnectingWebSocketListener.java index dc32da2..b51aacc 100644 --- a/src/main/java/com/deepgram/core/ReconnectingWebSocketListener.java +++ b/src/main/java/com/deepgram/core/ReconnectingWebSocketListener.java @@ -27,13 +27,7 @@ * Provides production-ready resilience for WebSocket connections. */ public abstract class ReconnectingWebSocketListener extends WebSocketListener { - private final long minReconnectionDelayMs; - - private final long maxReconnectionDelayMs; - - private final double reconnectionDelayGrowFactor; - - private final int maxRetries; + private volatile ReconnectOptions activeOptions; private final int maxEnqueuedMessages; @@ -81,22 +75,30 @@ public ReconnectingWebSocketListener( ReconnectingWebSocketListener.ReconnectOptions options, Supplier connectionSupplier, BooleanSupplier closedCheck) { - this.minReconnectionDelayMs = options.minReconnectionDelayMs; - this.maxReconnectionDelayMs = options.maxReconnectionDelayMs; - this.reconnectionDelayGrowFactor = options.reconnectionDelayGrowFactor; - this.maxRetries = options.maxRetries; + this.activeOptions = options; this.maxEnqueuedMessages = options.maxEnqueuedMessages; this.connectionSupplier = connectionSupplier; this.closedCheck = closedCheck; } + /** + * Replaces option-derived reconnect settings without rebuilding generated clients. + * + * @param options replacement options; {@code null} is a no-op + */ + public void applyOptionsOverride(ReconnectOptions options) { + if (options != null) { + this.activeOptions = options; + } + } + /** * Initiates a WebSocket connection with automatic reconnection enabled. * * Connection behavior: - * - Times out after 4000 milliseconds + * - Times out after {@code ReconnectOptions.connectionTimeoutMs} (default 4000ms) * - Thread-safe via atomic lock (returns immediately if connection in progress) - * - Retry count not incremented for initial connection attempt + * - {@code maxRetries} counts retries only; {@code maxRetries(0)} means connect once, do not retry * * Error handling: * - TimeoutException: Includes retry attempt context @@ -114,18 +116,20 @@ public void connect() { onWebSocketFailure(null, new IllegalStateException("root client has been closed"), null); return; } - if (retryCount.get() >= maxRetries) { + ReconnectOptions options = this.activeOptions; + if (retryCount.get() > options.maxRetries) { connectLock.set(false); return; } try { CompletableFuture connectionFuture = CompletableFuture.supplyAsync(connectionSupplier); try { - webSocket = connectionFuture.get(4000, MILLISECONDS); + webSocket = connectionFuture.get(options.connectionTimeoutMs, MILLISECONDS); } catch (TimeoutException e) { connectionFuture.cancel(true); TimeoutException timeoutError = - new TimeoutException("WebSocket connection timeout after " + 4000 + " milliseconds" + new TimeoutException("WebSocket connection timeout after " + options.connectionTimeoutMs + + " milliseconds" + (retryCount.get() > 0 ? " (retry attempt #" + retryCount.get() + ")" : " (initial connection attempt)")); @@ -415,10 +419,12 @@ protected boolean shouldReconnectAfterClose(WebSocket webSocket, int code, Strin */ private long getNextDelay() { if (retryCount.get() == 1) { - return minReconnectionDelayMs; + return activeOptions.minReconnectionDelayMs; } - long delay = (long) (minReconnectionDelayMs * Math.pow(reconnectionDelayGrowFactor, retryCount.get() - 1)); - return Math.min(delay, maxReconnectionDelayMs); + ReconnectOptions options = this.activeOptions; + long delay = (long) + (options.minReconnectionDelayMs * Math.pow(options.reconnectionDelayGrowFactor, retryCount.get() - 1)); + return Math.min(delay, options.maxReconnectionDelayMs); } /** @@ -504,12 +510,15 @@ public static final class ReconnectOptions { public final int maxEnqueuedMessages; + public final long connectionTimeoutMs; + private ReconnectOptions(Builder builder) { this.minReconnectionDelayMs = builder.minReconnectionDelayMs; this.maxReconnectionDelayMs = builder.maxReconnectionDelayMs; this.reconnectionDelayGrowFactor = builder.reconnectionDelayGrowFactor; this.maxRetries = builder.maxRetries; this.maxEnqueuedMessages = builder.maxEnqueuedMessages; + this.connectionTimeoutMs = builder.connectionTimeoutMs; } public static Builder builder() { @@ -527,12 +536,15 @@ public static final class Builder { private int maxEnqueuedMessages; + private long connectionTimeoutMs; + public Builder() { this.minReconnectionDelayMs = 1000; this.maxReconnectionDelayMs = 10000; this.reconnectionDelayGrowFactor = 1.3; this.maxRetries = 2147483647; this.maxEnqueuedMessages = 1000; + this.connectionTimeoutMs = 4000; } public Builder minReconnectionDelayMs(long minReconnectionDelayMs) { @@ -560,6 +572,14 @@ public Builder maxEnqueuedMessages(int maxEnqueuedMessages) { return this; } + /** + * Sets the per-attempt connection timeout in milliseconds. Defaults to {@code 4000}. + */ + public Builder connectionTimeoutMs(long connectionTimeoutMs) { + this.connectionTimeoutMs = connectionTimeoutMs; + return this; + } + /** * Builds the ReconnectOptions with validation. * @@ -592,6 +612,9 @@ public ReconnectOptions build() { if (maxEnqueuedMessages < 0) { throw new IllegalArgumentException("maxEnqueuedMessages must be non-negative"); } + if (connectionTimeoutMs <= 0) { + throw new IllegalArgumentException("connectionTimeoutMs must be positive"); + } return new ReconnectOptions(this); } } diff --git a/src/main/java/com/deepgram/core/ReconnectingWebSocketListener.java.bak b/src/main/java/com/deepgram/core/ReconnectingWebSocketListener.java.bak deleted file mode 100644 index b51aacc..0000000 --- a/src/main/java/com/deepgram/core/ReconnectingWebSocketListener.java.bak +++ /dev/null @@ -1,622 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.core; - -import static java.util.concurrent.TimeUnit.*; - -import java.util.ArrayList; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.BooleanSupplier; -import java.util.function.Consumer; -import java.util.function.Supplier; -import okhttp3.Response; -import okhttp3.WebSocket; -import okhttp3.WebSocketListener; -import okio.ByteString; - -/** - * WebSocketListener with automatic reconnection, exponential backoff, and message queuing. - * Provides production-ready resilience for WebSocket connections. - */ -public abstract class ReconnectingWebSocketListener extends WebSocketListener { - private volatile ReconnectOptions activeOptions; - - private final int maxEnqueuedMessages; - - private final AtomicInteger retryCount = new AtomicInteger(0); - - private final AtomicBoolean connectLock = new AtomicBoolean(false); - - private final AtomicBoolean shouldReconnect = new AtomicBoolean(true); - - protected volatile WebSocket webSocket; - - private volatile long connectionEstablishedTime = 0L; - - private final ConcurrentLinkedQueue messageQueue = new ConcurrentLinkedQueue<>(); - - private final ConcurrentLinkedQueue binaryMessageQueue = new ConcurrentLinkedQueue<>(); - - private final ScheduledExecutorService reconnectExecutor = Executors.newSingleThreadScheduledExecutor(); - - private final Supplier connectionSupplier; - - private final BooleanSupplier closedCheck; - - /** - * Creates a new reconnecting WebSocket listener. - * - * @param options Reconnection configuration options - * @param connectionSupplier Supplier that creates new WebSocket connections - */ - public ReconnectingWebSocketListener( - ReconnectingWebSocketListener.ReconnectOptions options, Supplier connectionSupplier) { - this(options, connectionSupplier, () -> false); - } - - /** - * Creates a new reconnecting WebSocket listener. - * - * @param options Reconnection configuration options - * @param connectionSupplier Supplier that creates new WebSocket connections - * @param closedCheck Returns true once the owning client has been closed; connect and - * reconnect attempts made after that point fail with an {@link IllegalStateException} - * instead of being retried - */ - public ReconnectingWebSocketListener( - ReconnectingWebSocketListener.ReconnectOptions options, - Supplier connectionSupplier, - BooleanSupplier closedCheck) { - this.activeOptions = options; - this.maxEnqueuedMessages = options.maxEnqueuedMessages; - this.connectionSupplier = connectionSupplier; - this.closedCheck = closedCheck; - } - - /** - * Replaces option-derived reconnect settings without rebuilding generated clients. - * - * @param options replacement options; {@code null} is a no-op - */ - public void applyOptionsOverride(ReconnectOptions options) { - if (options != null) { - this.activeOptions = options; - } - } - - /** - * Initiates a WebSocket connection with automatic reconnection enabled. - * - * Connection behavior: - * - Times out after {@code ReconnectOptions.connectionTimeoutMs} (default 4000ms) - * - Thread-safe via atomic lock (returns immediately if connection in progress) - * - {@code maxRetries} counts retries only; {@code maxRetries(0)} means connect once, do not retry - * - * Error handling: - * - TimeoutException: Includes retry attempt context - * - InterruptedException: Preserves thread interruption status - * - ExecutionException: Extracts actual cause and adds context - * - Owning client closed: reports an IllegalStateException once and stops reconnecting - */ - public void connect() { - if (!connectLock.compareAndSet(false, true)) { - return; - } - if (closedCheck.getAsBoolean()) { - shouldReconnect.set(false); - connectLock.set(false); - onWebSocketFailure(null, new IllegalStateException("root client has been closed"), null); - return; - } - ReconnectOptions options = this.activeOptions; - if (retryCount.get() > options.maxRetries) { - connectLock.set(false); - return; - } - try { - CompletableFuture connectionFuture = CompletableFuture.supplyAsync(connectionSupplier); - try { - webSocket = connectionFuture.get(options.connectionTimeoutMs, MILLISECONDS); - } catch (TimeoutException e) { - connectionFuture.cancel(true); - TimeoutException timeoutError = - new TimeoutException("WebSocket connection timeout after " + options.connectionTimeoutMs - + " milliseconds" - + (retryCount.get() > 0 - ? " (retry attempt #" + retryCount.get() + ")" - : " (initial connection attempt)")); - onWebSocketFailure(null, timeoutError, null); - if (shouldReconnect.get()) { - scheduleReconnect(); - } - } catch (InterruptedException e) { - connectionFuture.cancel(true); - Thread.currentThread().interrupt(); - InterruptedException interruptError = new InterruptedException("WebSocket connection interrupted" - + (retryCount.get() > 0 - ? " during retry attempt #" + retryCount.get() - : " during initial connection")); - interruptError.initCause(e); - onWebSocketFailure(null, interruptError, null); - } catch (ExecutionException e) { - Throwable cause = e.getCause() != null ? e.getCause() : e; - String context = retryCount.get() > 0 - ? "WebSocket connection failed during retry attempt #" + retryCount.get() - : "WebSocket connection failed during initial attempt"; - RuntimeException wrappedException = new RuntimeException( - context + ": " + cause.getClass().getSimpleName() + ": " + cause.getMessage()); - wrappedException.initCause(cause); - onWebSocketFailure(null, wrappedException, null); - if (shouldReconnect.get()) { - scheduleReconnect(); - } - } - } finally { - connectLock.set(false); - } - } - - /** - * Disconnects the WebSocket and disables automatic reconnection. - * - * This method: - * - Disables automatic reconnection - * - Clears queued messages to prevent stale data - * - Closes the WebSocket with standard close code 1000 - * - Properly shuts down the reconnect executor to prevent thread leaks - * - Waits up to 5 seconds for executor termination - */ - public void disconnect() { - shouldReconnect.set(false); - messageQueue.clear(); - binaryMessageQueue.clear(); - if (webSocket != null) { - webSocket.close(1000, "Client disconnecting"); - } - reconnectExecutor.shutdown(); - try { - if (!reconnectExecutor.awaitTermination(5, SECONDS)) { - reconnectExecutor.shutdownNow(); - } - } catch (InterruptedException e) { - reconnectExecutor.shutdownNow(); - Thread.currentThread().interrupt(); - } - } - - /** - * Sends a message or queues it if not connected. - * - * Thread-safe: Synchronized to prevent race conditions with flushMessageQueue(). - * - * Behavior: - * - If connected: Attempts direct send, queues if buffer full - * - If disconnected: Queues message up to maxEnqueuedMessages limit - * - If queue full: Message is dropped - * - * @param message The message to send - * @return true if sent immediately, false if queued or dropped - */ - public synchronized boolean send(String message) { - return send(message, null); - } - - /** - * Sends a message or queues it if not connected, exposing the accepting socket. - * - * Behaves like {@link #send(String)}, but additionally invokes {@code onSent} with the - * WebSocket that accepted the message. The callback is only invoked when the message was - * sent directly, never when it was queued or dropped. This lets callers associate a - * protocol-level message with the specific connection it was delivered on, e.g. to decide - * in {@link #shouldReconnectAfterClose(WebSocket, int, String)} whether a later close of that same - * connection was expected. - * - * @param message The message to send - * @param onSent Callback receiving the WebSocket that accepted the message, or null - * @return true if sent immediately, false if queued or dropped - */ - public synchronized boolean send(String message, Consumer onSent) { - WebSocket ws = webSocket; - if (ws != null) { - boolean sent = ws.send(message); - if (sent && onSent != null) { - onSent.accept(ws); - } - if (!sent && messageQueue.size() < maxEnqueuedMessages) { - messageQueue.offer(message); - return false; - } - return sent; - } else { - if (messageQueue.size() < maxEnqueuedMessages) { - messageQueue.offer(message); - return false; - } - return false; - } - } - - /** - * Sends binary data or queues it if not connected. - * - * Thread-safe: Synchronized to prevent race conditions with flushMessageQueue(). - * - * Behavior: - * - If connected: Attempts direct send, queues if buffer full - * - If disconnected: Queues data up to maxEnqueuedMessages limit - * - If queue full: Data is dropped - * - * @param data The binary data to send - * @return true if sent immediately, false if queued or dropped - */ - public synchronized boolean sendBinary(ByteString data) { - return sendBinary(data, null); - } - - /** - * Sends binary data or queues it if not connected, exposing the accepting socket. - * - * Behaves like {@link #sendBinary(ByteString)}, but additionally invokes {@code onSent} with - * the WebSocket that accepted the data. The callback is only invoked when the data was sent - * directly, never when it was queued or dropped. - * - * @param data The binary data to send - * @param onSent Callback receiving the WebSocket that accepted the data, or null - * @return true if sent immediately, false if queued or dropped - */ - public synchronized boolean sendBinary(ByteString data, Consumer onSent) { - WebSocket ws = webSocket; - if (ws != null) { - boolean sent = ws.send(data); - if (sent && onSent != null) { - onSent.accept(ws); - } - if (!sent && binaryMessageQueue.size() < maxEnqueuedMessages) { - binaryMessageQueue.offer(data); - return false; - } - return sent; - } else { - if (binaryMessageQueue.size() < maxEnqueuedMessages) { - binaryMessageQueue.offer(data); - return false; - } - return false; - } - } - - /** - * Gets the current WebSocket instance. - * Thread-safe method to access the WebSocket connection. - * @return the WebSocket or null if not connected - */ - public WebSocket getWebSocket() { - return webSocket; - } - - /** - * @hidden - */ - @Override - public void onOpen(WebSocket webSocket, Response response) { - this.webSocket = webSocket; - connectionEstablishedTime = System.currentTimeMillis(); - retryCount.set(0); - flushMessageQueue(); - onWebSocketOpen(webSocket, response); - } - - @Override - public void onMessage(WebSocket webSocket, String text) { - onWebSocketMessage(webSocket, text); - } - - @Override - public void onMessage(WebSocket webSocket, ByteString bytes) { - onWebSocketBinaryMessage(webSocket, bytes); - } - - /** - * @hidden - */ - @Override - public void onFailure(WebSocket webSocket, Throwable t, Response response) { - this.webSocket = null; - long uptime = 0L; - if (connectionEstablishedTime > 0) { - uptime = System.currentTimeMillis() - connectionEstablishedTime; - if (uptime >= 5000) { - retryCount.set(0); - } - } - connectionEstablishedTime = 0L; - Throwable enhancedError = t; - if (t != null) { - String errorContext = "WebSocket connection failed"; - if (uptime > 0) { - errorContext += " after " + (uptime / 1000) + " seconds"; - } - if (response != null) { - errorContext += " with HTTP " + response.code() + " " + response.message(); - } - enhancedError = - new RuntimeException(errorContext + ": " + t.getClass().getSimpleName() + ": " + t.getMessage()); - enhancedError.initCause(t); - } - onWebSocketFailure(webSocket, enhancedError, response); - if (shouldReconnect.get()) { - scheduleReconnect(); - } - } - - /** - * Acknowledges a peer-initiated close so OkHttp can complete the close handshake and - * invoke {@link #onClosed(WebSocket, int, String)}. - * - * Code 1005 is a local "no status received" sentinel reported when the peer sent an empty - * close frame. It is not a valid code to put on the wire, so it is acknowledged with - * the normal closure code 1000 instead. - * - * @hidden - */ - @Override - public void onClosing(WebSocket webSocket, int code, String reason) { - webSocket.close(code == 1005 ? 1000 : code, reason); - } - - /** - * @hidden - */ - @Override - public void onClosed(WebSocket webSocket, int code, String reason) { - this.webSocket = null; - if (connectionEstablishedTime > 0) { - long uptime = System.currentTimeMillis() - connectionEstablishedTime; - if (uptime >= 5000) { - retryCount.set(0); - } - } - connectionEstablishedTime = 0L; - onWebSocketClosed(webSocket, code, reason); - if (shouldReconnect.get() && shouldReconnectAfterClose(webSocket, code, reason)) { - scheduleReconnect(); - } - } - - /** - * Decides whether a completed close handshake should trigger a reconnect. - * - * Only consulted when reconnection has not been disabled via {@link #disconnect()}. - * The default treats normal closure (1000) as terminal and reconnects on any - * other code. Subclasses can override this when protocol context establishes that a - * particular close is terminal, for example a no-status close following a message that - * ends the stream. - * - * @param webSocket The WebSocket that was closed - * @param code The close status code reported by OkHttp - * @param reason The close reason sent by the peer, or an empty string - * @return true to schedule a reconnect, false to stay disconnected - */ - protected boolean shouldReconnectAfterClose(WebSocket webSocket, int code, String reason) { - return code != 1000; - } - - /** - * Calculates the next reconnection delay using exponential backoff. - * - * Uses 0-based retry count where: - * - 0 = initial connection (not used by this method) - * - 1 = first retry (returns minReconnectionDelayMs) - * - 2+ = exponential backoff up to maxReconnectionDelayMs - */ - private long getNextDelay() { - if (retryCount.get() == 1) { - return activeOptions.minReconnectionDelayMs; - } - ReconnectOptions options = this.activeOptions; - long delay = (long) - (options.minReconnectionDelayMs * Math.pow(options.reconnectionDelayGrowFactor, retryCount.get() - 1)); - return Math.min(delay, options.maxReconnectionDelayMs); - } - - /** - * Schedules a reconnection attempt with appropriate delay. - * Increments retry count and uses exponential backoff. - * Does nothing once the owning client has been closed. - */ - private void scheduleReconnect() { - if (closedCheck.getAsBoolean()) { - shouldReconnect.set(false); - return; - } - retryCount.incrementAndGet(); - long delay = getNextDelay(); - reconnectExecutor.schedule(this::connect, delay, MILLISECONDS); - } - - /** - * Sends all queued messages after reconnection. - * - * Thread-safe: Synchronized to prevent race conditions with send() method. - * - * Algorithm: - * 1. Drains queue into temporary list to avoid holding lock during sends - * 2. Attempts to send each message in order - * 3. If any send fails, re-queues that message and all subsequent messages - * 4. Preserves message ordering during re-queueing - * 5. Repeats for binary message queue - */ - private synchronized void flushMessageQueue() { - WebSocket ws = webSocket; - if (ws != null) { - ArrayList tempQueue = new ArrayList<>(); - String message; - while ((message = messageQueue.poll()) != null) { - tempQueue.add(message); - } - for (int i = 0; i < tempQueue.size(); i++) { - if (!ws.send(tempQueue.get(i))) { - for (int j = i; j < tempQueue.size(); j++) { - messageQueue.offer(tempQueue.get(j)); - } - break; - } - } - ArrayList tempBinaryQueue = new ArrayList<>(); - ByteString binaryMsg; - while ((binaryMsg = binaryMessageQueue.poll()) != null) { - tempBinaryQueue.add(binaryMsg); - } - for (int i = 0; i < tempBinaryQueue.size(); i++) { - if (!ws.send(tempBinaryQueue.get(i))) { - for (int j = i; j < tempBinaryQueue.size(); j++) { - binaryMessageQueue.offer(tempBinaryQueue.get(j)); - } - break; - } - } - } - } - - protected abstract void onWebSocketOpen(WebSocket webSocket, Response response); - - protected abstract void onWebSocketMessage(WebSocket webSocket, String text); - - protected abstract void onWebSocketBinaryMessage(WebSocket webSocket, ByteString bytes); - - protected abstract void onWebSocketFailure(WebSocket webSocket, Throwable t, Response response); - - protected abstract void onWebSocketClosed(WebSocket webSocket, int code, String reason); - - /** - * Configuration options for automatic reconnection. - */ - public static final class ReconnectOptions { - public final long minReconnectionDelayMs; - - public final long maxReconnectionDelayMs; - - public final double reconnectionDelayGrowFactor; - - public final int maxRetries; - - public final int maxEnqueuedMessages; - - public final long connectionTimeoutMs; - - private ReconnectOptions(Builder builder) { - this.minReconnectionDelayMs = builder.minReconnectionDelayMs; - this.maxReconnectionDelayMs = builder.maxReconnectionDelayMs; - this.reconnectionDelayGrowFactor = builder.reconnectionDelayGrowFactor; - this.maxRetries = builder.maxRetries; - this.maxEnqueuedMessages = builder.maxEnqueuedMessages; - this.connectionTimeoutMs = builder.connectionTimeoutMs; - } - - public static Builder builder() { - return new Builder(); - } - - public static final class Builder { - private long minReconnectionDelayMs; - - private long maxReconnectionDelayMs; - - private double reconnectionDelayGrowFactor; - - private int maxRetries; - - private int maxEnqueuedMessages; - - private long connectionTimeoutMs; - - public Builder() { - this.minReconnectionDelayMs = 1000; - this.maxReconnectionDelayMs = 10000; - this.reconnectionDelayGrowFactor = 1.3; - this.maxRetries = 2147483647; - this.maxEnqueuedMessages = 1000; - this.connectionTimeoutMs = 4000; - } - - public Builder minReconnectionDelayMs(long minReconnectionDelayMs) { - this.minReconnectionDelayMs = minReconnectionDelayMs; - return this; - } - - public Builder maxReconnectionDelayMs(long maxReconnectionDelayMs) { - this.maxReconnectionDelayMs = maxReconnectionDelayMs; - return this; - } - - public Builder reconnectionDelayGrowFactor(double reconnectionDelayGrowFactor) { - this.reconnectionDelayGrowFactor = reconnectionDelayGrowFactor; - return this; - } - - public Builder maxRetries(int maxRetries) { - this.maxRetries = maxRetries; - return this; - } - - public Builder maxEnqueuedMessages(int maxEnqueuedMessages) { - this.maxEnqueuedMessages = maxEnqueuedMessages; - return this; - } - - /** - * Sets the per-attempt connection timeout in milliseconds. Defaults to {@code 4000}. - */ - public Builder connectionTimeoutMs(long connectionTimeoutMs) { - this.connectionTimeoutMs = connectionTimeoutMs; - return this; - } - - /** - * Builds the ReconnectOptions with validation. - * - * Validates that: - * - All delay values are positive - * - minReconnectionDelayMs <= maxReconnectionDelayMs - * - reconnectionDelayGrowFactor >= 1.0 - * - maxRetries and maxEnqueuedMessages are non-negative - * - * @return The validated ReconnectOptions instance - * @throws IllegalArgumentException if configuration is invalid - */ - public ReconnectOptions build() { - if (minReconnectionDelayMs <= 0) { - throw new IllegalArgumentException("minReconnectionDelayMs must be positive"); - } - if (maxReconnectionDelayMs <= 0) { - throw new IllegalArgumentException("maxReconnectionDelayMs must be positive"); - } - if (minReconnectionDelayMs > maxReconnectionDelayMs) { - throw new IllegalArgumentException("minReconnectionDelayMs (" + minReconnectionDelayMs - + ") must not exceed maxReconnectionDelayMs (" + maxReconnectionDelayMs + ")"); - } - if (reconnectionDelayGrowFactor < 1.0) { - throw new IllegalArgumentException("reconnectionDelayGrowFactor must be >= 1.0"); - } - if (maxRetries < 0) { - throw new IllegalArgumentException("maxRetries must be non-negative"); - } - if (maxEnqueuedMessages < 0) { - throw new IllegalArgumentException("maxEnqueuedMessages must be non-negative"); - } - if (connectionTimeoutMs <= 0) { - throw new IllegalArgumentException("connectionTimeoutMs must be positive"); - } - return new ReconnectOptions(this); - } - } - } -} diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1AgentAudioDone.java b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1AgentAudioDone.java index 71825ed..5962f4b 100644 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1AgentAudioDone.java +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1AgentAudioDone.java @@ -36,6 +36,11 @@ public boolean equals(Object other) { return other instanceof AgentV1AgentAudioDone; } + @java.lang.Override + public int hashCode() { + return getClass().hashCode(); + } + @JsonAnyGetter public Map getAdditionalProperties() { return this.additionalProperties; diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1AgentAudioDone.java.bak b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1AgentAudioDone.java.bak deleted file mode 100644 index 5962f4b..0000000 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1AgentAudioDone.java.bak +++ /dev/null @@ -1,83 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.resources.agent.v1.types; - -import com.deepgram.core.ObjectMappers; -import com.fasterxml.jackson.annotation.JsonAnyGetter; -import com.fasterxml.jackson.annotation.JsonAnySetter; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import java.util.HashMap; -import java.util.Map; - -@JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = AgentV1AgentAudioDone.Builder.class) -public final class AgentV1AgentAudioDone { - private final Map additionalProperties; - - private AgentV1AgentAudioDone(Map additionalProperties) { - this.additionalProperties = additionalProperties; - } - - /** - * @return Message type identifier indicating the agent has finished sending audio - */ - @JsonProperty("type") - public String getType() { - return "AgentAudioDone"; - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof AgentV1AgentAudioDone; - } - - @java.lang.Override - public int hashCode() { - return getClass().hashCode(); - } - - @JsonAnyGetter - public Map getAdditionalProperties() { - return this.additionalProperties; - } - - @java.lang.Override - public String toString() { - return ObjectMappers.stringify(this); - } - - public static Builder builder() { - return new Builder(); - } - - @JsonIgnoreProperties(ignoreUnknown = true) - public static final class Builder { - @JsonAnySetter - private Map additionalProperties = new HashMap<>(); - - private Builder() {} - - public Builder from(AgentV1AgentAudioDone other) { - return this; - } - - public AgentV1AgentAudioDone build() { - return new AgentV1AgentAudioDone(additionalProperties); - } - - public Builder additionalProperty(String key, Object value) { - this.additionalProperties.put(key, value); - return this; - } - - public Builder additionalProperties(Map additionalProperties) { - this.additionalProperties.putAll(additionalProperties); - return this; - } - } -} diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ForceEndTurn.java b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ForceEndTurn.java index 1672d2d..9bd5f76 100644 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ForceEndTurn.java +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ForceEndTurn.java @@ -36,6 +36,11 @@ public boolean equals(Object other) { return other instanceof AgentV1ForceEndTurn; } + @java.lang.Override + public int hashCode() { + return getClass().hashCode(); + } + @JsonAnyGetter public Map getAdditionalProperties() { return this.additionalProperties; diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ForceEndTurn.java.bak b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ForceEndTurn.java.bak deleted file mode 100644 index 9bd5f76..0000000 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ForceEndTurn.java.bak +++ /dev/null @@ -1,83 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.resources.agent.v1.types; - -import com.deepgram.core.ObjectMappers; -import com.fasterxml.jackson.annotation.JsonAnyGetter; -import com.fasterxml.jackson.annotation.JsonAnySetter; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import java.util.HashMap; -import java.util.Map; - -@JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = AgentV1ForceEndTurn.Builder.class) -public final class AgentV1ForceEndTurn { - private final Map additionalProperties; - - private AgentV1ForceEndTurn(Map additionalProperties) { - this.additionalProperties = additionalProperties; - } - - /** - * @return Message type identifier for forcing the end of the current turn - */ - @JsonProperty("type") - public String getType() { - return "ForceEndTurn"; - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof AgentV1ForceEndTurn; - } - - @java.lang.Override - public int hashCode() { - return getClass().hashCode(); - } - - @JsonAnyGetter - public Map getAdditionalProperties() { - return this.additionalProperties; - } - - @java.lang.Override - public String toString() { - return ObjectMappers.stringify(this); - } - - public static Builder builder() { - return new Builder(); - } - - @JsonIgnoreProperties(ignoreUnknown = true) - public static final class Builder { - @JsonAnySetter - private Map additionalProperties = new HashMap<>(); - - private Builder() {} - - public Builder from(AgentV1ForceEndTurn other) { - return this; - } - - public AgentV1ForceEndTurn build() { - return new AgentV1ForceEndTurn(additionalProperties); - } - - public Builder additionalProperty(String key, Object value) { - this.additionalProperties.put(key, value); - return this; - } - - public Builder additionalProperties(Map additionalProperties) { - this.additionalProperties.putAll(additionalProperties); - return this; - } - } -} diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1KeepAlive.java b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1KeepAlive.java index 7842266..f82f59e 100644 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1KeepAlive.java +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1KeepAlive.java @@ -36,6 +36,11 @@ public boolean equals(Object other) { return other instanceof AgentV1KeepAlive; } + @java.lang.Override + public int hashCode() { + return getClass().hashCode(); + } + @JsonAnyGetter public Map getAdditionalProperties() { return this.additionalProperties; diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1KeepAlive.java.bak b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1KeepAlive.java.bak deleted file mode 100644 index f82f59e..0000000 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1KeepAlive.java.bak +++ /dev/null @@ -1,83 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.resources.agent.v1.types; - -import com.deepgram.core.ObjectMappers; -import com.fasterxml.jackson.annotation.JsonAnyGetter; -import com.fasterxml.jackson.annotation.JsonAnySetter; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import java.util.HashMap; -import java.util.Map; - -@JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = AgentV1KeepAlive.Builder.class) -public final class AgentV1KeepAlive { - private final Map additionalProperties; - - private AgentV1KeepAlive(Map additionalProperties) { - this.additionalProperties = additionalProperties; - } - - /** - * @return Message type identifier - */ - @JsonProperty("type") - public String getType() { - return "KeepAlive"; - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof AgentV1KeepAlive; - } - - @java.lang.Override - public int hashCode() { - return getClass().hashCode(); - } - - @JsonAnyGetter - public Map getAdditionalProperties() { - return this.additionalProperties; - } - - @java.lang.Override - public String toString() { - return ObjectMappers.stringify(this); - } - - public static Builder builder() { - return new Builder(); - } - - @JsonIgnoreProperties(ignoreUnknown = true) - public static final class Builder { - @JsonAnySetter - private Map additionalProperties = new HashMap<>(); - - private Builder() {} - - public Builder from(AgentV1KeepAlive other) { - return this; - } - - public AgentV1KeepAlive build() { - return new AgentV1KeepAlive(additionalProperties); - } - - public Builder additionalProperty(String key, Object value) { - this.additionalProperties.put(key, value); - return this; - } - - public Builder additionalProperties(Map additionalProperties) { - this.additionalProperties.putAll(additionalProperties); - return this; - } - } -} diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ListenUpdated.java b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ListenUpdated.java index 65878c9..43b8628 100644 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ListenUpdated.java +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ListenUpdated.java @@ -36,6 +36,11 @@ public boolean equals(Object other) { return other instanceof AgentV1ListenUpdated; } + @java.lang.Override + public int hashCode() { + return getClass().hashCode(); + } + @JsonAnyGetter public Map getAdditionalProperties() { return this.additionalProperties; diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ListenUpdated.java.bak b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ListenUpdated.java.bak deleted file mode 100644 index 43b8628..0000000 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ListenUpdated.java.bak +++ /dev/null @@ -1,83 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.resources.agent.v1.types; - -import com.deepgram.core.ObjectMappers; -import com.fasterxml.jackson.annotation.JsonAnyGetter; -import com.fasterxml.jackson.annotation.JsonAnySetter; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import java.util.HashMap; -import java.util.Map; - -@JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = AgentV1ListenUpdated.Builder.class) -public final class AgentV1ListenUpdated { - private final Map additionalProperties; - - private AgentV1ListenUpdated(Map additionalProperties) { - this.additionalProperties = additionalProperties; - } - - /** - * @return Message type identifier for listen update confirmation - */ - @JsonProperty("type") - public String getType() { - return "ListenUpdated"; - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof AgentV1ListenUpdated; - } - - @java.lang.Override - public int hashCode() { - return getClass().hashCode(); - } - - @JsonAnyGetter - public Map getAdditionalProperties() { - return this.additionalProperties; - } - - @java.lang.Override - public String toString() { - return ObjectMappers.stringify(this); - } - - public static Builder builder() { - return new Builder(); - } - - @JsonIgnoreProperties(ignoreUnknown = true) - public static final class Builder { - @JsonAnySetter - private Map additionalProperties = new HashMap<>(); - - private Builder() {} - - public Builder from(AgentV1ListenUpdated other) { - return this; - } - - public AgentV1ListenUpdated build() { - return new AgentV1ListenUpdated(additionalProperties); - } - - public Builder additionalProperty(String key, Object value) { - this.additionalProperties.put(key, value); - return this; - } - - public Builder additionalProperties(Map additionalProperties) { - this.additionalProperties.putAll(additionalProperties); - return this; - } - } -} diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1PromptUpdated.java b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1PromptUpdated.java index 68d71cc..e6efced 100644 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1PromptUpdated.java +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1PromptUpdated.java @@ -36,6 +36,11 @@ public boolean equals(Object other) { return other instanceof AgentV1PromptUpdated; } + @java.lang.Override + public int hashCode() { + return getClass().hashCode(); + } + @JsonAnyGetter public Map getAdditionalProperties() { return this.additionalProperties; diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1PromptUpdated.java.bak b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1PromptUpdated.java.bak deleted file mode 100644 index e6efced..0000000 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1PromptUpdated.java.bak +++ /dev/null @@ -1,83 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.resources.agent.v1.types; - -import com.deepgram.core.ObjectMappers; -import com.fasterxml.jackson.annotation.JsonAnyGetter; -import com.fasterxml.jackson.annotation.JsonAnySetter; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import java.util.HashMap; -import java.util.Map; - -@JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = AgentV1PromptUpdated.Builder.class) -public final class AgentV1PromptUpdated { - private final Map additionalProperties; - - private AgentV1PromptUpdated(Map additionalProperties) { - this.additionalProperties = additionalProperties; - } - - /** - * @return Message type identifier for prompt update confirmation - */ - @JsonProperty("type") - public String getType() { - return "PromptUpdated"; - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof AgentV1PromptUpdated; - } - - @java.lang.Override - public int hashCode() { - return getClass().hashCode(); - } - - @JsonAnyGetter - public Map getAdditionalProperties() { - return this.additionalProperties; - } - - @java.lang.Override - public String toString() { - return ObjectMappers.stringify(this); - } - - public static Builder builder() { - return new Builder(); - } - - @JsonIgnoreProperties(ignoreUnknown = true) - public static final class Builder { - @JsonAnySetter - private Map additionalProperties = new HashMap<>(); - - private Builder() {} - - public Builder from(AgentV1PromptUpdated other) { - return this; - } - - public AgentV1PromptUpdated build() { - return new AgentV1PromptUpdated(additionalProperties); - } - - public Builder additionalProperty(String key, Object value) { - this.additionalProperties.put(key, value); - return this; - } - - public Builder additionalProperties(Map additionalProperties) { - this.additionalProperties.putAll(additionalProperties); - return this; - } - } -} diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentContextListenProvider.java b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentContextListenProvider.java index eea1585..393f1f9 100644 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentContextListenProvider.java +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentContextListenProvider.java @@ -99,7 +99,7 @@ public interface Visitor { T _visitUnknown(Object unknownType); } - @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "version", visible = true, defaultImpl = _UnknownValue.class) + @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "version", visible = true, defaultImpl = V2Value.class) @JsonSubTypes({@JsonSubTypes.Type(V1Value.class), @JsonSubTypes.Type(V2Value.class)}) @JsonIgnoreProperties(ignoreUnknown = true) private interface Value { diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentContextListenProvider.java.bak b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentContextListenProvider.java.bak deleted file mode 100644 index 393f1f9..0000000 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentContextListenProvider.java.bak +++ /dev/null @@ -1,224 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.resources.agent.v1.types; - -import com.deepgram.types.DeepgramListenProviderV1; -import com.deepgram.types.DeepgramListenProviderV2; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonSubTypes; -import com.fasterxml.jackson.annotation.JsonTypeInfo; -import com.fasterxml.jackson.annotation.JsonTypeName; -import com.fasterxml.jackson.annotation.JsonUnwrapped; -import com.fasterxml.jackson.annotation.JsonValue; -import java.util.Objects; -import java.util.Optional; - -public final class AgentV1SettingsAgentContextListenProvider { - private final Value value; - - @JsonCreator(mode = JsonCreator.Mode.DELEGATING) - private AgentV1SettingsAgentContextListenProvider(Value value) { - this.value = value; - } - - public T visit(Visitor visitor) { - return value.visit(visitor); - } - - public static AgentV1SettingsAgentContextListenProvider v1(DeepgramListenProviderV1 value) { - return new AgentV1SettingsAgentContextListenProvider(new V1Value(value)); - } - - public static AgentV1SettingsAgentContextListenProvider v2(DeepgramListenProviderV2 value) { - return new AgentV1SettingsAgentContextListenProvider(new V2Value(value)); - } - - public boolean isV1() { - return value instanceof V1Value; - } - - public boolean isV2() { - return value instanceof V2Value; - } - - public boolean _isUnknown() { - return value instanceof _UnknownValue; - } - - public Optional getV1() { - if (isV1()) { - return Optional.of(((V1Value) value).value); - } - return Optional.empty(); - } - - public Optional getV2() { - if (isV2()) { - return Optional.of(((V2Value) value).value); - } - return Optional.empty(); - } - - public Optional _getUnknown() { - if (_isUnknown()) { - return Optional.of(((_UnknownValue) value).value); - } - return Optional.empty(); - } - - @Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof AgentV1SettingsAgentContextListenProvider - && value.equals(((AgentV1SettingsAgentContextListenProvider) other).value); - } - - @Override - public int hashCode() { - return Objects.hash(value); - } - - @Override - public String toString() { - return value.toString(); - } - - @JsonValue - private Value getValue() { - return this.value; - } - - public interface Visitor { - T visitV1(DeepgramListenProviderV1 v1); - - T visitV2(DeepgramListenProviderV2 v2); - - T _visitUnknown(Object unknownType); - } - - @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "version", visible = true, defaultImpl = V2Value.class) - @JsonSubTypes({@JsonSubTypes.Type(V1Value.class), @JsonSubTypes.Type(V2Value.class)}) - @JsonIgnoreProperties(ignoreUnknown = true) - private interface Value { - T visit(Visitor visitor); - } - - @JsonTypeName("v1") - @JsonIgnoreProperties("version") - private static final class V1Value implements Value { - @JsonUnwrapped - @JsonIgnoreProperties(value = "version", allowSetters = true) - private DeepgramListenProviderV1 value; - - @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) - private V1Value() {} - - private V1Value(DeepgramListenProviderV1 value) { - this.value = value; - } - - @java.lang.Override - public T visit(Visitor visitor) { - return visitor.visitV1(value); - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof V1Value && equalTo((V1Value) other); - } - - private boolean equalTo(V1Value other) { - return value.equals(other.value); - } - - @java.lang.Override - public int hashCode() { - return Objects.hash(this.value); - } - - @java.lang.Override - public String toString() { - return "AgentV1SettingsAgentContextListenProvider{" + "value: " + value + "}"; - } - } - - @JsonTypeName("v2") - @JsonIgnoreProperties("version") - private static final class V2Value implements Value { - @JsonUnwrapped - @JsonIgnoreProperties(value = "version", allowSetters = true) - private DeepgramListenProviderV2 value; - - @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) - private V2Value() {} - - private V2Value(DeepgramListenProviderV2 value) { - this.value = value; - } - - @java.lang.Override - public T visit(Visitor visitor) { - return visitor.visitV2(value); - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof V2Value && equalTo((V2Value) other); - } - - private boolean equalTo(V2Value other) { - return value.equals(other.value); - } - - @java.lang.Override - public int hashCode() { - return Objects.hash(this.value); - } - - @java.lang.Override - public String toString() { - return "AgentV1SettingsAgentContextListenProvider{" + "value: " + value + "}"; - } - } - - @JsonIgnoreProperties("version") - private static final class _UnknownValue implements Value { - private String type; - - @JsonValue - private Object value; - - @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) - private _UnknownValue(@JsonProperty("value") Object value) {} - - @java.lang.Override - public T visit(Visitor visitor) { - return visitor._visitUnknown(value); - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof _UnknownValue && equalTo((_UnknownValue) other); - } - - private boolean equalTo(_UnknownValue other) { - return type.equals(other.type) && value.equals(other.value); - } - - @java.lang.Override - public int hashCode() { - return Objects.hash(this.type, this.value); - } - - @java.lang.Override - public String toString() { - return "AgentV1SettingsAgentContextListenProvider{" + "type: " + type + ", value: " + value + "}"; - } - } -} diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentListenProvider.java b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentListenProvider.java index 4309ec0..345ba2f 100644 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentListenProvider.java +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentListenProvider.java @@ -99,7 +99,7 @@ public interface Visitor { T _visitUnknown(Object unknownType); } - @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "version", visible = true, defaultImpl = _UnknownValue.class) + @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "version", visible = true, defaultImpl = V2Value.class) @JsonSubTypes({@JsonSubTypes.Type(V1Value.class), @JsonSubTypes.Type(V2Value.class)}) @JsonIgnoreProperties(ignoreUnknown = true) private interface Value { diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentListenProvider.java.bak b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentListenProvider.java.bak deleted file mode 100644 index 345ba2f..0000000 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentListenProvider.java.bak +++ /dev/null @@ -1,224 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.resources.agent.v1.types; - -import com.deepgram.types.DeepgramListenProviderV1; -import com.deepgram.types.DeepgramListenProviderV2; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonSubTypes; -import com.fasterxml.jackson.annotation.JsonTypeInfo; -import com.fasterxml.jackson.annotation.JsonTypeName; -import com.fasterxml.jackson.annotation.JsonUnwrapped; -import com.fasterxml.jackson.annotation.JsonValue; -import java.util.Objects; -import java.util.Optional; - -public final class AgentV1SettingsAgentListenProvider { - private final Value value; - - @JsonCreator(mode = JsonCreator.Mode.DELEGATING) - private AgentV1SettingsAgentListenProvider(Value value) { - this.value = value; - } - - public T visit(Visitor visitor) { - return value.visit(visitor); - } - - public static AgentV1SettingsAgentListenProvider v1(DeepgramListenProviderV1 value) { - return new AgentV1SettingsAgentListenProvider(new V1Value(value)); - } - - public static AgentV1SettingsAgentListenProvider v2(DeepgramListenProviderV2 value) { - return new AgentV1SettingsAgentListenProvider(new V2Value(value)); - } - - public boolean isV1() { - return value instanceof V1Value; - } - - public boolean isV2() { - return value instanceof V2Value; - } - - public boolean _isUnknown() { - return value instanceof _UnknownValue; - } - - public Optional getV1() { - if (isV1()) { - return Optional.of(((V1Value) value).value); - } - return Optional.empty(); - } - - public Optional getV2() { - if (isV2()) { - return Optional.of(((V2Value) value).value); - } - return Optional.empty(); - } - - public Optional _getUnknown() { - if (_isUnknown()) { - return Optional.of(((_UnknownValue) value).value); - } - return Optional.empty(); - } - - @Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof AgentV1SettingsAgentListenProvider - && value.equals(((AgentV1SettingsAgentListenProvider) other).value); - } - - @Override - public int hashCode() { - return Objects.hash(value); - } - - @Override - public String toString() { - return value.toString(); - } - - @JsonValue - private Value getValue() { - return this.value; - } - - public interface Visitor { - T visitV1(DeepgramListenProviderV1 v1); - - T visitV2(DeepgramListenProviderV2 v2); - - T _visitUnknown(Object unknownType); - } - - @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "version", visible = true, defaultImpl = V2Value.class) - @JsonSubTypes({@JsonSubTypes.Type(V1Value.class), @JsonSubTypes.Type(V2Value.class)}) - @JsonIgnoreProperties(ignoreUnknown = true) - private interface Value { - T visit(Visitor visitor); - } - - @JsonTypeName("v1") - @JsonIgnoreProperties("version") - private static final class V1Value implements Value { - @JsonUnwrapped - @JsonIgnoreProperties(value = "version", allowSetters = true) - private DeepgramListenProviderV1 value; - - @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) - private V1Value() {} - - private V1Value(DeepgramListenProviderV1 value) { - this.value = value; - } - - @java.lang.Override - public T visit(Visitor visitor) { - return visitor.visitV1(value); - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof V1Value && equalTo((V1Value) other); - } - - private boolean equalTo(V1Value other) { - return value.equals(other.value); - } - - @java.lang.Override - public int hashCode() { - return Objects.hash(this.value); - } - - @java.lang.Override - public String toString() { - return "AgentV1SettingsAgentListenProvider{" + "value: " + value + "}"; - } - } - - @JsonTypeName("v2") - @JsonIgnoreProperties("version") - private static final class V2Value implements Value { - @JsonUnwrapped - @JsonIgnoreProperties(value = "version", allowSetters = true) - private DeepgramListenProviderV2 value; - - @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) - private V2Value() {} - - private V2Value(DeepgramListenProviderV2 value) { - this.value = value; - } - - @java.lang.Override - public T visit(Visitor visitor) { - return visitor.visitV2(value); - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof V2Value && equalTo((V2Value) other); - } - - private boolean equalTo(V2Value other) { - return value.equals(other.value); - } - - @java.lang.Override - public int hashCode() { - return Objects.hash(this.value); - } - - @java.lang.Override - public String toString() { - return "AgentV1SettingsAgentListenProvider{" + "value: " + value + "}"; - } - } - - @JsonIgnoreProperties("version") - private static final class _UnknownValue implements Value { - private String type; - - @JsonValue - private Object value; - - @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) - private _UnknownValue(@JsonProperty("value") Object value) {} - - @java.lang.Override - public T visit(Visitor visitor) { - return visitor._visitUnknown(value); - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof _UnknownValue && equalTo((_UnknownValue) other); - } - - private boolean equalTo(_UnknownValue other) { - return type.equals(other.type) && value.equals(other.value); - } - - @java.lang.Override - public int hashCode() { - return Objects.hash(this.type, this.value); - } - - @java.lang.Override - public String toString() { - return "AgentV1SettingsAgentListenProvider{" + "type: " + type + ", value: " + value + "}"; - } - } -} diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsApplied.java b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsApplied.java index 0d60b72..ad1fdb2 100644 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsApplied.java +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsApplied.java @@ -36,6 +36,11 @@ public boolean equals(Object other) { return other instanceof AgentV1SettingsApplied; } + @java.lang.Override + public int hashCode() { + return getClass().hashCode(); + } + @JsonAnyGetter public Map getAdditionalProperties() { return this.additionalProperties; diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsApplied.java.bak b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsApplied.java.bak deleted file mode 100644 index ad1fdb2..0000000 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsApplied.java.bak +++ /dev/null @@ -1,83 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.resources.agent.v1.types; - -import com.deepgram.core.ObjectMappers; -import com.fasterxml.jackson.annotation.JsonAnyGetter; -import com.fasterxml.jackson.annotation.JsonAnySetter; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import java.util.HashMap; -import java.util.Map; - -@JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = AgentV1SettingsApplied.Builder.class) -public final class AgentV1SettingsApplied { - private final Map additionalProperties; - - private AgentV1SettingsApplied(Map additionalProperties) { - this.additionalProperties = additionalProperties; - } - - /** - * @return Message type identifier for settings applied confirmation - */ - @JsonProperty("type") - public String getType() { - return "SettingsApplied"; - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof AgentV1SettingsApplied; - } - - @java.lang.Override - public int hashCode() { - return getClass().hashCode(); - } - - @JsonAnyGetter - public Map getAdditionalProperties() { - return this.additionalProperties; - } - - @java.lang.Override - public String toString() { - return ObjectMappers.stringify(this); - } - - public static Builder builder() { - return new Builder(); - } - - @JsonIgnoreProperties(ignoreUnknown = true) - public static final class Builder { - @JsonAnySetter - private Map additionalProperties = new HashMap<>(); - - private Builder() {} - - public Builder from(AgentV1SettingsApplied other) { - return this; - } - - public AgentV1SettingsApplied build() { - return new AgentV1SettingsApplied(additionalProperties); - } - - public Builder additionalProperty(String key, Object value) { - this.additionalProperties.put(key, value); - return this; - } - - public Builder additionalProperties(Map additionalProperties) { - this.additionalProperties.putAll(additionalProperties); - return this; - } - } -} diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SpeakUpdated.java b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SpeakUpdated.java index 747aa9d..8b134b5 100644 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SpeakUpdated.java +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SpeakUpdated.java @@ -36,6 +36,11 @@ public boolean equals(Object other) { return other instanceof AgentV1SpeakUpdated; } + @java.lang.Override + public int hashCode() { + return getClass().hashCode(); + } + @JsonAnyGetter public Map getAdditionalProperties() { return this.additionalProperties; diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SpeakUpdated.java.bak b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SpeakUpdated.java.bak deleted file mode 100644 index 8b134b5..0000000 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SpeakUpdated.java.bak +++ /dev/null @@ -1,83 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.resources.agent.v1.types; - -import com.deepgram.core.ObjectMappers; -import com.fasterxml.jackson.annotation.JsonAnyGetter; -import com.fasterxml.jackson.annotation.JsonAnySetter; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import java.util.HashMap; -import java.util.Map; - -@JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = AgentV1SpeakUpdated.Builder.class) -public final class AgentV1SpeakUpdated { - private final Map additionalProperties; - - private AgentV1SpeakUpdated(Map additionalProperties) { - this.additionalProperties = additionalProperties; - } - - /** - * @return Message type identifier for speak update confirmation - */ - @JsonProperty("type") - public String getType() { - return "SpeakUpdated"; - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof AgentV1SpeakUpdated; - } - - @java.lang.Override - public int hashCode() { - return getClass().hashCode(); - } - - @JsonAnyGetter - public Map getAdditionalProperties() { - return this.additionalProperties; - } - - @java.lang.Override - public String toString() { - return ObjectMappers.stringify(this); - } - - public static Builder builder() { - return new Builder(); - } - - @JsonIgnoreProperties(ignoreUnknown = true) - public static final class Builder { - @JsonAnySetter - private Map additionalProperties = new HashMap<>(); - - private Builder() {} - - public Builder from(AgentV1SpeakUpdated other) { - return this; - } - - public AgentV1SpeakUpdated build() { - return new AgentV1SpeakUpdated(additionalProperties); - } - - public Builder additionalProperty(String key, Object value) { - this.additionalProperties.put(key, value); - return this; - } - - public Builder additionalProperties(Map additionalProperties) { - this.additionalProperties.putAll(additionalProperties); - return this; - } - } -} diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ThinkUpdated.java b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ThinkUpdated.java index 5668a71..2d67cad 100644 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ThinkUpdated.java +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ThinkUpdated.java @@ -36,6 +36,11 @@ public boolean equals(Object other) { return other instanceof AgentV1ThinkUpdated; } + @java.lang.Override + public int hashCode() { + return getClass().hashCode(); + } + @JsonAnyGetter public Map getAdditionalProperties() { return this.additionalProperties; diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ThinkUpdated.java.bak b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ThinkUpdated.java.bak deleted file mode 100644 index 2d67cad..0000000 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ThinkUpdated.java.bak +++ /dev/null @@ -1,83 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.resources.agent.v1.types; - -import com.deepgram.core.ObjectMappers; -import com.fasterxml.jackson.annotation.JsonAnyGetter; -import com.fasterxml.jackson.annotation.JsonAnySetter; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import java.util.HashMap; -import java.util.Map; - -@JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = AgentV1ThinkUpdated.Builder.class) -public final class AgentV1ThinkUpdated { - private final Map additionalProperties; - - private AgentV1ThinkUpdated(Map additionalProperties) { - this.additionalProperties = additionalProperties; - } - - /** - * @return Message type identifier for think update confirmation - */ - @JsonProperty("type") - public String getType() { - return "ThinkUpdated"; - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof AgentV1ThinkUpdated; - } - - @java.lang.Override - public int hashCode() { - return getClass().hashCode(); - } - - @JsonAnyGetter - public Map getAdditionalProperties() { - return this.additionalProperties; - } - - @java.lang.Override - public String toString() { - return ObjectMappers.stringify(this); - } - - public static Builder builder() { - return new Builder(); - } - - @JsonIgnoreProperties(ignoreUnknown = true) - public static final class Builder { - @JsonAnySetter - private Map additionalProperties = new HashMap<>(); - - private Builder() {} - - public Builder from(AgentV1ThinkUpdated other) { - return this; - } - - public AgentV1ThinkUpdated build() { - return new AgentV1ThinkUpdated(additionalProperties); - } - - public Builder additionalProperty(String key, Object value) { - this.additionalProperties.put(key, value); - return this; - } - - public Builder additionalProperties(Map additionalProperties) { - this.additionalProperties.putAll(additionalProperties); - return this; - } - } -} diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UpdateListenListenProvider.java b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UpdateListenListenProvider.java index e693a04..e739aec 100644 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UpdateListenListenProvider.java +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UpdateListenListenProvider.java @@ -99,7 +99,7 @@ public interface Visitor { T _visitUnknown(Object unknownType); } - @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "version", visible = true, defaultImpl = _UnknownValue.class) + @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "version", visible = true, defaultImpl = V2Value.class) @JsonSubTypes({@JsonSubTypes.Type(V1Value.class), @JsonSubTypes.Type(V2Value.class)}) @JsonIgnoreProperties(ignoreUnknown = true) private interface Value { diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UpdateListenListenProvider.java.bak b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UpdateListenListenProvider.java.bak deleted file mode 100644 index e739aec..0000000 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UpdateListenListenProvider.java.bak +++ /dev/null @@ -1,224 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.resources.agent.v1.types; - -import com.deepgram.types.DeepgramListenProviderV1; -import com.deepgram.types.DeepgramListenProviderV2; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonSubTypes; -import com.fasterxml.jackson.annotation.JsonTypeInfo; -import com.fasterxml.jackson.annotation.JsonTypeName; -import com.fasterxml.jackson.annotation.JsonUnwrapped; -import com.fasterxml.jackson.annotation.JsonValue; -import java.util.Objects; -import java.util.Optional; - -public final class AgentV1UpdateListenListenProvider { - private final Value value; - - @JsonCreator(mode = JsonCreator.Mode.DELEGATING) - private AgentV1UpdateListenListenProvider(Value value) { - this.value = value; - } - - public T visit(Visitor visitor) { - return value.visit(visitor); - } - - public static AgentV1UpdateListenListenProvider v1(DeepgramListenProviderV1 value) { - return new AgentV1UpdateListenListenProvider(new V1Value(value)); - } - - public static AgentV1UpdateListenListenProvider v2(DeepgramListenProviderV2 value) { - return new AgentV1UpdateListenListenProvider(new V2Value(value)); - } - - public boolean isV1() { - return value instanceof V1Value; - } - - public boolean isV2() { - return value instanceof V2Value; - } - - public boolean _isUnknown() { - return value instanceof _UnknownValue; - } - - public Optional getV1() { - if (isV1()) { - return Optional.of(((V1Value) value).value); - } - return Optional.empty(); - } - - public Optional getV2() { - if (isV2()) { - return Optional.of(((V2Value) value).value); - } - return Optional.empty(); - } - - public Optional _getUnknown() { - if (_isUnknown()) { - return Optional.of(((_UnknownValue) value).value); - } - return Optional.empty(); - } - - @Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof AgentV1UpdateListenListenProvider - && value.equals(((AgentV1UpdateListenListenProvider) other).value); - } - - @Override - public int hashCode() { - return Objects.hash(value); - } - - @Override - public String toString() { - return value.toString(); - } - - @JsonValue - private Value getValue() { - return this.value; - } - - public interface Visitor { - T visitV1(DeepgramListenProviderV1 v1); - - T visitV2(DeepgramListenProviderV2 v2); - - T _visitUnknown(Object unknownType); - } - - @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "version", visible = true, defaultImpl = V2Value.class) - @JsonSubTypes({@JsonSubTypes.Type(V1Value.class), @JsonSubTypes.Type(V2Value.class)}) - @JsonIgnoreProperties(ignoreUnknown = true) - private interface Value { - T visit(Visitor visitor); - } - - @JsonTypeName("v1") - @JsonIgnoreProperties("version") - private static final class V1Value implements Value { - @JsonUnwrapped - @JsonIgnoreProperties(value = "version", allowSetters = true) - private DeepgramListenProviderV1 value; - - @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) - private V1Value() {} - - private V1Value(DeepgramListenProviderV1 value) { - this.value = value; - } - - @java.lang.Override - public T visit(Visitor visitor) { - return visitor.visitV1(value); - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof V1Value && equalTo((V1Value) other); - } - - private boolean equalTo(V1Value other) { - return value.equals(other.value); - } - - @java.lang.Override - public int hashCode() { - return Objects.hash(this.value); - } - - @java.lang.Override - public String toString() { - return "AgentV1UpdateListenListenProvider{" + "value: " + value + "}"; - } - } - - @JsonTypeName("v2") - @JsonIgnoreProperties("version") - private static final class V2Value implements Value { - @JsonUnwrapped - @JsonIgnoreProperties(value = "version", allowSetters = true) - private DeepgramListenProviderV2 value; - - @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) - private V2Value() {} - - private V2Value(DeepgramListenProviderV2 value) { - this.value = value; - } - - @java.lang.Override - public T visit(Visitor visitor) { - return visitor.visitV2(value); - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof V2Value && equalTo((V2Value) other); - } - - private boolean equalTo(V2Value other) { - return value.equals(other.value); - } - - @java.lang.Override - public int hashCode() { - return Objects.hash(this.value); - } - - @java.lang.Override - public String toString() { - return "AgentV1UpdateListenListenProvider{" + "value: " + value + "}"; - } - } - - @JsonIgnoreProperties("version") - private static final class _UnknownValue implements Value { - private String type; - - @JsonValue - private Object value; - - @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) - private _UnknownValue(@JsonProperty("value") Object value) {} - - @java.lang.Override - public T visit(Visitor visitor) { - return visitor._visitUnknown(value); - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof _UnknownValue && equalTo((_UnknownValue) other); - } - - private boolean equalTo(_UnknownValue other) { - return type.equals(other.type) && value.equals(other.value); - } - - @java.lang.Override - public int hashCode() { - return Objects.hash(this.type, this.value); - } - - @java.lang.Override - public String toString() { - return "AgentV1UpdateListenListenProvider{" + "type: " + type + ", value: " + value + "}"; - } - } -} diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UserStartedSpeaking.java b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UserStartedSpeaking.java index edb80f8..3556d31 100644 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UserStartedSpeaking.java +++ b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UserStartedSpeaking.java @@ -36,6 +36,11 @@ public boolean equals(Object other) { return other instanceof AgentV1UserStartedSpeaking; } + @java.lang.Override + public int hashCode() { + return getClass().hashCode(); + } + @JsonAnyGetter public Map getAdditionalProperties() { return this.additionalProperties; diff --git a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UserStartedSpeaking.java.bak b/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UserStartedSpeaking.java.bak deleted file mode 100644 index 3556d31..0000000 --- a/src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UserStartedSpeaking.java.bak +++ /dev/null @@ -1,83 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.resources.agent.v1.types; - -import com.deepgram.core.ObjectMappers; -import com.fasterxml.jackson.annotation.JsonAnyGetter; -import com.fasterxml.jackson.annotation.JsonAnySetter; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import java.util.HashMap; -import java.util.Map; - -@JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = AgentV1UserStartedSpeaking.Builder.class) -public final class AgentV1UserStartedSpeaking { - private final Map additionalProperties; - - private AgentV1UserStartedSpeaking(Map additionalProperties) { - this.additionalProperties = additionalProperties; - } - - /** - * @return Message type identifier indicating that the user has begun speaking - */ - @JsonProperty("type") - public String getType() { - return "UserStartedSpeaking"; - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof AgentV1UserStartedSpeaking; - } - - @java.lang.Override - public int hashCode() { - return getClass().hashCode(); - } - - @JsonAnyGetter - public Map getAdditionalProperties() { - return this.additionalProperties; - } - - @java.lang.Override - public String toString() { - return ObjectMappers.stringify(this); - } - - public static Builder builder() { - return new Builder(); - } - - @JsonIgnoreProperties(ignoreUnknown = true) - public static final class Builder { - @JsonAnySetter - private Map additionalProperties = new HashMap<>(); - - private Builder() {} - - public Builder from(AgentV1UserStartedSpeaking other) { - return this; - } - - public AgentV1UserStartedSpeaking build() { - return new AgentV1UserStartedSpeaking(additionalProperties); - } - - public Builder additionalProperty(String key, Object value) { - this.additionalProperties.put(key, value); - return this; - } - - public Builder additionalProperties(Map additionalProperties) { - this.additionalProperties.putAll(additionalProperties); - return this; - } - } -} diff --git a/src/main/java/com/deepgram/resources/listen/v1/websocket/V1WebSocketClient.java b/src/main/java/com/deepgram/resources/listen/v1/websocket/V1WebSocketClient.java index a91c4e1..e7cd50c 100644 --- a/src/main/java/com/deepgram/resources/listen/v1/websocket/V1WebSocketClient.java +++ b/src/main/java/com/deepgram/resources/listen/v1/websocket/V1WebSocketClient.java @@ -6,6 +6,7 @@ import com.deepgram.core.ClientOptions; import com.deepgram.core.DisconnectReason; import com.deepgram.core.ObjectMappers; +import com.deepgram.core.QueryStringMapper; import com.deepgram.core.ReconnectingWebSocketListener; import com.deepgram.core.RequestOptions; import com.deepgram.core.WebSocketReadyState; @@ -142,8 +143,7 @@ public CompletableFuture connect(V1ConnectOptions options) { "endpointing", String.valueOf(options.getEndpointing().get())); } if (options.getExtra() != null && options.getExtra().isPresent()) { - urlBuilder.addQueryParameter( - "extra", String.valueOf(options.getExtra().get())); + QueryStringMapper.addQueryParameter(urlBuilder, "extra", options.getExtra().get().get(), true); } if (options.getInterimResults() != null && options.getInterimResults().isPresent()) { urlBuilder.addQueryParameter( @@ -151,12 +151,10 @@ public CompletableFuture connect(V1ConnectOptions options) { String.valueOf(options.getInterimResults().get())); } if (options.getKeyterm() != null && options.getKeyterm().isPresent()) { - urlBuilder.addQueryParameter( - "keyterm", String.valueOf(options.getKeyterm().get())); + QueryStringMapper.addQueryParameter(urlBuilder, "keyterm", options.getKeyterm().get().get(), true); } if (options.getKeywords() != null && options.getKeywords().isPresent()) { - urlBuilder.addQueryParameter( - "keywords", String.valueOf(options.getKeywords().get())); + QueryStringMapper.addQueryParameter(urlBuilder, "keywords", options.getKeywords().get().get(), true); } if (options.getLanguage() != null && options.getLanguage().isPresent()) { urlBuilder.addQueryParameter( @@ -189,23 +187,21 @@ public CompletableFuture connect(V1ConnectOptions options) { "redact", String.valueOf(options.getRedact().get())); } if (options.getReplace() != null && options.getReplace().isPresent()) { - urlBuilder.addQueryParameter( - "replace", String.valueOf(options.getReplace().get())); + QueryStringMapper.addQueryParameter(urlBuilder, "replace", options.getReplace().get().get(), true); } if (options.getSampleRate() != null && options.getSampleRate().isPresent()) { urlBuilder.addQueryParameter( "sample_rate", String.valueOf(options.getSampleRate().get())); } if (options.getSearch() != null && options.getSearch().isPresent()) { - urlBuilder.addQueryParameter( - "search", String.valueOf(options.getSearch().get())); + QueryStringMapper.addQueryParameter(urlBuilder, "search", options.getSearch().get().get(), true); } if (options.getSmartFormat() != null && options.getSmartFormat().isPresent()) { urlBuilder.addQueryParameter( "smart_format", String.valueOf(options.getSmartFormat().get())); } if (options.getTag() != null && options.getTag().isPresent()) { - urlBuilder.addQueryParameter("tag", String.valueOf(options.getTag().get())); + QueryStringMapper.addQueryParameter(urlBuilder, "tag", options.getTag().get().get(), true); } if (options.getUtteranceEndMs() != null && options.getUtteranceEndMs().isPresent()) { urlBuilder.addQueryParameter( @@ -220,6 +216,13 @@ public CompletableFuture connect(V1ConnectOptions options) { urlBuilder.addQueryParameter( "version", String.valueOf(options.getVersion().get())); } + if (options.getAdditionalProperties() != null) { + options.getAdditionalProperties().forEach((key, value) -> { + if (value != null) { + QueryStringMapper.addQueryParameter(urlBuilder, key, value, true); + } + }); + } Request.Builder requestBuilder = new Request.Builder().url(urlBuilder.build()); clientOptions.headers((RequestOptions) null).forEach(requestBuilder::addHeader); final Request request = requestBuilder.build(); @@ -569,6 +572,8 @@ private void handleIncomingMessage(String json) { if (errorHandlerEvent != null) { if (errorHandler != null) { errorHandler.accept(errorHandlerEvent); + } else if (onErrorHandler != null) { + onErrorHandler.accept(new ListenV1ErrorException(errorHandlerEvent)); } return; } diff --git a/src/main/java/com/deepgram/resources/listen/v1/websocket/V1WebSocketClient.java.bak b/src/main/java/com/deepgram/resources/listen/v1/websocket/V1WebSocketClient.java.bak deleted file mode 100644 index e7cd50c..0000000 --- a/src/main/java/com/deepgram/resources/listen/v1/websocket/V1WebSocketClient.java.bak +++ /dev/null @@ -1,592 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.resources.listen.v1.websocket; - -import com.deepgram.core.ClientOptions; -import com.deepgram.core.DisconnectReason; -import com.deepgram.core.ObjectMappers; -import com.deepgram.core.QueryStringMapper; -import com.deepgram.core.ReconnectingWebSocketListener; -import com.deepgram.core.RequestOptions; -import com.deepgram.core.WebSocketReadyState; -import com.deepgram.resources.listen.v1.types.ListenV1CloseStream; -import com.deepgram.resources.listen.v1.types.ListenV1Configure; -import com.deepgram.resources.listen.v1.types.ListenV1Error; -import com.deepgram.resources.listen.v1.types.ListenV1Finalize; -import com.deepgram.resources.listen.v1.types.ListenV1KeepAlive; -import com.deepgram.resources.listen.v1.types.ListenV1Metadata; -import com.deepgram.resources.listen.v1.types.ListenV1Results; -import com.deepgram.resources.listen.v1.types.ListenV1SpeechStarted; -import com.deepgram.resources.listen.v1.types.ListenV1UtteranceEnd; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ScheduledExecutorService; -import java.util.function.Consumer; -import okhttp3.HttpUrl; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; -import okhttp3.WebSocket; -import okio.ByteString; - -/** - * WebSocket client for the v1 channel. - * Provides real-time bidirectional communication with strongly-typed messages. - */ -public class V1WebSocketClient implements AutoCloseable { - protected final ClientOptions clientOptions; - - private final ObjectMapper objectMapper; - - private final OkHttpClient okHttpClient; - - private ScheduledExecutorService timeoutExecutor; - - private volatile WebSocketReadyState readyState = WebSocketReadyState.CLOSED; - - private volatile Runnable onConnectedHandler; - - private volatile Consumer onDisconnectedHandler; - - private volatile Consumer onErrorHandler; - - private volatile Consumer onMessageHandler; - - private volatile ReconnectingWebSocketListener.ReconnectOptions reconnectOptions; - - private CompletableFuture connectionFuture; - - private ReconnectingWebSocketListener reconnectingListener; - - private volatile Consumer resultsHandler; - - private volatile Consumer metadataHandler; - - private volatile Consumer utteranceEndHandler; - - private volatile Consumer speechStartedHandler; - - private volatile Consumer errorHandler; - - /** - * Creates a new async WebSocket client for the v1 channel. - */ - public V1WebSocketClient(ClientOptions clientOptions) { - this.clientOptions = clientOptions; - this.objectMapper = ObjectMappers.JSON_MAPPER; - this.okHttpClient = clientOptions.httpClient(); - } - - /** - * Establishes the WebSocket connection asynchronously with automatic reconnection. - * @return a CompletableFuture that completes when the connection is established - * @param options connection options including query parameters - */ - public CompletableFuture connect(V1ConnectOptions options) { - connectionFuture = new CompletableFuture<>(); - String baseUrl = clientOptions.environment().getProductionURL(); - String fullPath = "/v1/listen"; - if (baseUrl.endsWith("/") && fullPath.startsWith("/")) { - fullPath = fullPath.substring(1); - } else if (!baseUrl.endsWith("/") && !fullPath.startsWith("/")) { - fullPath = "/" + fullPath; - } - // OkHttp's HttpUrl only supports http/https schemes; convert wss/ws for URL parsing - if (baseUrl.startsWith("wss://")) { - baseUrl = "https://" + baseUrl.substring(6); - } else if (baseUrl.startsWith("ws://")) { - baseUrl = "http://" + baseUrl.substring(5); - } - HttpUrl parsedUrl = HttpUrl.parse(baseUrl + fullPath); - if (parsedUrl == null) { - throw new IllegalArgumentException("Invalid WebSocket URL: " + baseUrl + fullPath); - } - HttpUrl.Builder urlBuilder = parsedUrl.newBuilder(); - if (options.getCallback() != null && options.getCallback().isPresent()) { - urlBuilder.addQueryParameter( - "callback", String.valueOf(options.getCallback().get())); - } - if (options.getCallbackMethod() != null && options.getCallbackMethod().isPresent()) { - urlBuilder.addQueryParameter( - "callback_method", - String.valueOf(options.getCallbackMethod().get())); - } - if (options.getChannels() != null && options.getChannels().isPresent()) { - urlBuilder.addQueryParameter( - "channels", String.valueOf(options.getChannels().get())); - } - if (options.getDetectEntities() != null && options.getDetectEntities().isPresent()) { - urlBuilder.addQueryParameter( - "detect_entities", - String.valueOf(options.getDetectEntities().get())); - } - if (options.getDiarize() != null && options.getDiarize().isPresent()) { - urlBuilder.addQueryParameter( - "diarize", String.valueOf(options.getDiarize().get())); - } - if (options.getDiarizeModel() != null && options.getDiarizeModel().isPresent()) { - urlBuilder.addQueryParameter( - "diarize_model", String.valueOf(options.getDiarizeModel().get())); - } - if (options.getDictation() != null && options.getDictation().isPresent()) { - urlBuilder.addQueryParameter( - "dictation", String.valueOf(options.getDictation().get())); - } - if (options.getEncoding() != null && options.getEncoding().isPresent()) { - urlBuilder.addQueryParameter( - "encoding", String.valueOf(options.getEncoding().get())); - } - if (options.getEndpointing() != null && options.getEndpointing().isPresent()) { - urlBuilder.addQueryParameter( - "endpointing", String.valueOf(options.getEndpointing().get())); - } - if (options.getExtra() != null && options.getExtra().isPresent()) { - QueryStringMapper.addQueryParameter(urlBuilder, "extra", options.getExtra().get().get(), true); - } - if (options.getInterimResults() != null && options.getInterimResults().isPresent()) { - urlBuilder.addQueryParameter( - "interim_results", - String.valueOf(options.getInterimResults().get())); - } - if (options.getKeyterm() != null && options.getKeyterm().isPresent()) { - QueryStringMapper.addQueryParameter(urlBuilder, "keyterm", options.getKeyterm().get().get(), true); - } - if (options.getKeywords() != null && options.getKeywords().isPresent()) { - QueryStringMapper.addQueryParameter(urlBuilder, "keywords", options.getKeywords().get().get(), true); - } - if (options.getLanguage() != null && options.getLanguage().isPresent()) { - urlBuilder.addQueryParameter( - "language", String.valueOf(options.getLanguage().get())); - } - if (options.getMipOptOut() != null && options.getMipOptOut().isPresent()) { - urlBuilder.addQueryParameter( - "mip_opt_out", String.valueOf(options.getMipOptOut().get())); - } - urlBuilder.addQueryParameter("model", String.valueOf(options.getModel())); - if (options.getMultichannel() != null && options.getMultichannel().isPresent()) { - urlBuilder.addQueryParameter( - "multichannel", String.valueOf(options.getMultichannel().get())); - } - if (options.getNumerals() != null && options.getNumerals().isPresent()) { - urlBuilder.addQueryParameter( - "numerals", String.valueOf(options.getNumerals().get())); - } - if (options.getProfanityFilter() != null && options.getProfanityFilter().isPresent()) { - urlBuilder.addQueryParameter( - "profanity_filter", - String.valueOf(options.getProfanityFilter().get())); - } - if (options.getPunctuate() != null && options.getPunctuate().isPresent()) { - urlBuilder.addQueryParameter( - "punctuate", String.valueOf(options.getPunctuate().get())); - } - if (options.getRedact() != null && options.getRedact().isPresent()) { - urlBuilder.addQueryParameter( - "redact", String.valueOf(options.getRedact().get())); - } - if (options.getReplace() != null && options.getReplace().isPresent()) { - QueryStringMapper.addQueryParameter(urlBuilder, "replace", options.getReplace().get().get(), true); - } - if (options.getSampleRate() != null && options.getSampleRate().isPresent()) { - urlBuilder.addQueryParameter( - "sample_rate", String.valueOf(options.getSampleRate().get())); - } - if (options.getSearch() != null && options.getSearch().isPresent()) { - QueryStringMapper.addQueryParameter(urlBuilder, "search", options.getSearch().get().get(), true); - } - if (options.getSmartFormat() != null && options.getSmartFormat().isPresent()) { - urlBuilder.addQueryParameter( - "smart_format", String.valueOf(options.getSmartFormat().get())); - } - if (options.getTag() != null && options.getTag().isPresent()) { - QueryStringMapper.addQueryParameter(urlBuilder, "tag", options.getTag().get().get(), true); - } - if (options.getUtteranceEndMs() != null && options.getUtteranceEndMs().isPresent()) { - urlBuilder.addQueryParameter( - "utterance_end_ms", - String.valueOf(options.getUtteranceEndMs().get())); - } - if (options.getVadEvents() != null && options.getVadEvents().isPresent()) { - urlBuilder.addQueryParameter( - "vad_events", String.valueOf(options.getVadEvents().get())); - } - if (options.getVersion() != null && options.getVersion().isPresent()) { - urlBuilder.addQueryParameter( - "version", String.valueOf(options.getVersion().get())); - } - if (options.getAdditionalProperties() != null) { - options.getAdditionalProperties().forEach((key, value) -> { - if (value != null) { - QueryStringMapper.addQueryParameter(urlBuilder, key, value, true); - } - }); - } - Request.Builder requestBuilder = new Request.Builder().url(urlBuilder.build()); - clientOptions.headers((RequestOptions) null).forEach(requestBuilder::addHeader); - final Request request = requestBuilder.build(); - this.readyState = WebSocketReadyState.CONNECTING; - ReconnectingWebSocketListener.ReconnectOptions reconnectOpts = this.reconnectOptions != null - ? this.reconnectOptions - : ReconnectingWebSocketListener.ReconnectOptions.builder().build(); - this.reconnectingListener = - new ReconnectingWebSocketListener( - reconnectOpts, - () -> { - if (clientOptions.isClosed()) { - throw new IllegalStateException("root client has been closed"); - } - if (clientOptions.webSocketFactory().isPresent()) { - return clientOptions - .webSocketFactory() - .get() - .create(request, this.reconnectingListener); - } else { - return okHttpClient.newWebSocket(request, this.reconnectingListener); - } - }, - clientOptions::isClosed) { - @Override - protected void onWebSocketOpen(WebSocket webSocket, Response response) { - readyState = WebSocketReadyState.OPEN; - if (onConnectedHandler != null) { - onConnectedHandler.run(); - } - connectionFuture.complete(null); - } - - @Override - protected void onWebSocketMessage(WebSocket webSocket, String text) { - handleIncomingMessage(text); - } - - @Override - protected void onWebSocketBinaryMessage(WebSocket webSocket, ByteString bytes) {} - - @Override - protected void onWebSocketFailure(WebSocket webSocket, Throwable t, Response response) { - readyState = WebSocketReadyState.CLOSED; - if (onErrorHandler != null) { - onErrorHandler.accept(new RuntimeException(t)); - } - connectionFuture.completeExceptionally(t); - } - - @Override - protected void onWebSocketClosed(WebSocket webSocket, int code, String reason) { - readyState = WebSocketReadyState.CLOSED; - if (onDisconnectedHandler != null) { - onDisconnectedHandler.accept(new DisconnectReason(code, reason)); - } - } - }; - clientOptions.registerWebSocket(this); - reconnectingListener.connect(); - return connectionFuture; - } - - /** - * Disconnects the WebSocket connection and releases resources. - */ - public void disconnect() { - clientOptions.unregisterWebSocket(this); - if (reconnectingListener != null) { - reconnectingListener.disconnect(); - } - if (timeoutExecutor != null) { - timeoutExecutor.shutdownNow(); - timeoutExecutor = null; - } - } - - /** - * Gets the current state of the WebSocket connection. - * - * This provides the actual connection state, similar to the W3C WebSocket API. - * - * @return the current WebSocket ready state - */ - public WebSocketReadyState getReadyState() { - return readyState; - } - - /** - * Sends a ListenV1Media message to the server asynchronously. - * @param message the message to send - * @return a CompletableFuture that completes when the message is sent - */ - public CompletableFuture sendMedia(ByteString message) { - CompletableFuture future = new CompletableFuture<>(); - try { - assertSocketIsOpen(); - // Use reconnecting listener's sendBinary method which handles queuing - reconnectingListener.sendBinary(message); - future.complete(null); - } catch (Exception e) { - future.completeExceptionally(new RuntimeException("Failed to send binary data", e)); - } - return future; - } - - /** - * Sends a ListenV1Finalize message to the server asynchronously. - * @param message the message to send - * @return a CompletableFuture that completes when the message is sent - */ - public CompletableFuture sendFinalize(ListenV1Finalize message) { - return sendMessage(message); - } - - /** - * Sends a ListenV1CloseStream message to the server asynchronously. - * @param message the message to send - * @return a CompletableFuture that completes when the message is sent - */ - public CompletableFuture sendCloseStream(ListenV1CloseStream message) { - return sendMessage(message); - } - - /** - * Sends a ListenV1KeepAlive message to the server asynchronously. - * @param message the message to send - * @return a CompletableFuture that completes when the message is sent - */ - public CompletableFuture sendKeepAlive(ListenV1KeepAlive message) { - return sendMessage(message); - } - - /** - * Sends a ListenV1Configure message to the server asynchronously. - * @param message the message to send - * @return a CompletableFuture that completes when the message is sent - */ - public CompletableFuture sendConfigure(ListenV1Configure message) { - return sendMessage(message); - } - - /** - * Registers a handler for ListenV1Results messages from the server. - * @param handler the handler to invoke when a message is received - */ - public void onResults(Consumer handler) { - this.resultsHandler = handler; - } - - /** - * Registers a handler for ListenV1Metadata messages from the server. - * @param handler the handler to invoke when a message is received - */ - public void onMetadata(Consumer handler) { - this.metadataHandler = handler; - } - - /** - * Registers a handler for ListenV1UtteranceEnd messages from the server. - * @param handler the handler to invoke when a message is received - */ - public void onUtteranceEnd(Consumer handler) { - this.utteranceEndHandler = handler; - } - - /** - * Registers a handler for ListenV1SpeechStarted messages from the server. - * @param handler the handler to invoke when a message is received - */ - public void onSpeechStarted(Consumer handler) { - this.speechStartedHandler = handler; - } - - /** - * Registers a handler for ListenV1Error messages from the server. - * @param handler the handler to invoke when a message is received - */ - public void onErrorMessage(Consumer handler) { - this.errorHandler = handler; - } - - /** - * Registers a handler called when the connection is established. - * @param handler the handler to invoke when connected - */ - public void onConnected(Runnable handler) { - this.onConnectedHandler = handler; - } - - /** - * Registers a handler called when the connection is closed. - * @param handler the handler to invoke when disconnected - */ - public void onDisconnected(Consumer handler) { - this.onDisconnectedHandler = handler; - } - - /** - * Registers a handler called when an error occurs. - * @param handler the handler to invoke on error - */ - public void onError(Consumer handler) { - this.onErrorHandler = handler; - } - - /** - * Registers a handler called for every incoming text message. - * The handler receives the raw JSON string before type-specific dispatch. - * @param handler the handler to invoke with the raw message JSON - */ - public void onMessage(Consumer handler) { - this.onMessageHandler = handler; - } - - /** - * Configures reconnection behavior. Must be called before {@link #connect}. - * - * @param options the reconnection options (backoff, retries, queue size) - */ - public void reconnectOptions(ReconnectingWebSocketListener.ReconnectOptions options) { - this.reconnectOptions = options; - } - - /** - * Closes this WebSocket client, releasing all resources. - * Equivalent to calling {@link #disconnect()}. - */ - @Override - public void close() { - disconnect(); - } - - /** - * Ensures the WebSocket is connected and ready to send messages. - * @throws IllegalStateException if the socket is not connected or not open - */ - private void assertSocketIsOpen() { - if (reconnectingListener.getWebSocket() == null) { - throw new IllegalStateException("WebSocket is not connected. Call connect() first."); - } - if (readyState != WebSocketReadyState.OPEN) { - throw new IllegalStateException("WebSocket is not open. Current state: " + readyState); - } - } - - private CompletableFuture sendMessage(Object body) { - CompletableFuture future = new CompletableFuture<>(); - try { - assertSocketIsOpen(); - String json = objectMapper.writeValueAsString(body); - // Use reconnecting listener's send method which handles queuing - reconnectingListener.send(json); - future.complete(null); - } catch (IllegalStateException e) { - future.completeExceptionally(e); - } catch (Exception e) { - future.completeExceptionally(new RuntimeException("Failed to send message", e)); - } - return future; - } - - private void handleIncomingMessage(String json) { - try { - if (onMessageHandler != null) { - onMessageHandler.accept(json); - } - JsonNode node = objectMapper.readTree(json); - if (node == null || node.isNull()) { - throw new IllegalArgumentException("Received null or invalid JSON message"); - } - if (node.has("transaction_key") - && node.has("request_id") - && node.has("sha256") - && node.has("created") - && node.has("duration") - && node.has("channels") - && "Metadata".equals(node.path("type").asText())) { - ListenV1Metadata metadataHandlerEvent = null; - try { - metadataHandlerEvent = objectMapper.treeToValue(node, ListenV1Metadata.class); - } catch (Exception e) { - } - if (metadataHandlerEvent != null) { - if (metadataHandler != null) { - metadataHandler.accept(metadataHandlerEvent); - } - return; - } - } - if (node.has("channel_index") - && node.has("duration") - && node.has("start") - && node.has("channel") - && node.has("metadata") - && "Results".equals(node.path("type").asText())) { - ListenV1Results resultsHandlerEvent = null; - try { - resultsHandlerEvent = objectMapper.treeToValue(node, ListenV1Results.class); - } catch (Exception e) { - } - if (resultsHandlerEvent != null) { - if (resultsHandler != null) { - resultsHandler.accept(resultsHandlerEvent); - } - return; - } - } - if (node.has("channel") - && node.has("last_word_end") - && "UtteranceEnd".equals(node.path("type").asText())) { - ListenV1UtteranceEnd utteranceEndHandlerEvent = null; - try { - utteranceEndHandlerEvent = objectMapper.treeToValue(node, ListenV1UtteranceEnd.class); - } catch (Exception e) { - } - if (utteranceEndHandlerEvent != null) { - if (utteranceEndHandler != null) { - utteranceEndHandler.accept(utteranceEndHandlerEvent); - } - return; - } - } - if (node.has("channel") - && node.has("timestamp") - && "SpeechStarted".equals(node.path("type").asText())) { - ListenV1SpeechStarted speechStartedHandlerEvent = null; - try { - speechStartedHandlerEvent = objectMapper.treeToValue(node, ListenV1SpeechStarted.class); - } catch (Exception e) { - } - if (speechStartedHandlerEvent != null) { - if (speechStartedHandler != null) { - speechStartedHandler.accept(speechStartedHandlerEvent); - } - return; - } - } - if (node.has("variant") - && node.has("description") - && "Error".equals(node.path("type").asText())) { - ListenV1Error errorHandlerEvent = null; - try { - errorHandlerEvent = objectMapper.treeToValue(node, ListenV1Error.class); - } catch (Exception e) { - } - if (errorHandlerEvent != null) { - if (errorHandler != null) { - errorHandler.accept(errorHandlerEvent); - } else if (onErrorHandler != null) { - onErrorHandler.accept(new ListenV1ErrorException(errorHandlerEvent)); - } - return; - } - } - if (onErrorHandler != null) { - onErrorHandler.accept(new RuntimeException( - "Unrecognized WebSocket message: " + json.substring(0, Math.min(200, json.length())) - + "... Update your SDK version to support new message types.")); - } - } catch (Exception e) { - if (onErrorHandler != null) { - onErrorHandler.accept(e); - } - } - } -} diff --git a/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2CloseStream.java b/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2CloseStream.java index e6308e2..c9f2f35 100644 --- a/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2CloseStream.java +++ b/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2CloseStream.java @@ -36,6 +36,11 @@ public boolean equals(Object other) { return other instanceof ListenV2CloseStream; } + @java.lang.Override + public int hashCode() { + return getClass().hashCode(); + } + @JsonAnyGetter public Map getAdditionalProperties() { return this.additionalProperties; diff --git a/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2CloseStream.java.bak b/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2CloseStream.java.bak deleted file mode 100644 index c9f2f35..0000000 --- a/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2CloseStream.java.bak +++ /dev/null @@ -1,83 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.resources.listen.v2.types; - -import com.deepgram.core.ObjectMappers; -import com.fasterxml.jackson.annotation.JsonAnyGetter; -import com.fasterxml.jackson.annotation.JsonAnySetter; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import java.util.HashMap; -import java.util.Map; - -@JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = ListenV2CloseStream.Builder.class) -public final class ListenV2CloseStream { - private final Map additionalProperties; - - private ListenV2CloseStream(Map additionalProperties) { - this.additionalProperties = additionalProperties; - } - - /** - * @return Message type identifier - */ - @JsonProperty("type") - public String getType() { - return "CloseStream"; - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof ListenV2CloseStream; - } - - @java.lang.Override - public int hashCode() { - return getClass().hashCode(); - } - - @JsonAnyGetter - public Map getAdditionalProperties() { - return this.additionalProperties; - } - - @java.lang.Override - public String toString() { - return ObjectMappers.stringify(this); - } - - public static Builder builder() { - return new Builder(); - } - - @JsonIgnoreProperties(ignoreUnknown = true) - public static final class Builder { - @JsonAnySetter - private Map additionalProperties = new HashMap<>(); - - private Builder() {} - - public Builder from(ListenV2CloseStream other) { - return this; - } - - public ListenV2CloseStream build() { - return new ListenV2CloseStream(additionalProperties); - } - - public Builder additionalProperty(String key, Object value) { - this.additionalProperties.put(key, value); - return this; - } - - public Builder additionalProperties(Map additionalProperties) { - this.additionalProperties.putAll(additionalProperties); - return this; - } - } -} diff --git a/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ForceEndTurn.java b/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ForceEndTurn.java index c3dbd38..894bd3c 100644 --- a/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ForceEndTurn.java +++ b/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ForceEndTurn.java @@ -36,6 +36,11 @@ public boolean equals(Object other) { return other instanceof ListenV2ForceEndTurn; } + @java.lang.Override + public int hashCode() { + return getClass().hashCode(); + } + @JsonAnyGetter public Map getAdditionalProperties() { return this.additionalProperties; diff --git a/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ForceEndTurn.java.bak b/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ForceEndTurn.java.bak deleted file mode 100644 index 894bd3c..0000000 --- a/src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ForceEndTurn.java.bak +++ /dev/null @@ -1,83 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.resources.listen.v2.types; - -import com.deepgram.core.ObjectMappers; -import com.fasterxml.jackson.annotation.JsonAnyGetter; -import com.fasterxml.jackson.annotation.JsonAnySetter; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import java.util.HashMap; -import java.util.Map; - -@JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = ListenV2ForceEndTurn.Builder.class) -public final class ListenV2ForceEndTurn { - private final Map additionalProperties; - - private ListenV2ForceEndTurn(Map additionalProperties) { - this.additionalProperties = additionalProperties; - } - - /** - * @return Message type identifier - */ - @JsonProperty("type") - public String getType() { - return "ForceEndTurn"; - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof ListenV2ForceEndTurn; - } - - @java.lang.Override - public int hashCode() { - return getClass().hashCode(); - } - - @JsonAnyGetter - public Map getAdditionalProperties() { - return this.additionalProperties; - } - - @java.lang.Override - public String toString() { - return ObjectMappers.stringify(this); - } - - public static Builder builder() { - return new Builder(); - } - - @JsonIgnoreProperties(ignoreUnknown = true) - public static final class Builder { - @JsonAnySetter - private Map additionalProperties = new HashMap<>(); - - private Builder() {} - - public Builder from(ListenV2ForceEndTurn other) { - return this; - } - - public ListenV2ForceEndTurn build() { - return new ListenV2ForceEndTurn(additionalProperties); - } - - public Builder additionalProperty(String key, Object value) { - this.additionalProperties.put(key, value); - return this; - } - - public Builder additionalProperties(Map additionalProperties) { - this.additionalProperties.putAll(additionalProperties); - return this; - } - } -} diff --git a/src/main/java/com/deepgram/resources/listen/v2/websocket/V2WebSocketClient.java b/src/main/java/com/deepgram/resources/listen/v2/websocket/V2WebSocketClient.java index 84bf5df..5f55fea 100644 --- a/src/main/java/com/deepgram/resources/listen/v2/websocket/V2WebSocketClient.java +++ b/src/main/java/com/deepgram/resources/listen/v2/websocket/V2WebSocketClient.java @@ -6,6 +6,7 @@ import com.deepgram.core.ClientOptions; import com.deepgram.core.DisconnectReason; import com.deepgram.core.ObjectMappers; +import com.deepgram.core.QueryStringMapper; import com.deepgram.core.ReconnectingWebSocketListener; import com.deepgram.core.RequestOptions; import com.deepgram.core.WebSocketReadyState; @@ -22,6 +23,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; import okhttp3.HttpUrl; import okhttp3.OkHttpClient; @@ -59,6 +61,8 @@ public class V2WebSocketClient implements AutoCloseable { private ReconnectingWebSocketListener reconnectingListener; + private final AtomicReference closeStreamSocket = new AtomicReference<>(); + private volatile Consumer connectedHandler; private volatile Consumer turnInfoHandler; @@ -87,6 +91,7 @@ public V2WebSocketClient(ClientOptions clientOptions) { */ public CompletableFuture connect(V2ConnectOptions options) { connectionFuture = new CompletableFuture<>(); + closeStreamSocket.set(null); String baseUrl = clientOptions.environment().getProductionURL(); String fullPath = "/v2/listen"; if (baseUrl.endsWith("/") && fullPath.startsWith("/")) { @@ -129,12 +134,12 @@ public CompletableFuture connect(V2ConnectOptions options) { "eot_timeout_ms", String.valueOf(options.getEotTimeoutMs().get())); } if (options.getKeyterm() != null && options.getKeyterm().isPresent()) { - urlBuilder.addQueryParameter( - "keyterm", String.valueOf(options.getKeyterm().get())); + QueryStringMapper.addQueryParameter( + urlBuilder, "keyterm", options.getKeyterm().get().get(), true); } if (options.getLanguageHint() != null && options.getLanguageHint().isPresent()) { - urlBuilder.addQueryParameter( - "language_hint", String.valueOf(options.getLanguageHint().get())); + QueryStringMapper.addQueryParameter( + urlBuilder, "language_hint", options.getLanguageHint().get().get(), true); } if (options.getProfanityFilter() != null && options.getProfanityFilter().isPresent()) { urlBuilder.addQueryParameter( @@ -154,7 +159,14 @@ public CompletableFuture connect(V2ConnectOptions options) { "mip_opt_out", String.valueOf(options.getMipOptOut().get())); } if (options.getTag() != null && options.getTag().isPresent()) { - urlBuilder.addQueryParameter("tag", String.valueOf(options.getTag().get())); + QueryStringMapper.addQueryParameter(urlBuilder, "tag", options.getTag().get().get(), true); + } + if (options.getAdditionalProperties() != null) { + options.getAdditionalProperties().forEach((key, value) -> { + if (value != null) { + QueryStringMapper.addQueryParameter(urlBuilder, key, value, true); + } + }); } Request.Builder requestBuilder = new Request.Builder().url(urlBuilder.build()); clientOptions.headers((RequestOptions) null).forEach(requestBuilder::addHeader); @@ -182,6 +194,7 @@ public CompletableFuture connect(V2ConnectOptions options) { clientOptions::isClosed) { @Override protected void onWebSocketOpen(WebSocket webSocket, Response response) { + closeStreamSocket.set(null); readyState = WebSocketReadyState.OPEN; if (onConnectedHandler != null) { onConnectedHandler.run(); @@ -213,6 +226,12 @@ protected void onWebSocketClosed(WebSocket webSocket, int code, String reason) { onDisconnectedHandler.accept(new DisconnectReason(code, reason)); } } + + @Override + protected boolean shouldReconnectAfterClose(WebSocket webSocket, int code, String reason) { + return super.shouldReconnectAfterClose(webSocket, code, reason) + && (code != 1005 || closeStreamSocket.get() != webSocket); + } }; clientOptions.registerWebSocket(this); reconnectingListener.connect(); @@ -263,12 +282,13 @@ public CompletableFuture sendMedia(ByteString message) { } /** - * Sends a ListenV2CloseStream message to the server asynchronously. + * Sends a ListenV2CloseStream message to the server asynchronously. A queued CloseStream does + * not suppress reconnects because it might never reach the server. * @param message the message to send * @return a CompletableFuture that completes when the message is sent */ public CompletableFuture sendCloseStream(ListenV2CloseStream message) { - return sendMessage(message); + return sendMessage(message, closeStreamSocket::set); } /** @@ -402,12 +422,16 @@ private void assertSocketIsOpen() { } private CompletableFuture sendMessage(Object body) { + return sendMessage(body, null); + } + + private CompletableFuture sendMessage(Object body, Consumer onSent) { CompletableFuture future = new CompletableFuture<>(); try { assertSocketIsOpen(); String json = objectMapper.writeValueAsString(body); // Use reconnecting listener's send method which handles queuing - reconnectingListener.send(json); + reconnectingListener.send(json, onSent); future.complete(null); } catch (IllegalStateException e) { future.completeExceptionally(e); @@ -528,11 +552,8 @@ private void handleIncomingMessage(String json) { return; } } - if (onErrorHandler != null) { - onErrorHandler.accept(new RuntimeException( - "Unrecognized WebSocket message: " + json.substring(0, Math.min(200, json.length())) - + "... Update your SDK version to support new message types.")); - } + // The raw frame is already delivered to onMessage(String), so ignore unknown typed + // frames for forward compatibility with newly added server control messages. } catch (Exception e) { if (onErrorHandler != null) { onErrorHandler.accept(e); diff --git a/src/main/java/com/deepgram/resources/listen/v2/websocket/V2WebSocketClient.java.bak b/src/main/java/com/deepgram/resources/listen/v2/websocket/V2WebSocketClient.java.bak deleted file mode 100644 index 5f55fea..0000000 --- a/src/main/java/com/deepgram/resources/listen/v2/websocket/V2WebSocketClient.java.bak +++ /dev/null @@ -1,563 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.resources.listen.v2.websocket; - -import com.deepgram.core.ClientOptions; -import com.deepgram.core.DisconnectReason; -import com.deepgram.core.ObjectMappers; -import com.deepgram.core.QueryStringMapper; -import com.deepgram.core.ReconnectingWebSocketListener; -import com.deepgram.core.RequestOptions; -import com.deepgram.core.WebSocketReadyState; -import com.deepgram.resources.listen.v2.types.ListenV2CloseStream; -import com.deepgram.resources.listen.v2.types.ListenV2Configure; -import com.deepgram.resources.listen.v2.types.ListenV2ConfigureFailure; -import com.deepgram.resources.listen.v2.types.ListenV2ConfigureSuccess; -import com.deepgram.resources.listen.v2.types.ListenV2Connected; -import com.deepgram.resources.listen.v2.types.ListenV2FatalError; -import com.deepgram.resources.listen.v2.types.ListenV2ForceEndTurn; -import com.deepgram.resources.listen.v2.types.ListenV2TurnInfo; -import com.deepgram.resources.listen.v2.types.ListenV2Warning; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Consumer; -import okhttp3.HttpUrl; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; -import okhttp3.WebSocket; -import okio.ByteString; - -/** - * WebSocket client for the v2 channel. - * Provides real-time bidirectional communication with strongly-typed messages. - */ -public class V2WebSocketClient implements AutoCloseable { - protected final ClientOptions clientOptions; - - private final ObjectMapper objectMapper; - - private final OkHttpClient okHttpClient; - - private ScheduledExecutorService timeoutExecutor; - - private volatile WebSocketReadyState readyState = WebSocketReadyState.CLOSED; - - private volatile Runnable onConnectedHandler; - - private volatile Consumer onDisconnectedHandler; - - private volatile Consumer onErrorHandler; - - private volatile Consumer onMessageHandler; - - private volatile ReconnectingWebSocketListener.ReconnectOptions reconnectOptions; - - private CompletableFuture connectionFuture; - - private ReconnectingWebSocketListener reconnectingListener; - - private final AtomicReference closeStreamSocket = new AtomicReference<>(); - - private volatile Consumer connectedHandler; - - private volatile Consumer turnInfoHandler; - - private volatile Consumer configureSuccessHandler; - - private volatile Consumer configureFailureHandler; - - private volatile Consumer warningHandler; - - private volatile Consumer errorHandler; - - /** - * Creates a new async WebSocket client for the v2 channel. - */ - public V2WebSocketClient(ClientOptions clientOptions) { - this.clientOptions = clientOptions; - this.objectMapper = ObjectMappers.JSON_MAPPER; - this.okHttpClient = clientOptions.httpClient(); - } - - /** - * Establishes the WebSocket connection asynchronously with automatic reconnection. - * @return a CompletableFuture that completes when the connection is established - * @param options connection options including query parameters - */ - public CompletableFuture connect(V2ConnectOptions options) { - connectionFuture = new CompletableFuture<>(); - closeStreamSocket.set(null); - String baseUrl = clientOptions.environment().getProductionURL(); - String fullPath = "/v2/listen"; - if (baseUrl.endsWith("/") && fullPath.startsWith("/")) { - fullPath = fullPath.substring(1); - } else if (!baseUrl.endsWith("/") && !fullPath.startsWith("/")) { - fullPath = "/" + fullPath; - } - // OkHttp's HttpUrl only supports http/https schemes; convert wss/ws for URL parsing - if (baseUrl.startsWith("wss://")) { - baseUrl = "https://" + baseUrl.substring(6); - } else if (baseUrl.startsWith("ws://")) { - baseUrl = "http://" + baseUrl.substring(5); - } - HttpUrl parsedUrl = HttpUrl.parse(baseUrl + fullPath); - if (parsedUrl == null) { - throw new IllegalArgumentException("Invalid WebSocket URL: " + baseUrl + fullPath); - } - HttpUrl.Builder urlBuilder = parsedUrl.newBuilder(); - urlBuilder.addQueryParameter("model", String.valueOf(options.getModel())); - if (options.getEncoding() != null && options.getEncoding().isPresent()) { - urlBuilder.addQueryParameter( - "encoding", String.valueOf(options.getEncoding().get())); - } - if (options.getSampleRate() != null && options.getSampleRate().isPresent()) { - urlBuilder.addQueryParameter( - "sample_rate", String.valueOf(options.getSampleRate().get())); - } - if (options.getEagerEotThreshold() != null - && options.getEagerEotThreshold().isPresent()) { - urlBuilder.addQueryParameter( - "eager_eot_threshold", - String.valueOf(options.getEagerEotThreshold().get())); - } - if (options.getEotThreshold() != null && options.getEotThreshold().isPresent()) { - urlBuilder.addQueryParameter( - "eot_threshold", String.valueOf(options.getEotThreshold().get())); - } - if (options.getEotTimeoutMs() != null && options.getEotTimeoutMs().isPresent()) { - urlBuilder.addQueryParameter( - "eot_timeout_ms", String.valueOf(options.getEotTimeoutMs().get())); - } - if (options.getKeyterm() != null && options.getKeyterm().isPresent()) { - QueryStringMapper.addQueryParameter( - urlBuilder, "keyterm", options.getKeyterm().get().get(), true); - } - if (options.getLanguageHint() != null && options.getLanguageHint().isPresent()) { - QueryStringMapper.addQueryParameter( - urlBuilder, "language_hint", options.getLanguageHint().get().get(), true); - } - if (options.getProfanityFilter() != null && options.getProfanityFilter().isPresent()) { - urlBuilder.addQueryParameter( - "profanity_filter", - String.valueOf(options.getProfanityFilter().get())); - } - if (options.getNumerals() != null && options.getNumerals().isPresent()) { - urlBuilder.addQueryParameter( - "numerals", String.valueOf(options.getNumerals().get())); - } - if (options.getRedact() != null && options.getRedact().isPresent()) { - urlBuilder.addQueryParameter( - "redact", String.valueOf(options.getRedact().get())); - } - if (options.getMipOptOut() != null && options.getMipOptOut().isPresent()) { - urlBuilder.addQueryParameter( - "mip_opt_out", String.valueOf(options.getMipOptOut().get())); - } - if (options.getTag() != null && options.getTag().isPresent()) { - QueryStringMapper.addQueryParameter(urlBuilder, "tag", options.getTag().get().get(), true); - } - if (options.getAdditionalProperties() != null) { - options.getAdditionalProperties().forEach((key, value) -> { - if (value != null) { - QueryStringMapper.addQueryParameter(urlBuilder, key, value, true); - } - }); - } - Request.Builder requestBuilder = new Request.Builder().url(urlBuilder.build()); - clientOptions.headers((RequestOptions) null).forEach(requestBuilder::addHeader); - final Request request = requestBuilder.build(); - this.readyState = WebSocketReadyState.CONNECTING; - ReconnectingWebSocketListener.ReconnectOptions reconnectOpts = this.reconnectOptions != null - ? this.reconnectOptions - : ReconnectingWebSocketListener.ReconnectOptions.builder().build(); - this.reconnectingListener = - new ReconnectingWebSocketListener( - reconnectOpts, - () -> { - if (clientOptions.isClosed()) { - throw new IllegalStateException("root client has been closed"); - } - if (clientOptions.webSocketFactory().isPresent()) { - return clientOptions - .webSocketFactory() - .get() - .create(request, this.reconnectingListener); - } else { - return okHttpClient.newWebSocket(request, this.reconnectingListener); - } - }, - clientOptions::isClosed) { - @Override - protected void onWebSocketOpen(WebSocket webSocket, Response response) { - closeStreamSocket.set(null); - readyState = WebSocketReadyState.OPEN; - if (onConnectedHandler != null) { - onConnectedHandler.run(); - } - connectionFuture.complete(null); - } - - @Override - protected void onWebSocketMessage(WebSocket webSocket, String text) { - handleIncomingMessage(text); - } - - @Override - protected void onWebSocketBinaryMessage(WebSocket webSocket, ByteString bytes) {} - - @Override - protected void onWebSocketFailure(WebSocket webSocket, Throwable t, Response response) { - readyState = WebSocketReadyState.CLOSED; - if (onErrorHandler != null) { - onErrorHandler.accept(new RuntimeException(t)); - } - connectionFuture.completeExceptionally(t); - } - - @Override - protected void onWebSocketClosed(WebSocket webSocket, int code, String reason) { - readyState = WebSocketReadyState.CLOSED; - if (onDisconnectedHandler != null) { - onDisconnectedHandler.accept(new DisconnectReason(code, reason)); - } - } - - @Override - protected boolean shouldReconnectAfterClose(WebSocket webSocket, int code, String reason) { - return super.shouldReconnectAfterClose(webSocket, code, reason) - && (code != 1005 || closeStreamSocket.get() != webSocket); - } - }; - clientOptions.registerWebSocket(this); - reconnectingListener.connect(); - return connectionFuture; - } - - /** - * Disconnects the WebSocket connection and releases resources. - */ - public void disconnect() { - clientOptions.unregisterWebSocket(this); - if (reconnectingListener != null) { - reconnectingListener.disconnect(); - } - if (timeoutExecutor != null) { - timeoutExecutor.shutdownNow(); - timeoutExecutor = null; - } - } - - /** - * Gets the current state of the WebSocket connection. - * - * This provides the actual connection state, similar to the W3C WebSocket API. - * - * @return the current WebSocket ready state - */ - public WebSocketReadyState getReadyState() { - return readyState; - } - - /** - * Sends a ListenV2Media message to the server asynchronously. - * @param message the message to send - * @return a CompletableFuture that completes when the message is sent - */ - public CompletableFuture sendMedia(ByteString message) { - CompletableFuture future = new CompletableFuture<>(); - try { - assertSocketIsOpen(); - // Use reconnecting listener's sendBinary method which handles queuing - reconnectingListener.sendBinary(message); - future.complete(null); - } catch (Exception e) { - future.completeExceptionally(new RuntimeException("Failed to send binary data", e)); - } - return future; - } - - /** - * Sends a ListenV2CloseStream message to the server asynchronously. A queued CloseStream does - * not suppress reconnects because it might never reach the server. - * @param message the message to send - * @return a CompletableFuture that completes when the message is sent - */ - public CompletableFuture sendCloseStream(ListenV2CloseStream message) { - return sendMessage(message, closeStreamSocket::set); - } - - /** - * Sends a ListenV2ForceEndTurn message to the server asynchronously. - * @param message the message to send - * @return a CompletableFuture that completes when the message is sent - */ - public CompletableFuture sendForceEndTurn(ListenV2ForceEndTurn message) { - return sendMessage(message); - } - - /** - * Sends a ListenV2Configure message to the server asynchronously. - * @param message the message to send - * @return a CompletableFuture that completes when the message is sent - */ - public CompletableFuture sendConfigure(ListenV2Configure message) { - return sendMessage(message); - } - - /** - * Registers a handler for ListenV2Connected messages from the server. - * @param handler the handler to invoke when a message is received - */ - public void onConnected(Consumer handler) { - this.connectedHandler = handler; - } - - /** - * Registers a handler for ListenV2TurnInfo messages from the server. - * @param handler the handler to invoke when a message is received - */ - public void onTurnInfo(Consumer handler) { - this.turnInfoHandler = handler; - } - - /** - * Registers a handler for ListenV2ConfigureSuccess messages from the server. - * @param handler the handler to invoke when a message is received - */ - public void onConfigureSuccess(Consumer handler) { - this.configureSuccessHandler = handler; - } - - /** - * Registers a handler for ListenV2ConfigureFailure messages from the server. - * @param handler the handler to invoke when a message is received - */ - public void onConfigureFailure(Consumer handler) { - this.configureFailureHandler = handler; - } - - /** - * Registers a handler for ListenV2Warning messages from the server. - * @param handler the handler to invoke when a message is received - */ - public void onWarning(Consumer handler) { - this.warningHandler = handler; - } - - /** - * Registers a handler for ListenV2FatalError messages from the server. - * @param handler the handler to invoke when a message is received - */ - public void onErrorMessage(Consumer handler) { - this.errorHandler = handler; - } - - /** - * Registers a handler called when the connection is established. - * @param handler the handler to invoke when connected - */ - public void onConnected(Runnable handler) { - this.onConnectedHandler = handler; - } - - /** - * Registers a handler called when the connection is closed. - * @param handler the handler to invoke when disconnected - */ - public void onDisconnected(Consumer handler) { - this.onDisconnectedHandler = handler; - } - - /** - * Registers a handler called when an error occurs. - * @param handler the handler to invoke on error - */ - public void onError(Consumer handler) { - this.onErrorHandler = handler; - } - - /** - * Registers a handler called for every incoming text message. - * The handler receives the raw JSON string before type-specific dispatch. - * @param handler the handler to invoke with the raw message JSON - */ - public void onMessage(Consumer handler) { - this.onMessageHandler = handler; - } - - /** - * Configures reconnection behavior. Must be called before {@link #connect}. - * - * @param options the reconnection options (backoff, retries, queue size) - */ - public void reconnectOptions(ReconnectingWebSocketListener.ReconnectOptions options) { - this.reconnectOptions = options; - } - - /** - * Closes this WebSocket client, releasing all resources. - * Equivalent to calling {@link #disconnect()}. - */ - @Override - public void close() { - disconnect(); - } - - /** - * Ensures the WebSocket is connected and ready to send messages. - * @throws IllegalStateException if the socket is not connected or not open - */ - private void assertSocketIsOpen() { - if (reconnectingListener.getWebSocket() == null) { - throw new IllegalStateException("WebSocket is not connected. Call connect() first."); - } - if (readyState != WebSocketReadyState.OPEN) { - throw new IllegalStateException("WebSocket is not open. Current state: " + readyState); - } - } - - private CompletableFuture sendMessage(Object body) { - return sendMessage(body, null); - } - - private CompletableFuture sendMessage(Object body, Consumer onSent) { - CompletableFuture future = new CompletableFuture<>(); - try { - assertSocketIsOpen(); - String json = objectMapper.writeValueAsString(body); - // Use reconnecting listener's send method which handles queuing - reconnectingListener.send(json, onSent); - future.complete(null); - } catch (IllegalStateException e) { - future.completeExceptionally(e); - } catch (Exception e) { - future.completeExceptionally(new RuntimeException("Failed to send message", e)); - } - return future; - } - - private void handleIncomingMessage(String json) { - try { - if (onMessageHandler != null) { - onMessageHandler.accept(json); - } - JsonNode node = objectMapper.readTree(json); - if (node == null || node.isNull()) { - throw new IllegalArgumentException("Received null or invalid JSON message"); - } - if (node.has("request_id") - && node.has("sequence_id") - && node.has("event") - && node.has("turn_index") - && node.has("audio_window_start") - && node.has("audio_window_end") - && node.has("transcript") - && node.has("words") - && node.has("end_of_turn_confidence") - && "TurnInfo".equals(node.path("type").asText())) { - ListenV2TurnInfo turnInfoHandlerEvent = null; - try { - turnInfoHandlerEvent = objectMapper.treeToValue(node, ListenV2TurnInfo.class); - } catch (Exception e) { - } - if (turnInfoHandlerEvent != null) { - if (turnInfoHandler != null) { - turnInfoHandler.accept(turnInfoHandlerEvent); - } - return; - } - } - if (node.has("request_id") - && node.has("thresholds") - && node.has("keyterms") - && node.has("sequence_id") - && "ConfigureSuccess".equals(node.path("type").asText())) { - ListenV2ConfigureSuccess configureSuccessHandlerEvent = null; - try { - configureSuccessHandlerEvent = objectMapper.treeToValue(node, ListenV2ConfigureSuccess.class); - } catch (Exception e) { - } - if (configureSuccessHandlerEvent != null) { - if (configureSuccessHandler != null) { - configureSuccessHandler.accept(configureSuccessHandlerEvent); - } - return; - } - } - if (node.has("request_id") - && node.has("sequence_id") - && node.has("code") - && node.has("description") - && "Warning".equals(node.path("type").asText())) { - ListenV2Warning warningHandlerEvent = null; - try { - warningHandlerEvent = objectMapper.treeToValue(node, ListenV2Warning.class); - } catch (Exception e) { - } - if (warningHandlerEvent != null) { - if (warningHandler != null) { - warningHandler.accept(warningHandlerEvent); - } - return; - } - } - if (node.has("sequence_id") - && node.has("code") - && node.has("description") - && "Error".equals(node.path("type").asText())) { - ListenV2FatalError errorHandlerEvent = null; - try { - errorHandlerEvent = objectMapper.treeToValue(node, ListenV2FatalError.class); - } catch (Exception e) { - } - if (errorHandlerEvent != null) { - if (errorHandler != null) { - errorHandler.accept(errorHandlerEvent); - } - return; - } - } - if (node.has("request_id") - && node.has("sequence_id") - && "Connected".equals(node.path("type").asText())) { - ListenV2Connected connectedHandlerEvent = null; - try { - connectedHandlerEvent = objectMapper.treeToValue(node, ListenV2Connected.class); - } catch (Exception e) { - } - if (connectedHandlerEvent != null) { - if (connectedHandler != null) { - connectedHandler.accept(connectedHandlerEvent); - } - return; - } - } - if (node.has("request_id") - && node.has("sequence_id") - && "ConfigureFailure".equals(node.path("type").asText())) { - ListenV2ConfigureFailure configureFailureHandlerEvent = null; - try { - configureFailureHandlerEvent = objectMapper.treeToValue(node, ListenV2ConfigureFailure.class); - } catch (Exception e) { - } - if (configureFailureHandlerEvent != null) { - if (configureFailureHandler != null) { - configureFailureHandler.accept(configureFailureHandlerEvent); - } - return; - } - } - // The raw frame is already delivered to onMessage(String), so ignore unknown typed - // frames for forward compatibility with newly added server control messages. - } catch (Exception e) { - if (onErrorHandler != null) { - onErrorHandler.accept(e); - } - } - } -} diff --git a/src/main/java/com/deepgram/resources/speak/v1/websocket/V1WebSocketClient.java b/src/main/java/com/deepgram/resources/speak/v1/websocket/V1WebSocketClient.java index 6dd298a..e6824a3 100644 --- a/src/main/java/com/deepgram/resources/speak/v1/websocket/V1WebSocketClient.java +++ b/src/main/java/com/deepgram/resources/speak/v1/websocket/V1WebSocketClient.java @@ -6,6 +6,7 @@ import com.deepgram.core.ClientOptions; import com.deepgram.core.DisconnectReason; import com.deepgram.core.ObjectMappers; +import com.deepgram.core.QueryStringMapper; import com.deepgram.core.ReconnectingWebSocketListener; import com.deepgram.core.RequestOptions; import com.deepgram.core.WebSocketReadyState; @@ -122,6 +123,13 @@ public CompletableFuture connect(V1ConnectOptions options) { urlBuilder.addQueryParameter( "speed", String.valueOf(options.getSpeed().get())); } + if (options.getAdditionalProperties() != null) { + options.getAdditionalProperties().forEach((key, value) -> { + if (value != null) { + QueryStringMapper.addQueryParameter(urlBuilder, key, value, true); + } + }); + } Request.Builder requestBuilder = new Request.Builder().url(urlBuilder.build()); clientOptions.headers((RequestOptions) null).forEach(requestBuilder::addHeader); final Request request = requestBuilder.build(); diff --git a/src/main/java/com/deepgram/resources/speak/v1/websocket/V1WebSocketClient.java.bak b/src/main/java/com/deepgram/resources/speak/v1/websocket/V1WebSocketClient.java.bak deleted file mode 100644 index e6824a3..0000000 --- a/src/main/java/com/deepgram/resources/speak/v1/websocket/V1WebSocketClient.java.bak +++ /dev/null @@ -1,467 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.resources.speak.v1.websocket; - -import com.deepgram.core.ClientOptions; -import com.deepgram.core.DisconnectReason; -import com.deepgram.core.ObjectMappers; -import com.deepgram.core.QueryStringMapper; -import com.deepgram.core.ReconnectingWebSocketListener; -import com.deepgram.core.RequestOptions; -import com.deepgram.core.WebSocketReadyState; -import com.deepgram.resources.speak.v1.types.SpeakV1Clear; -import com.deepgram.resources.speak.v1.types.SpeakV1Cleared; -import com.deepgram.resources.speak.v1.types.SpeakV1Close; -import com.deepgram.resources.speak.v1.types.SpeakV1Flush; -import com.deepgram.resources.speak.v1.types.SpeakV1Flushed; -import com.deepgram.resources.speak.v1.types.SpeakV1Metadata; -import com.deepgram.resources.speak.v1.types.SpeakV1Text; -import com.deepgram.resources.speak.v1.types.SpeakV1Warning; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ScheduledExecutorService; -import java.util.function.Consumer; -import okhttp3.HttpUrl; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; -import okhttp3.WebSocket; -import okio.ByteString; - -/** - * WebSocket client for the v1 channel. - * Provides real-time bidirectional communication with strongly-typed messages. - */ -public class V1WebSocketClient implements AutoCloseable { - protected final ClientOptions clientOptions; - - private final ObjectMapper objectMapper; - - private final OkHttpClient okHttpClient; - - private ScheduledExecutorService timeoutExecutor; - - private volatile WebSocketReadyState readyState = WebSocketReadyState.CLOSED; - - private volatile Runnable onConnectedHandler; - - private volatile Consumer onDisconnectedHandler; - - private volatile Consumer onErrorHandler; - - private volatile Consumer onMessageHandler; - - private volatile ReconnectingWebSocketListener.ReconnectOptions reconnectOptions; - - private CompletableFuture connectionFuture; - - private ReconnectingWebSocketListener reconnectingListener; - - private volatile Consumer speakV1AudioHandler; - - private volatile Consumer metadataHandler; - - private volatile Consumer flushedHandler; - - private volatile Consumer clearedHandler; - - private volatile Consumer warningHandler; - - /** - * Creates a new async WebSocket client for the v1 channel. - */ - public V1WebSocketClient(ClientOptions clientOptions) { - this.clientOptions = clientOptions; - this.objectMapper = ObjectMappers.JSON_MAPPER; - this.okHttpClient = clientOptions.httpClient(); - } - - /** - * Establishes the WebSocket connection asynchronously with automatic reconnection. - * @return a CompletableFuture that completes when the connection is established - * @param options connection options including query parameters - */ - public CompletableFuture connect(V1ConnectOptions options) { - connectionFuture = new CompletableFuture<>(); - String baseUrl = clientOptions.environment().getProductionURL(); - String fullPath = "/v1/speak"; - if (baseUrl.endsWith("/") && fullPath.startsWith("/")) { - fullPath = fullPath.substring(1); - } else if (!baseUrl.endsWith("/") && !fullPath.startsWith("/")) { - fullPath = "/" + fullPath; - } - // OkHttp's HttpUrl only supports http/https schemes; convert wss/ws for URL parsing - if (baseUrl.startsWith("wss://")) { - baseUrl = "https://" + baseUrl.substring(6); - } else if (baseUrl.startsWith("ws://")) { - baseUrl = "http://" + baseUrl.substring(5); - } - HttpUrl parsedUrl = HttpUrl.parse(baseUrl + fullPath); - if (parsedUrl == null) { - throw new IllegalArgumentException("Invalid WebSocket URL: " + baseUrl + fullPath); - } - HttpUrl.Builder urlBuilder = parsedUrl.newBuilder(); - if (options.getEncoding() != null && options.getEncoding().isPresent()) { - urlBuilder.addQueryParameter( - "encoding", String.valueOf(options.getEncoding().get())); - } - if (options.getMipOptOut() != null && options.getMipOptOut().isPresent()) { - urlBuilder.addQueryParameter( - "mip_opt_out", String.valueOf(options.getMipOptOut().get())); - } - if (options.getModel() != null && options.getModel().isPresent()) { - urlBuilder.addQueryParameter( - "model", String.valueOf(options.getModel().get())); - } - if (options.getSampleRate() != null && options.getSampleRate().isPresent()) { - urlBuilder.addQueryParameter( - "sample_rate", String.valueOf(options.getSampleRate().get())); - } - if (options.getSpeed() != null && options.getSpeed().isPresent()) { - urlBuilder.addQueryParameter( - "speed", String.valueOf(options.getSpeed().get())); - } - if (options.getAdditionalProperties() != null) { - options.getAdditionalProperties().forEach((key, value) -> { - if (value != null) { - QueryStringMapper.addQueryParameter(urlBuilder, key, value, true); - } - }); - } - Request.Builder requestBuilder = new Request.Builder().url(urlBuilder.build()); - clientOptions.headers((RequestOptions) null).forEach(requestBuilder::addHeader); - final Request request = requestBuilder.build(); - this.readyState = WebSocketReadyState.CONNECTING; - ReconnectingWebSocketListener.ReconnectOptions reconnectOpts = this.reconnectOptions != null - ? this.reconnectOptions - : ReconnectingWebSocketListener.ReconnectOptions.builder().build(); - this.reconnectingListener = - new ReconnectingWebSocketListener( - reconnectOpts, - () -> { - if (clientOptions.isClosed()) { - throw new IllegalStateException("root client has been closed"); - } - if (clientOptions.webSocketFactory().isPresent()) { - return clientOptions - .webSocketFactory() - .get() - .create(request, this.reconnectingListener); - } else { - return okHttpClient.newWebSocket(request, this.reconnectingListener); - } - }, - clientOptions::isClosed) { - @Override - protected void onWebSocketOpen(WebSocket webSocket, Response response) { - readyState = WebSocketReadyState.OPEN; - if (onConnectedHandler != null) { - onConnectedHandler.run(); - } - connectionFuture.complete(null); - } - - @Override - protected void onWebSocketMessage(WebSocket webSocket, String text) { - handleIncomingMessage(text); - } - - @Override - protected void onWebSocketBinaryMessage(WebSocket webSocket, ByteString bytes) { - if (speakV1AudioHandler != null) { - speakV1AudioHandler.accept(bytes); - } - } - - @Override - protected void onWebSocketFailure(WebSocket webSocket, Throwable t, Response response) { - readyState = WebSocketReadyState.CLOSED; - if (onErrorHandler != null) { - onErrorHandler.accept(new RuntimeException(t)); - } - connectionFuture.completeExceptionally(t); - } - - @Override - protected void onWebSocketClosed(WebSocket webSocket, int code, String reason) { - readyState = WebSocketReadyState.CLOSED; - if (onDisconnectedHandler != null) { - onDisconnectedHandler.accept(new DisconnectReason(code, reason)); - } - } - }; - clientOptions.registerWebSocket(this); - reconnectingListener.connect(); - return connectionFuture; - } - - /** - * Establishes the WebSocket connection asynchronously with default options. - * @return a CompletableFuture that completes when the connection is established - */ - public CompletableFuture connect() { - return connect(V1ConnectOptions.builder().build()); - } - - /** - * Disconnects the WebSocket connection and releases resources. - */ - public void disconnect() { - clientOptions.unregisterWebSocket(this); - if (reconnectingListener != null) { - reconnectingListener.disconnect(); - } - if (timeoutExecutor != null) { - timeoutExecutor.shutdownNow(); - timeoutExecutor = null; - } - } - - /** - * Gets the current state of the WebSocket connection. - * - * This provides the actual connection state, similar to the W3C WebSocket API. - * - * @return the current WebSocket ready state - */ - public WebSocketReadyState getReadyState() { - return readyState; - } - - /** - * Sends a SpeakV1Text message to the server asynchronously. - * @param message the message to send - * @return a CompletableFuture that completes when the message is sent - */ - public CompletableFuture sendText(SpeakV1Text message) { - return sendMessage(message); - } - - /** - * Sends a SpeakV1Flush message to the server asynchronously. - * @param message the message to send - * @return a CompletableFuture that completes when the message is sent - */ - public CompletableFuture sendFlush(SpeakV1Flush message) { - return sendMessage(message); - } - - /** - * Sends a SpeakV1Clear message to the server asynchronously. - * @param message the message to send - * @return a CompletableFuture that completes when the message is sent - */ - public CompletableFuture sendClear(SpeakV1Clear message) { - return sendMessage(message); - } - - /** - * Sends a SpeakV1Close message to the server asynchronously. - * @param message the message to send - * @return a CompletableFuture that completes when the message is sent - */ - public CompletableFuture sendClose(SpeakV1Close message) { - return sendMessage(message); - } - - /** - * Registers a handler for SpeakV1Audio messages from the server. - * @param handler the handler to invoke when a message is received - */ - public void onSpeakV1Audio(Consumer handler) { - this.speakV1AudioHandler = handler; - } - - /** - * Registers a handler for SpeakV1Metadata messages from the server. - * @param handler the handler to invoke when a message is received - */ - public void onMetadata(Consumer handler) { - this.metadataHandler = handler; - } - - /** - * Registers a handler for SpeakV1Flushed messages from the server. - * @param handler the handler to invoke when a message is received - */ - public void onFlushed(Consumer handler) { - this.flushedHandler = handler; - } - - /** - * Registers a handler for SpeakV1Cleared messages from the server. - * @param handler the handler to invoke when a message is received - */ - public void onCleared(Consumer handler) { - this.clearedHandler = handler; - } - - /** - * Registers a handler for SpeakV1Warning messages from the server. - * @param handler the handler to invoke when a message is received - */ - public void onWarning(Consumer handler) { - this.warningHandler = handler; - } - - /** - * Registers a handler called when the connection is established. - * @param handler the handler to invoke when connected - */ - public void onConnected(Runnable handler) { - this.onConnectedHandler = handler; - } - - /** - * Registers a handler called when the connection is closed. - * @param handler the handler to invoke when disconnected - */ - public void onDisconnected(Consumer handler) { - this.onDisconnectedHandler = handler; - } - - /** - * Registers a handler called when an error occurs. - * @param handler the handler to invoke on error - */ - public void onError(Consumer handler) { - this.onErrorHandler = handler; - } - - /** - * Registers a handler called for every incoming text message. - * The handler receives the raw JSON string before type-specific dispatch. - * @param handler the handler to invoke with the raw message JSON - */ - public void onMessage(Consumer handler) { - this.onMessageHandler = handler; - } - - /** - * Configures reconnection behavior. Must be called before {@link #connect}. - * - * @param options the reconnection options (backoff, retries, queue size) - */ - public void reconnectOptions(ReconnectingWebSocketListener.ReconnectOptions options) { - this.reconnectOptions = options; - } - - /** - * Closes this WebSocket client, releasing all resources. - * Equivalent to calling {@link #disconnect()}. - */ - @Override - public void close() { - disconnect(); - } - - /** - * Ensures the WebSocket is connected and ready to send messages. - * @throws IllegalStateException if the socket is not connected or not open - */ - private void assertSocketIsOpen() { - if (reconnectingListener.getWebSocket() == null) { - throw new IllegalStateException("WebSocket is not connected. Call connect() first."); - } - if (readyState != WebSocketReadyState.OPEN) { - throw new IllegalStateException("WebSocket is not open. Current state: " + readyState); - } - } - - private CompletableFuture sendMessage(Object body) { - CompletableFuture future = new CompletableFuture<>(); - try { - assertSocketIsOpen(); - String json = objectMapper.writeValueAsString(body); - // Use reconnecting listener's send method which handles queuing - reconnectingListener.send(json); - future.complete(null); - } catch (IllegalStateException e) { - future.completeExceptionally(e); - } catch (Exception e) { - future.completeExceptionally(new RuntimeException("Failed to send message", e)); - } - return future; - } - - private void handleIncomingMessage(String json) { - try { - if (onMessageHandler != null) { - onMessageHandler.accept(json); - } - JsonNode node = objectMapper.readTree(json); - if (node == null || node.isNull()) { - throw new IllegalArgumentException("Received null or invalid JSON message"); - } - if (node.has("request_id") - && node.has("model_name") - && node.has("model_version") - && node.has("model_uuid") - && "Metadata".equals(node.path("type").asText())) { - SpeakV1Metadata metadataHandlerEvent = null; - try { - metadataHandlerEvent = objectMapper.treeToValue(node, SpeakV1Metadata.class); - } catch (Exception e) { - } - if (metadataHandlerEvent != null) { - if (metadataHandler != null) { - metadataHandler.accept(metadataHandlerEvent); - } - return; - } - } - if (node.has("description") - && node.has("code") - && "Warning".equals(node.path("type").asText())) { - SpeakV1Warning warningHandlerEvent = null; - try { - warningHandlerEvent = objectMapper.treeToValue(node, SpeakV1Warning.class); - } catch (Exception e) { - } - if (warningHandlerEvent != null) { - if (warningHandler != null) { - warningHandler.accept(warningHandlerEvent); - } - return; - } - } - if (node.has("type") && node.has("sequence_id")) { - SpeakV1Flushed flushedHandlerEvent = null; - try { - flushedHandlerEvent = objectMapper.treeToValue(node, SpeakV1Flushed.class); - } catch (Exception e) { - } - if (flushedHandlerEvent != null) { - if (flushedHandler != null) { - flushedHandler.accept(flushedHandlerEvent); - } - return; - } - } - if (node.has("type") && node.has("sequence_id")) { - SpeakV1Cleared clearedHandlerEvent = null; - try { - clearedHandlerEvent = objectMapper.treeToValue(node, SpeakV1Cleared.class); - } catch (Exception e) { - } - if (clearedHandlerEvent != null) { - if (clearedHandler != null) { - clearedHandler.accept(clearedHandlerEvent); - } - return; - } - } - if (onErrorHandler != null) { - onErrorHandler.accept(new RuntimeException( - "Unrecognized WebSocket message: " + json.substring(0, Math.min(200, json.length())) - + "... Update your SDK version to support new message types.")); - } - } catch (Exception e) { - if (onErrorHandler != null) { - onErrorHandler.accept(e); - } - } - } -} diff --git a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Close.java b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Close.java index 2e96a5c..7fecd79 100644 --- a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Close.java +++ b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Close.java @@ -36,6 +36,11 @@ public boolean equals(Object other) { return other instanceof SpeakV2Close; } + @java.lang.Override + public int hashCode() { + return getClass().hashCode(); + } + @JsonAnyGetter public Map getAdditionalProperties() { return this.additionalProperties; diff --git a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Close.java.bak b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Close.java.bak deleted file mode 100644 index 7fecd79..0000000 --- a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Close.java.bak +++ /dev/null @@ -1,83 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.resources.speak.v2.types; - -import com.deepgram.core.ObjectMappers; -import com.fasterxml.jackson.annotation.JsonAnyGetter; -import com.fasterxml.jackson.annotation.JsonAnySetter; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import java.util.HashMap; -import java.util.Map; - -@JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = SpeakV2Close.Builder.class) -public final class SpeakV2Close { - private final Map additionalProperties; - - private SpeakV2Close(Map additionalProperties) { - this.additionalProperties = additionalProperties; - } - - /** - * @return Message type identifier - */ - @JsonProperty("type") - public String getType() { - return "Close"; - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof SpeakV2Close; - } - - @java.lang.Override - public int hashCode() { - return getClass().hashCode(); - } - - @JsonAnyGetter - public Map getAdditionalProperties() { - return this.additionalProperties; - } - - @java.lang.Override - public String toString() { - return ObjectMappers.stringify(this); - } - - public static Builder builder() { - return new Builder(); - } - - @JsonIgnoreProperties(ignoreUnknown = true) - public static final class Builder { - @JsonAnySetter - private Map additionalProperties = new HashMap<>(); - - private Builder() {} - - public Builder from(SpeakV2Close other) { - return this; - } - - public SpeakV2Close build() { - return new SpeakV2Close(additionalProperties); - } - - public Builder additionalProperty(String key, Object value) { - this.additionalProperties.put(key, value); - return this; - } - - public Builder additionalProperties(Map additionalProperties) { - this.additionalProperties.putAll(additionalProperties); - return this; - } - } -} diff --git a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2ConfigureFailureCode.java b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2ConfigureFailureCode.java index 63ec45a..f678e97 100644 --- a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2ConfigureFailureCode.java +++ b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2ConfigureFailureCode.java @@ -110,7 +110,9 @@ public interface Visitor { T visitSpeedNotSupported(); - T visitControlCombinationInvalid(); + default T visitControlCombinationInvalid() { + return visitUnknown("CONTROL_COMBINATION_INVALID"); + } T visitInternalError(); diff --git a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Flush.java b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Flush.java index acd717d..130da0d 100644 --- a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Flush.java +++ b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Flush.java @@ -36,6 +36,11 @@ public boolean equals(Object other) { return other instanceof SpeakV2Flush; } + @java.lang.Override + public int hashCode() { + return getClass().hashCode(); + } + @JsonAnyGetter public Map getAdditionalProperties() { return this.additionalProperties; diff --git a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Flush.java.bak b/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Flush.java.bak deleted file mode 100644 index 130da0d..0000000 --- a/src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Flush.java.bak +++ /dev/null @@ -1,83 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.resources.speak.v2.types; - -import com.deepgram.core.ObjectMappers; -import com.fasterxml.jackson.annotation.JsonAnyGetter; -import com.fasterxml.jackson.annotation.JsonAnySetter; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import java.util.HashMap; -import java.util.Map; - -@JsonInclude(JsonInclude.Include.NON_ABSENT) -@JsonDeserialize(builder = SpeakV2Flush.Builder.class) -public final class SpeakV2Flush { - private final Map additionalProperties; - - private SpeakV2Flush(Map additionalProperties) { - this.additionalProperties = additionalProperties; - } - - /** - * @return Message type identifier - */ - @JsonProperty("type") - public String getType() { - return "Flush"; - } - - @java.lang.Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof SpeakV2Flush; - } - - @java.lang.Override - public int hashCode() { - return getClass().hashCode(); - } - - @JsonAnyGetter - public Map getAdditionalProperties() { - return this.additionalProperties; - } - - @java.lang.Override - public String toString() { - return ObjectMappers.stringify(this); - } - - public static Builder builder() { - return new Builder(); - } - - @JsonIgnoreProperties(ignoreUnknown = true) - public static final class Builder { - @JsonAnySetter - private Map additionalProperties = new HashMap<>(); - - private Builder() {} - - public Builder from(SpeakV2Flush other) { - return this; - } - - public SpeakV2Flush build() { - return new SpeakV2Flush(additionalProperties); - } - - public Builder additionalProperty(String key, Object value) { - this.additionalProperties.put(key, value); - return this; - } - - public Builder additionalProperties(Map additionalProperties) { - this.additionalProperties.putAll(additionalProperties); - return this; - } - } -} diff --git a/src/main/java/com/deepgram/resources/speak/v2/websocket/V2WebSocketClient.java b/src/main/java/com/deepgram/resources/speak/v2/websocket/V2WebSocketClient.java index 07f6c36..b4e01f7 100644 --- a/src/main/java/com/deepgram/resources/speak/v2/websocket/V2WebSocketClient.java +++ b/src/main/java/com/deepgram/resources/speak/v2/websocket/V2WebSocketClient.java @@ -6,6 +6,7 @@ import com.deepgram.core.ClientOptions; import com.deepgram.core.DisconnectReason; import com.deepgram.core.ObjectMappers; +import com.deepgram.core.QueryStringMapper; import com.deepgram.core.ReconnectingWebSocketListener; import com.deepgram.core.RequestOptions; import com.deepgram.core.WebSocketReadyState; @@ -143,7 +144,14 @@ public CompletableFuture connect(V2ConnectOptions options) { "mip_opt_out", String.valueOf(options.getMipOptOut().get())); } if (options.getTag() != null && options.getTag().isPresent()) { - urlBuilder.addQueryParameter("tag", String.valueOf(options.getTag().get())); + QueryStringMapper.addQueryParameter(urlBuilder, "tag", options.getTag().get().get(), true); + } + if (options.getAdditionalProperties() != null) { + options.getAdditionalProperties().forEach((key, value) -> { + if (value != null) { + QueryStringMapper.addQueryParameter(urlBuilder, key, value, true); + } + }); } Request.Builder requestBuilder = new Request.Builder().url(urlBuilder.build()); clientOptions.headers((RequestOptions) null).forEach(requestBuilder::addHeader); @@ -611,11 +619,8 @@ private void handleIncomingMessage(String json) { return; } } - if (onErrorHandler != null) { - onErrorHandler.accept(new RuntimeException( - "Unrecognized WebSocket message: " + json.substring(0, Math.min(200, json.length())) - + "... Update your SDK version to support new message types.")); - } + // The raw frame is already delivered to onMessage(String), so ignore unknown typed + // frames for forward compatibility with newly added server control messages. } catch (Exception e) { if (onErrorHandler != null) { onErrorHandler.accept(e); diff --git a/src/main/java/com/deepgram/resources/speak/v2/websocket/V2WebSocketClient.java.bak b/src/main/java/com/deepgram/resources/speak/v2/websocket/V2WebSocketClient.java.bak deleted file mode 100644 index b4e01f7..0000000 --- a/src/main/java/com/deepgram/resources/speak/v2/websocket/V2WebSocketClient.java.bak +++ /dev/null @@ -1,630 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.resources.speak.v2.websocket; - -import com.deepgram.core.ClientOptions; -import com.deepgram.core.DisconnectReason; -import com.deepgram.core.ObjectMappers; -import com.deepgram.core.QueryStringMapper; -import com.deepgram.core.ReconnectingWebSocketListener; -import com.deepgram.core.RequestOptions; -import com.deepgram.core.WebSocketReadyState; -import com.deepgram.resources.speak.v2.types.SpeakV2Close; -import com.deepgram.resources.speak.v2.types.SpeakV2Configure; -import com.deepgram.resources.speak.v2.types.SpeakV2ConfigureFailure; -import com.deepgram.resources.speak.v2.types.SpeakV2ConfigureSuccess; -import com.deepgram.resources.speak.v2.types.SpeakV2Connected; -import com.deepgram.resources.speak.v2.types.SpeakV2Error; -import com.deepgram.resources.speak.v2.types.SpeakV2Flush; -import com.deepgram.resources.speak.v2.types.SpeakV2Flushed; -import com.deepgram.resources.speak.v2.types.SpeakV2Interrupt; -import com.deepgram.resources.speak.v2.types.SpeakV2SessionMetadata; -import com.deepgram.resources.speak.v2.types.SpeakV2Speak; -import com.deepgram.resources.speak.v2.types.SpeakV2SpeechInterrupted; -import com.deepgram.resources.speak.v2.types.SpeakV2SpeechMetadata; -import com.deepgram.resources.speak.v2.types.SpeakV2SpeechStarted; -import com.deepgram.resources.speak.v2.types.SpeakV2Warning; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ScheduledExecutorService; -import java.util.function.Consumer; -import okhttp3.HttpUrl; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; -import okhttp3.WebSocket; -import okio.ByteString; - -/** - * WebSocket client for the v2 channel. - * Provides real-time bidirectional communication with strongly-typed messages. - */ -public class V2WebSocketClient implements AutoCloseable { - protected final ClientOptions clientOptions; - - private final ObjectMapper objectMapper; - - private final OkHttpClient okHttpClient; - - private ScheduledExecutorService timeoutExecutor; - - private volatile WebSocketReadyState readyState = WebSocketReadyState.CLOSED; - - private volatile Runnable onConnectedHandler; - - private volatile Consumer onDisconnectedHandler; - - private volatile Consumer onErrorHandler; - - private volatile Consumer onMessageHandler; - - private volatile ReconnectingWebSocketListener.ReconnectOptions reconnectOptions; - - private CompletableFuture connectionFuture; - - private ReconnectingWebSocketListener reconnectingListener; - - private volatile Consumer speakV2AudioHandler; - - private volatile Consumer connectedHandler; - - private volatile Consumer speechStartedHandler; - - private volatile Consumer speechMetadataHandler; - - private volatile Consumer speechInterruptedHandler; - - private volatile Consumer flushedHandler; - - private volatile Consumer sessionMetadataHandler; - - private volatile Consumer configureSuccessHandler; - - private volatile Consumer configureFailureHandler; - - private volatile Consumer warningHandler; - - private volatile Consumer errorHandler; - - /** - * Creates a new async WebSocket client for the v2 channel. - */ - public V2WebSocketClient(ClientOptions clientOptions) { - this.clientOptions = clientOptions; - this.objectMapper = ObjectMappers.JSON_MAPPER; - this.okHttpClient = clientOptions.httpClient(); - } - - /** - * Establishes the WebSocket connection asynchronously with automatic reconnection. - * @return a CompletableFuture that completes when the connection is established - * @param options connection options including query parameters - */ - public CompletableFuture connect(V2ConnectOptions options) { - connectionFuture = new CompletableFuture<>(); - String baseUrl = clientOptions.environment().getProductionURL(); - String fullPath = "/v2/speak"; - if (baseUrl.endsWith("/") && fullPath.startsWith("/")) { - fullPath = fullPath.substring(1); - } else if (!baseUrl.endsWith("/") && !fullPath.startsWith("/")) { - fullPath = "/" + fullPath; - } - // OkHttp's HttpUrl only supports http/https schemes; convert wss/ws for URL parsing - if (baseUrl.startsWith("wss://")) { - baseUrl = "https://" + baseUrl.substring(6); - } else if (baseUrl.startsWith("ws://")) { - baseUrl = "http://" + baseUrl.substring(5); - } - HttpUrl parsedUrl = HttpUrl.parse(baseUrl + fullPath); - if (parsedUrl == null) { - throw new IllegalArgumentException("Invalid WebSocket URL: " + baseUrl + fullPath); - } - HttpUrl.Builder urlBuilder = parsedUrl.newBuilder(); - urlBuilder.addQueryParameter("model", String.valueOf(options.getModel())); - if (options.getEncoding() != null && options.getEncoding().isPresent()) { - urlBuilder.addQueryParameter( - "encoding", String.valueOf(options.getEncoding().get())); - } - if (options.getSampleRate() != null && options.getSampleRate().isPresent()) { - urlBuilder.addQueryParameter( - "sample_rate", String.valueOf(options.getSampleRate().get())); - } - if (options.getSpeed() != null && options.getSpeed().isPresent()) { - urlBuilder.addQueryParameter( - "speed", String.valueOf(options.getSpeed().get())); - } - if (options.getExpressivity() != null && options.getExpressivity().isPresent()) { - urlBuilder.addQueryParameter( - "expressivity", String.valueOf(options.getExpressivity().get())); - } - if (options.getMipOptOut() != null && options.getMipOptOut().isPresent()) { - urlBuilder.addQueryParameter( - "mip_opt_out", String.valueOf(options.getMipOptOut().get())); - } - if (options.getTag() != null && options.getTag().isPresent()) { - QueryStringMapper.addQueryParameter(urlBuilder, "tag", options.getTag().get().get(), true); - } - if (options.getAdditionalProperties() != null) { - options.getAdditionalProperties().forEach((key, value) -> { - if (value != null) { - QueryStringMapper.addQueryParameter(urlBuilder, key, value, true); - } - }); - } - Request.Builder requestBuilder = new Request.Builder().url(urlBuilder.build()); - clientOptions.headers((RequestOptions) null).forEach(requestBuilder::addHeader); - final Request request = requestBuilder.build(); - this.readyState = WebSocketReadyState.CONNECTING; - ReconnectingWebSocketListener.ReconnectOptions reconnectOpts = this.reconnectOptions != null - ? this.reconnectOptions - : ReconnectingWebSocketListener.ReconnectOptions.builder().build(); - this.reconnectingListener = - new ReconnectingWebSocketListener( - reconnectOpts, - () -> { - if (clientOptions.isClosed()) { - throw new IllegalStateException("root client has been closed"); - } - if (clientOptions.webSocketFactory().isPresent()) { - return clientOptions - .webSocketFactory() - .get() - .create(request, this.reconnectingListener); - } else { - return okHttpClient.newWebSocket(request, this.reconnectingListener); - } - }, - clientOptions::isClosed) { - @Override - protected void onWebSocketOpen(WebSocket webSocket, Response response) { - readyState = WebSocketReadyState.OPEN; - if (onConnectedHandler != null) { - onConnectedHandler.run(); - } - connectionFuture.complete(null); - } - - @Override - protected void onWebSocketMessage(WebSocket webSocket, String text) { - handleIncomingMessage(text); - } - - @Override - protected void onWebSocketBinaryMessage(WebSocket webSocket, ByteString bytes) { - if (speakV2AudioHandler != null) { - speakV2AudioHandler.accept(bytes); - } - } - - @Override - protected void onWebSocketFailure(WebSocket webSocket, Throwable t, Response response) { - readyState = WebSocketReadyState.CLOSED; - if (onErrorHandler != null) { - onErrorHandler.accept(new RuntimeException(t)); - } - connectionFuture.completeExceptionally(t); - } - - @Override - protected void onWebSocketClosed(WebSocket webSocket, int code, String reason) { - readyState = WebSocketReadyState.CLOSED; - if (onDisconnectedHandler != null) { - onDisconnectedHandler.accept(new DisconnectReason(code, reason)); - } - } - }; - clientOptions.registerWebSocket(this); - reconnectingListener.connect(); - return connectionFuture; - } - - /** - * Disconnects the WebSocket connection and releases resources. - */ - public void disconnect() { - clientOptions.unregisterWebSocket(this); - if (reconnectingListener != null) { - reconnectingListener.disconnect(); - } - if (timeoutExecutor != null) { - timeoutExecutor.shutdownNow(); - timeoutExecutor = null; - } - } - - /** - * Gets the current state of the WebSocket connection. - * - * This provides the actual connection state, similar to the W3C WebSocket API. - * - * @return the current WebSocket ready state - */ - public WebSocketReadyState getReadyState() { - return readyState; - } - - /** - * Sends a SpeakV2Speak message to the server asynchronously. - * @param message the message to send - * @return a CompletableFuture that completes when the message is sent - */ - public CompletableFuture sendSpeak(SpeakV2Speak message) { - return sendMessage(message); - } - - /** - * Sends a SpeakV2Flush message to the server asynchronously. - * @param message the message to send - * @return a CompletableFuture that completes when the message is sent - */ - public CompletableFuture sendFlush(SpeakV2Flush message) { - return sendMessage(message); - } - - /** - * Sends a SpeakV2Interrupt message to the server asynchronously. - * @param message the message to send - * @return a CompletableFuture that completes when the message is sent - */ - public CompletableFuture sendInterrupt(SpeakV2Interrupt message) { - return sendMessage(message); - } - - /** - * Sends a SpeakV2Configure message to the server asynchronously. - * @param message the message to send - * @return a CompletableFuture that completes when the message is sent - */ - public CompletableFuture sendConfigure(SpeakV2Configure message) { - return sendMessage(message); - } - - /** - * Sends a SpeakV2Close message to the server asynchronously. - * @param message the message to send - * @return a CompletableFuture that completes when the message is sent - */ - public CompletableFuture sendClose(SpeakV2Close message) { - return sendMessage(message); - } - - /** - * Registers a handler for SpeakV2Audio messages from the server. - * @param handler the handler to invoke when a message is received - */ - public void onSpeakV2Audio(Consumer handler) { - this.speakV2AudioHandler = handler; - } - - /** - * Registers a handler for SpeakV2Connected messages from the server. - * @param handler the handler to invoke when a message is received - */ - public void onConnected(Consumer handler) { - this.connectedHandler = handler; - } - - /** - * Registers a handler for SpeakV2SpeechStarted messages from the server. - * @param handler the handler to invoke when a message is received - */ - public void onSpeechStarted(Consumer handler) { - this.speechStartedHandler = handler; - } - - /** - * Registers a handler for SpeakV2SpeechMetadata messages from the server. - * @param handler the handler to invoke when a message is received - */ - public void onSpeechMetadata(Consumer handler) { - this.speechMetadataHandler = handler; - } - - /** - * Registers a handler for SpeakV2SpeechInterrupted messages from the server. - * @param handler the handler to invoke when a message is received - */ - public void onSpeechInterrupted(Consumer handler) { - this.speechInterruptedHandler = handler; - } - - /** - * Registers a handler for SpeakV2Flushed messages from the server. - * @param handler the handler to invoke when a message is received - */ - public void onFlushed(Consumer handler) { - this.flushedHandler = handler; - } - - /** - * Registers a handler for SpeakV2SessionMetadata messages from the server. - * @param handler the handler to invoke when a message is received - */ - public void onSessionMetadata(Consumer handler) { - this.sessionMetadataHandler = handler; - } - - /** - * Registers a handler for SpeakV2ConfigureSuccess messages from the server. - * @param handler the handler to invoke when a message is received - */ - public void onConfigureSuccess(Consumer handler) { - this.configureSuccessHandler = handler; - } - - /** - * Registers a handler for SpeakV2ConfigureFailure messages from the server. - * @param handler the handler to invoke when a message is received - */ - public void onConfigureFailure(Consumer handler) { - this.configureFailureHandler = handler; - } - - /** - * Registers a handler for SpeakV2Warning messages from the server. - * @param handler the handler to invoke when a message is received - */ - public void onWarning(Consumer handler) { - this.warningHandler = handler; - } - - /** - * Registers a handler for SpeakV2Error messages from the server. - * @param handler the handler to invoke when a message is received - */ - public void onErrorMessage(Consumer handler) { - this.errorHandler = handler; - } - - /** - * Registers a handler called when the connection is established. - * @param handler the handler to invoke when connected - */ - public void onConnected(Runnable handler) { - this.onConnectedHandler = handler; - } - - /** - * Registers a handler called when the connection is closed. - * @param handler the handler to invoke when disconnected - */ - public void onDisconnected(Consumer handler) { - this.onDisconnectedHandler = handler; - } - - /** - * Registers a handler called when an error occurs. - * @param handler the handler to invoke on error - */ - public void onError(Consumer handler) { - this.onErrorHandler = handler; - } - - /** - * Registers a handler called for every incoming text message. - * The handler receives the raw JSON string before type-specific dispatch. - * @param handler the handler to invoke with the raw message JSON - */ - public void onMessage(Consumer handler) { - this.onMessageHandler = handler; - } - - /** - * Configures reconnection behavior. Must be called before {@link #connect}. - * - * @param options the reconnection options (backoff, retries, queue size) - */ - public void reconnectOptions(ReconnectingWebSocketListener.ReconnectOptions options) { - this.reconnectOptions = options; - } - - /** - * Closes this WebSocket client, releasing all resources. - * Equivalent to calling {@link #disconnect()}. - */ - @Override - public void close() { - disconnect(); - } - - /** - * Ensures the WebSocket is connected and ready to send messages. - * @throws IllegalStateException if the socket is not connected or not open - */ - private void assertSocketIsOpen() { - if (reconnectingListener.getWebSocket() == null) { - throw new IllegalStateException("WebSocket is not connected. Call connect() first."); - } - if (readyState != WebSocketReadyState.OPEN) { - throw new IllegalStateException("WebSocket is not open. Current state: " + readyState); - } - } - - private CompletableFuture sendMessage(Object body) { - CompletableFuture future = new CompletableFuture<>(); - try { - assertSocketIsOpen(); - String json = objectMapper.writeValueAsString(body); - // Use reconnecting listener's send method which handles queuing - reconnectingListener.send(json); - future.complete(null); - } catch (IllegalStateException e) { - future.completeExceptionally(e); - } catch (Exception e) { - future.completeExceptionally(new RuntimeException("Failed to send message", e)); - } - return future; - } - - private void handleIncomingMessage(String json) { - try { - if (onMessageHandler != null) { - onMessageHandler.accept(json); - } - JsonNode node = objectMapper.readTree(json); - if (node == null || node.isNull()) { - throw new IllegalArgumentException("Received null or invalid JSON message"); - } - if (node.has("speech_id") - && node.has("audio_duration_ms") - && node.has("input_character_count") - && node.has("billable_character_count") - && node.has("controls_applied") - && "SpeechMetadata".equals(node.path("type").asText())) { - SpeakV2SpeechMetadata speechMetadataHandlerEvent = null; - try { - speechMetadataHandlerEvent = objectMapper.treeToValue(node, SpeakV2SpeechMetadata.class); - } catch (Exception e) { - } - if (speechMetadataHandlerEvent != null) { - if (speechMetadataHandler != null) { - speechMetadataHandler.accept(speechMetadataHandlerEvent); - } - return; - } - } - if (node.has("request_id") - && node.has("model_name") - && node.has("model_version") - && node.has("model_uuids") - && "Connected".equals(node.path("type").asText())) { - SpeakV2Connected connectedHandlerEvent = null; - try { - connectedHandlerEvent = objectMapper.treeToValue(node, SpeakV2Connected.class); - } catch (Exception e) { - } - if (connectedHandlerEvent != null) { - if (connectedHandler != null) { - connectedHandler.accept(connectedHandlerEvent); - } - return; - } - } - if (node.has("total_audio_duration_ms") - && node.has("total_input_character_count") - && node.has("total_billable_character_count") - && "SessionMetadata".equals(node.path("type").asText())) { - SpeakV2SessionMetadata sessionMetadataHandlerEvent = null; - try { - sessionMetadataHandlerEvent = objectMapper.treeToValue(node, SpeakV2SessionMetadata.class); - } catch (Exception e) { - } - if (sessionMetadataHandlerEvent != null) { - if (sessionMetadataHandler != null) { - sessionMetadataHandler.accept(sessionMetadataHandlerEvent); - } - return; - } - } - if (node.has("audio_played_ms") - && node.has("metadata") - && "SpeechInterrupted".equals(node.path("type").asText())) { - SpeakV2SpeechInterrupted speechInterruptedHandlerEvent = null; - try { - speechInterruptedHandlerEvent = objectMapper.treeToValue(node, SpeakV2SpeechInterrupted.class); - } catch (Exception e) { - } - if (speechInterruptedHandlerEvent != null) { - if (speechInterruptedHandler != null) { - speechInterruptedHandler.accept(speechInterruptedHandlerEvent); - } - return; - } - } - if (node.has("code") - && node.has("description") - && "ConfigureFailure".equals(node.path("type").asText())) { - SpeakV2ConfigureFailure configureFailureHandlerEvent = null; - try { - configureFailureHandlerEvent = objectMapper.treeToValue(node, SpeakV2ConfigureFailure.class); - } catch (Exception e) { - } - if (configureFailureHandlerEvent != null) { - if (configureFailureHandler != null) { - configureFailureHandler.accept(configureFailureHandlerEvent); - } - return; - } - } - if (node.has("code") - && node.has("description") - && "Warning".equals(node.path("type").asText())) { - SpeakV2Warning warningHandlerEvent = null; - try { - warningHandlerEvent = objectMapper.treeToValue(node, SpeakV2Warning.class); - } catch (Exception e) { - } - if (warningHandlerEvent != null) { - if (warningHandler != null) { - warningHandler.accept(warningHandlerEvent); - } - return; - } - } - if (node.has("code") - && node.has("description") - && "Error".equals(node.path("type").asText())) { - SpeakV2Error errorHandlerEvent = null; - try { - errorHandlerEvent = objectMapper.treeToValue(node, SpeakV2Error.class); - } catch (Exception e) { - } - if (errorHandlerEvent != null) { - if (errorHandler != null) { - errorHandler.accept(errorHandlerEvent); - } - return; - } - } - if (node.has("speech_id") - && "SpeechStarted".equals(node.path("type").asText())) { - SpeakV2SpeechStarted speechStartedHandlerEvent = null; - try { - speechStartedHandlerEvent = objectMapper.treeToValue(node, SpeakV2SpeechStarted.class); - } catch (Exception e) { - } - if (speechStartedHandlerEvent != null) { - if (speechStartedHandler != null) { - speechStartedHandler.accept(speechStartedHandlerEvent); - } - return; - } - } - if (node.has("speech_id") && "Flushed".equals(node.path("type").asText())) { - SpeakV2Flushed flushedHandlerEvent = null; - try { - flushedHandlerEvent = objectMapper.treeToValue(node, SpeakV2Flushed.class); - } catch (Exception e) { - } - if (flushedHandlerEvent != null) { - if (flushedHandler != null) { - flushedHandler.accept(flushedHandlerEvent); - } - return; - } - } - if (node.has("applied") - && "ConfigureSuccess".equals(node.path("type").asText())) { - SpeakV2ConfigureSuccess configureSuccessHandlerEvent = null; - try { - configureSuccessHandlerEvent = objectMapper.treeToValue(node, SpeakV2ConfigureSuccess.class); - } catch (Exception e) { - } - if (configureSuccessHandlerEvent != null) { - if (configureSuccessHandler != null) { - configureSuccessHandler.accept(configureSuccessHandlerEvent); - } - return; - } - } - // The raw frame is already delivered to onMessage(String), so ignore unknown typed - // frames for forward compatibility with newly added server control messages. - } catch (Exception e) { - if (onErrorHandler != null) { - onErrorHandler.accept(e); - } - } - } -} diff --git a/src/main/java/com/deepgram/types/DeepgramModel.java b/src/main/java/com/deepgram/types/DeepgramModel.java index fc7c08c..974c3fa 100644 --- a/src/main/java/com/deepgram/types/DeepgramModel.java +++ b/src/main/java/com/deepgram/types/DeepgramModel.java @@ -13,6 +13,10 @@ public final class DeepgramModel { public static final DeepgramModel FLUX_KELSEY_EN = new DeepgramModel(Value.FLUX_KELSEY_EN, "flux-kelsey-en"); + /** @deprecated This live voice is absent from the generated model catalog. */ + @Deprecated + public static final DeepgramModel FLUX_RENEE_EN = new DeepgramModel(Value.FLUX_RENEE_EN, "flux-renee-en"); + public static final DeepgramModel FLUX_SIENNA_EN = new DeepgramModel(Value.FLUX_SIENNA_EN, "flux-sienna-en"); public static final DeepgramModel AURA2HARMONIA_EN = @@ -251,6 +255,8 @@ public T visit(Visitor visitor) { return visitor.visitAura2HeraEn(); case FLUX_KELSEY_EN: return visitor.visitFluxKelseyEn(); + case FLUX_RENEE_EN: + return visitor.visitFluxReneeEn(); case FLUX_SIENNA_EN: return visitor.visitFluxSiennaEn(); case AURA2HARMONIA_EN: @@ -458,6 +464,8 @@ public static DeepgramModel valueOf(String value) { return AURA2HERA_EN; case "flux-kelsey-en": return FLUX_KELSEY_EN; + case "flux-renee-en": + return FLUX_RENEE_EN; case "flux-sienna-en": return FLUX_SIENNA_EN; case "aura-2-harmonia-en": @@ -820,6 +828,8 @@ public enum Value { FLUX_KELSEY_EN, + FLUX_RENEE_EN, + FLUX_KIT_EN, FLUX_MAEVE_EN, @@ -1022,6 +1032,10 @@ public interface Visitor { T visitFluxKelseyEn(); + /** @deprecated This live voice is absent from the generated model catalog. */ + @Deprecated + T visitFluxReneeEn(); + T visitFluxKitEn(); T visitFluxMaeveEn(); diff --git a/src/main/java/com/deepgram/types/DeepgramModel.java.bak b/src/main/java/com/deepgram/types/DeepgramModel.java.bak deleted file mode 100644 index 6444d7f..0000000 --- a/src/main/java/com/deepgram/types/DeepgramModel.java.bak +++ /dev/null @@ -1,1071 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ -package com.deepgram.types; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonValue; - -public final class DeepgramModel { - public static final DeepgramModel AURA2SIRIO_ES = new DeepgramModel(Value.AURA2SIRIO_ES, "aura-2-sirio-es"); - - public static final DeepgramModel AURA2HERA_EN = new DeepgramModel(Value.AURA2HERA_EN, "aura-2-hera-en"); - - public static final DeepgramModel FLUX_KELSEY_EN = new DeepgramModel(Value.FLUX_KELSEY_EN, "flux-kelsey-en"); - - public static final DeepgramModel FLUX_RENEE_EN = new DeepgramModel(Value.FLUX_RENEE_EN, "flux-renee-en"); - - public static final DeepgramModel FLUX_SIENNA_EN = new DeepgramModel(Value.FLUX_SIENNA_EN, "flux-sienna-en"); - - public static final DeepgramModel AURA2HARMONIA_EN = - new DeepgramModel(Value.AURA2HARMONIA_EN, "aura-2-harmonia-en"); - - public static final DeepgramModel AURA2CARINA_ES = new DeepgramModel(Value.AURA2CARINA_ES, "aura-2-carina-es"); - - public static final DeepgramModel FLUX_MEENA_EN = new DeepgramModel(Value.FLUX_MEENA_EN, "flux-meena-en"); - - public static final DeepgramModel FLUX_MEGHAN_EN = new DeepgramModel(Value.FLUX_MEGHAN_EN, "flux-meghan-en"); - - public static final DeepgramModel AURA_ZEUS_EN = new DeepgramModel(Value.AURA_ZEUS_EN, "aura-zeus-en"); - - public static final DeepgramModel AURA2HERMES_EN = new DeepgramModel(Value.AURA2HERMES_EN, "aura-2-hermes-en"); - - public static final DeepgramModel FLUX_CONOR_EN = new DeepgramModel(Value.FLUX_CONOR_EN, "flux-conor-en"); - - public static final DeepgramModel AURA2NEPTUNE_EN = new DeepgramModel(Value.AURA2NEPTUNE_EN, "aura-2-neptune-en"); - - public static final DeepgramModel FLUX_BROOKE_EN = new DeepgramModel(Value.FLUX_BROOKE_EN, "flux-brooke-en"); - - public static final DeepgramModel FLUX_RUFUS_EN = new DeepgramModel(Value.FLUX_RUFUS_EN, "flux-rufus-en"); - - public static final DeepgramModel FLUX_WES_EN = new DeepgramModel(Value.FLUX_WES_EN, "flux-wes-en"); - - public static final DeepgramModel AURA2CALLISTA_EN = - new DeepgramModel(Value.AURA2CALLISTA_EN, "aura-2-callista-en"); - - public static final DeepgramModel AURA2AURORA_EN = new DeepgramModel(Value.AURA2AURORA_EN, "aura-2-aurora-en"); - - public static final DeepgramModel AURA2OPHELIA_EN = new DeepgramModel(Value.AURA2OPHELIA_EN, "aura-2-ophelia-en"); - - public static final DeepgramModel FLUX_BRUCE_EN = new DeepgramModel(Value.FLUX_BRUCE_EN, "flux-bruce-en"); - - public static final DeepgramModel AURA2APOLLO_EN = new DeepgramModel(Value.AURA2APOLLO_EN, "aura-2-apollo-en"); - - public static final DeepgramModel AURA2DELIA_EN = new DeepgramModel(Value.AURA2DELIA_EN, "aura-2-delia-en"); - - public static final DeepgramModel AURA2MARS_EN = new DeepgramModel(Value.AURA2MARS_EN, "aura-2-mars-en"); - - public static final DeepgramModel AURA_HERA_EN = new DeepgramModel(Value.AURA_HERA_EN, "aura-hera-en"); - - public static final DeepgramModel FLUX_MAEVE_EN = new DeepgramModel(Value.FLUX_MAEVE_EN, "flux-maeve-en"); - - public static final DeepgramModel FLUX_MARCUS_EN = new DeepgramModel(Value.FLUX_MARCUS_EN, "flux-marcus-en"); - - public static final DeepgramModel AURA2ARIES_EN = new DeepgramModel(Value.AURA2ARIES_EN, "aura-2-aries-en"); - - public static final DeepgramModel FLUX_PAIGE_EN = new DeepgramModel(Value.FLUX_PAIGE_EN, "flux-paige-en"); - - public static final DeepgramModel AURA2JUNO_EN = new DeepgramModel(Value.AURA2JUNO_EN, "aura-2-juno-en"); - - public static final DeepgramModel FLUX_DREW_EN = new DeepgramModel(Value.FLUX_DREW_EN, "flux-drew-en"); - - public static final DeepgramModel AURA2JAVIER_ES = new DeepgramModel(Value.AURA2JAVIER_ES, "aura-2-javier-es"); - - public static final DeepgramModel AURA2ANDROMEDA_EN = - new DeepgramModel(Value.AURA2ANDROMEDA_EN, "aura-2-andromeda-en"); - - public static final DeepgramModel AURA2SATURN_EN = new DeepgramModel(Value.AURA2SATURN_EN, "aura-2-saturn-en"); - - public static final DeepgramModel AURA2IRIS_EN = new DeepgramModel(Value.AURA2IRIS_EN, "aura-2-iris-en"); - - public static final DeepgramModel AURA_ANGUS_EN = new DeepgramModel(Value.AURA_ANGUS_EN, "aura-angus-en"); - - public static final DeepgramModel FLUX_KAI_EN = new DeepgramModel(Value.FLUX_KAI_EN, "flux-kai-en"); - - public static final DeepgramModel FLUX_BRITTANY_EN = new DeepgramModel(Value.FLUX_BRITTANY_EN, "flux-brittany-en"); - - public static final DeepgramModel FLUX_SEAN_EN = new DeepgramModel(Value.FLUX_SEAN_EN, "flux-sean-en"); - - public static final DeepgramModel AURA2HELENA_EN = new DeepgramModel(Value.AURA2HELENA_EN, "aura-2-helena-en"); - - public static final DeepgramModel FLUX_HALEY_EN = new DeepgramModel(Value.FLUX_HALEY_EN, "flux-haley-en"); - - public static final DeepgramModel AURA_STELLA_EN = new DeepgramModel(Value.AURA_STELLA_EN, "aura-stella-en"); - - public static final DeepgramModel FLUX_JACK_EN = new DeepgramModel(Value.FLUX_JACK_EN, "flux-jack-en"); - - public static final DeepgramModel AURA2DRACO_EN = new DeepgramModel(Value.AURA2DRACO_EN, "aura-2-draco-en"); - - public static final DeepgramModel FLUX_PRIYA_EN = new DeepgramModel(Value.FLUX_PRIYA_EN, "flux-priya-en"); - - public static final DeepgramModel AURA_HELIOS_EN = new DeepgramModel(Value.AURA_HELIOS_EN, "aura-helios-en"); - - public static final DeepgramModel AURA2JANUS_EN = new DeepgramModel(Value.AURA2JANUS_EN, "aura-2-janus-en"); - - public static final DeepgramModel AURA2NESTOR_ES = new DeepgramModel(Value.AURA2NESTOR_ES, "aura-2-nestor-es"); - - public static final DeepgramModel AURA2ORION_EN = new DeepgramModel(Value.AURA2ORION_EN, "aura-2-orion-en"); - - public static final DeepgramModel AURA2MINERVA_EN = new DeepgramModel(Value.AURA2MINERVA_EN, "aura-2-minerva-en"); - - public static final DeepgramModel AURA2ALVARO_ES = new DeepgramModel(Value.AURA2ALVARO_ES, "aura-2-alvaro-es"); - - public static final DeepgramModel AURA_PERSEUS_EN = new DeepgramModel(Value.AURA_PERSEUS_EN, "aura-perseus-en"); - - public static final DeepgramModel AURA2VESTA_EN = new DeepgramModel(Value.AURA2VESTA_EN, "aura-2-vesta-en"); - - public static final DeepgramModel FLUX_COLE_EN = new DeepgramModel(Value.FLUX_COLE_EN, "flux-cole-en"); - - public static final DeepgramModel AURA2ZEUS_EN = new DeepgramModel(Value.AURA2ZEUS_EN, "aura-2-zeus-en"); - - public static final DeepgramModel AURA2ORPHEUS_EN = new DeepgramModel(Value.AURA2ORPHEUS_EN, "aura-2-orpheus-en"); - - public static final DeepgramModel AURA2THALIA_EN = new DeepgramModel(Value.AURA2THALIA_EN, "aura-2-thalia-en"); - - public static final DeepgramModel FLUX_NAVEEN_EN = new DeepgramModel(Value.FLUX_NAVEEN_EN, "flux-naveen-en"); - - public static final DeepgramModel AURA2ASTERIA_EN = new DeepgramModel(Value.AURA2ASTERIA_EN, "aura-2-asteria-en"); - - public static final DeepgramModel AURA2SELENA_ES = new DeepgramModel(Value.AURA2SELENA_ES, "aura-2-selena-es"); - - public static final DeepgramModel FLUX_MARCELO_EN = new DeepgramModel(Value.FLUX_MARCELO_EN, "flux-marcelo-en"); - - public static final DeepgramModel FLUX_ELISE_EN = new DeepgramModel(Value.FLUX_ELISE_EN, "flux-elise-en"); - - public static final DeepgramModel FLUX_ALEXIS_EN = new DeepgramModel(Value.FLUX_ALEXIS_EN, "flux-alexis-en"); - - public static final DeepgramModel AURA_LUNA_EN = new DeepgramModel(Value.AURA_LUNA_EN, "aura-luna-en"); - - public static final DeepgramModel AURA_ORPHEUS_EN = new DeepgramModel(Value.AURA_ORPHEUS_EN, "aura-orpheus-en"); - - public static final DeepgramModel AURA2AMALTHEA_EN = - new DeepgramModel(Value.AURA2AMALTHEA_EN, "aura-2-amalthea-en"); - - public static final DeepgramModel FLUX_DONOVAN_EN = new DeepgramModel(Value.FLUX_DONOVAN_EN, "flux-donovan-en"); - - public static final DeepgramModel AURA2SELENE_EN = new DeepgramModel(Value.AURA2SELENE_EN, "aura-2-selene-en"); - - public static final DeepgramModel FLUX_TANNER_EN = new DeepgramModel(Value.FLUX_TANNER_EN, "flux-tanner-en"); - - public static final DeepgramModel FLUX_SHARON_EN = new DeepgramModel(Value.FLUX_SHARON_EN, "flux-sharon-en"); - - public static final DeepgramModel AURA2LUNA_EN = new DeepgramModel(Value.AURA2LUNA_EN, "aura-2-luna-en"); - - public static final DeepgramModel AURA2PHOEBE_EN = new DeepgramModel(Value.AURA2PHOEBE_EN, "aura-2-phoebe-en"); - - public static final DeepgramModel FLUX_HANNAH_EN = new DeepgramModel(Value.FLUX_HANNAH_EN, "flux-hannah-en"); - - public static final DeepgramModel AURA2DIANA_ES = new DeepgramModel(Value.AURA2DIANA_ES, "aura-2-diana-es"); - - public static final DeepgramModel AURA_ORION_EN = new DeepgramModel(Value.AURA_ORION_EN, "aura-orion-en"); - - public static final DeepgramModel AURA2ATHENA_EN = new DeepgramModel(Value.AURA2ATHENA_EN, "aura-2-athena-en"); - - public static final DeepgramModel AURA_ARCAS_EN = new DeepgramModel(Value.AURA_ARCAS_EN, "aura-arcas-en"); - - public static final DeepgramModel AURA2THEIA_EN = new DeepgramModel(Value.AURA2THEIA_EN, "aura-2-theia-en"); - - public static final DeepgramModel FLUX_WADE_EN = new DeepgramModel(Value.FLUX_WADE_EN, "flux-wade-en"); - - public static final DeepgramModel FLUX_HEATHER_EN = new DeepgramModel(Value.FLUX_HEATHER_EN, "flux-heather-en"); - - public static final DeepgramModel FLUX_CLIFF_EN = new DeepgramModel(Value.FLUX_CLIFF_EN, "flux-cliff-en"); - - public static final DeepgramModel AURA2JUPITER_EN = new DeepgramModel(Value.AURA2JUPITER_EN, "aura-2-jupiter-en"); - - public static final DeepgramModel FLUX_KIT_EN = new DeepgramModel(Value.FLUX_KIT_EN, "flux-kit-en"); - - public static final DeepgramModel AURA2AQUILA_ES = new DeepgramModel(Value.AURA2AQUILA_ES, "aura-2-aquila-es"); - - public static final DeepgramModel AURA2CORA_EN = new DeepgramModel(Value.AURA2CORA_EN, "aura-2-cora-en"); - - public static final DeepgramModel AURA2CORDELIA_EN = - new DeepgramModel(Value.AURA2CORDELIA_EN, "aura-2-cordelia-en"); - - public static final DeepgramModel AURA2ATLAS_EN = new DeepgramModel(Value.AURA2ATLAS_EN, "aura-2-atlas-en"); - - public static final DeepgramModel AURA2HYPERION_EN = - new DeepgramModel(Value.AURA2HYPERION_EN, "aura-2-hyperion-en"); - - public static final DeepgramModel AURA2CELESTE_ES = new DeepgramModel(Value.AURA2CELESTE_ES, "aura-2-celeste-es"); - - public static final DeepgramModel AURA2PLUTO_EN = new DeepgramModel(Value.AURA2PLUTO_EN, "aura-2-pluto-en"); - - public static final DeepgramModel FLUX_BREE_EN = new DeepgramModel(Value.FLUX_BREE_EN, "flux-bree-en"); - - public static final DeepgramModel AURA2ARCAS_EN = new DeepgramModel(Value.AURA2ARCAS_EN, "aura-2-arcas-en"); - - public static final DeepgramModel FLUX_COLIN_EN = new DeepgramModel(Value.FLUX_COLIN_EN, "flux-colin-en"); - - public static final DeepgramModel AURA_ATHENA_EN = new DeepgramModel(Value.AURA_ATHENA_EN, "aura-athena-en"); - - public static final DeepgramModel AURA2ODYSSEUS_EN = - new DeepgramModel(Value.AURA2ODYSSEUS_EN, "aura-2-odysseus-en"); - - public static final DeepgramModel AURA2PANDORA_EN = new DeepgramModel(Value.AURA2PANDORA_EN, "aura-2-pandora-en"); - - public static final DeepgramModel FLUX_MILES_EN = new DeepgramModel(Value.FLUX_MILES_EN, "flux-miles-en"); - - public static final DeepgramModel AURA_ASTERIA_EN = new DeepgramModel(Value.AURA_ASTERIA_EN, "aura-asteria-en"); - - public static final DeepgramModel AURA2ELECTRA_EN = new DeepgramModel(Value.AURA2ELECTRA_EN, "aura-2-electra-en"); - - public static final DeepgramModel FLUX_GEMMA_EN = new DeepgramModel(Value.FLUX_GEMMA_EN, "flux-gemma-en"); - - public static final DeepgramModel AURA2ESTRELLA_ES = - new DeepgramModel(Value.AURA2ESTRELLA_ES, "aura-2-estrella-es"); - - private final Value value; - - private final String string; - - DeepgramModel(Value value, String string) { - this.value = value; - this.string = string; - } - - public Value getEnumValue() { - return value; - } - - @java.lang.Override - @JsonValue - public String toString() { - return this.string; - } - - @java.lang.Override - public boolean equals(Object other) { - return (this == other) - || (other instanceof DeepgramModel && this.string.equals(((DeepgramModel) other).string)); - } - - @java.lang.Override - public int hashCode() { - return this.string.hashCode(); - } - - public T visit(Visitor visitor) { - switch (value) { - case AURA2SIRIO_ES: - return visitor.visitAura2SirioEs(); - case AURA2HERA_EN: - return visitor.visitAura2HeraEn(); - case FLUX_KELSEY_EN: - return visitor.visitFluxKelseyEn(); - case FLUX_RENEE_EN: - return visitor.visitFluxReneeEn(); - case FLUX_SIENNA_EN: - return visitor.visitFluxSiennaEn(); - case AURA2HARMONIA_EN: - return visitor.visitAura2HarmoniaEn(); - case AURA2CARINA_ES: - return visitor.visitAura2CarinaEs(); - case FLUX_MEENA_EN: - return visitor.visitFluxMeenaEn(); - case FLUX_MEGHAN_EN: - return visitor.visitFluxMeghanEn(); - case AURA_ZEUS_EN: - return visitor.visitAuraZeusEn(); - case AURA2HERMES_EN: - return visitor.visitAura2HermesEn(); - case FLUX_CONOR_EN: - return visitor.visitFluxConorEn(); - case AURA2NEPTUNE_EN: - return visitor.visitAura2NeptuneEn(); - case FLUX_BROOKE_EN: - return visitor.visitFluxBrookeEn(); - case FLUX_RUFUS_EN: - return visitor.visitFluxRufusEn(); - case FLUX_WES_EN: - return visitor.visitFluxWesEn(); - case AURA2CALLISTA_EN: - return visitor.visitAura2CallistaEn(); - case AURA2AURORA_EN: - return visitor.visitAura2AuroraEn(); - case AURA2OPHELIA_EN: - return visitor.visitAura2OpheliaEn(); - case FLUX_BRUCE_EN: - return visitor.visitFluxBruceEn(); - case AURA2APOLLO_EN: - return visitor.visitAura2ApolloEn(); - case AURA2DELIA_EN: - return visitor.visitAura2DeliaEn(); - case AURA2MARS_EN: - return visitor.visitAura2MarsEn(); - case AURA_HERA_EN: - return visitor.visitAuraHeraEn(); - case FLUX_MAEVE_EN: - return visitor.visitFluxMaeveEn(); - case FLUX_MARCUS_EN: - return visitor.visitFluxMarcusEn(); - case AURA2ARIES_EN: - return visitor.visitAura2AriesEn(); - case FLUX_PAIGE_EN: - return visitor.visitFluxPaigeEn(); - case AURA2JUNO_EN: - return visitor.visitAura2JunoEn(); - case FLUX_DREW_EN: - return visitor.visitFluxDrewEn(); - case AURA2JAVIER_ES: - return visitor.visitAura2JavierEs(); - case AURA2ANDROMEDA_EN: - return visitor.visitAura2AndromedaEn(); - case AURA2SATURN_EN: - return visitor.visitAura2SaturnEn(); - case AURA2IRIS_EN: - return visitor.visitAura2IrisEn(); - case AURA_ANGUS_EN: - return visitor.visitAuraAngusEn(); - case FLUX_KAI_EN: - return visitor.visitFluxKaiEn(); - case FLUX_BRITTANY_EN: - return visitor.visitFluxBrittanyEn(); - case FLUX_SEAN_EN: - return visitor.visitFluxSeanEn(); - case AURA2HELENA_EN: - return visitor.visitAura2HelenaEn(); - case FLUX_HALEY_EN: - return visitor.visitFluxHaleyEn(); - case AURA_STELLA_EN: - return visitor.visitAuraStellaEn(); - case FLUX_JACK_EN: - return visitor.visitFluxJackEn(); - case AURA2DRACO_EN: - return visitor.visitAura2DracoEn(); - case FLUX_PRIYA_EN: - return visitor.visitFluxPriyaEn(); - case AURA_HELIOS_EN: - return visitor.visitAuraHeliosEn(); - case AURA2JANUS_EN: - return visitor.visitAura2JanusEn(); - case AURA2NESTOR_ES: - return visitor.visitAura2NestorEs(); - case AURA2ORION_EN: - return visitor.visitAura2OrionEn(); - case AURA2MINERVA_EN: - return visitor.visitAura2MinervaEn(); - case AURA2ALVARO_ES: - return visitor.visitAura2AlvaroEs(); - case AURA_PERSEUS_EN: - return visitor.visitAuraPerseusEn(); - case AURA2VESTA_EN: - return visitor.visitAura2VestaEn(); - case FLUX_COLE_EN: - return visitor.visitFluxColeEn(); - case AURA2ZEUS_EN: - return visitor.visitAura2ZeusEn(); - case AURA2ORPHEUS_EN: - return visitor.visitAura2OrpheusEn(); - case AURA2THALIA_EN: - return visitor.visitAura2ThaliaEn(); - case FLUX_NAVEEN_EN: - return visitor.visitFluxNaveenEn(); - case AURA2ASTERIA_EN: - return visitor.visitAura2AsteriaEn(); - case AURA2SELENA_ES: - return visitor.visitAura2SelenaEs(); - case FLUX_MARCELO_EN: - return visitor.visitFluxMarceloEn(); - case FLUX_ELISE_EN: - return visitor.visitFluxEliseEn(); - case FLUX_ALEXIS_EN: - return visitor.visitFluxAlexisEn(); - case AURA_LUNA_EN: - return visitor.visitAuraLunaEn(); - case AURA_ORPHEUS_EN: - return visitor.visitAuraOrpheusEn(); - case AURA2AMALTHEA_EN: - return visitor.visitAura2AmaltheaEn(); - case FLUX_DONOVAN_EN: - return visitor.visitFluxDonovanEn(); - case AURA2SELENE_EN: - return visitor.visitAura2SeleneEn(); - case FLUX_TANNER_EN: - return visitor.visitFluxTannerEn(); - case FLUX_SHARON_EN: - return visitor.visitFluxSharonEn(); - case AURA2LUNA_EN: - return visitor.visitAura2LunaEn(); - case AURA2PHOEBE_EN: - return visitor.visitAura2PhoebeEn(); - case FLUX_HANNAH_EN: - return visitor.visitFluxHannahEn(); - case AURA2DIANA_ES: - return visitor.visitAura2DianaEs(); - case AURA_ORION_EN: - return visitor.visitAuraOrionEn(); - case AURA2ATHENA_EN: - return visitor.visitAura2AthenaEn(); - case AURA_ARCAS_EN: - return visitor.visitAuraArcasEn(); - case AURA2THEIA_EN: - return visitor.visitAura2TheiaEn(); - case FLUX_WADE_EN: - return visitor.visitFluxWadeEn(); - case FLUX_HEATHER_EN: - return visitor.visitFluxHeatherEn(); - case FLUX_CLIFF_EN: - return visitor.visitFluxCliffEn(); - case AURA2JUPITER_EN: - return visitor.visitAura2JupiterEn(); - case FLUX_KIT_EN: - return visitor.visitFluxKitEn(); - case AURA2AQUILA_ES: - return visitor.visitAura2AquilaEs(); - case AURA2CORA_EN: - return visitor.visitAura2CoraEn(); - case AURA2CORDELIA_EN: - return visitor.visitAura2CordeliaEn(); - case AURA2ATLAS_EN: - return visitor.visitAura2AtlasEn(); - case AURA2HYPERION_EN: - return visitor.visitAura2HyperionEn(); - case AURA2CELESTE_ES: - return visitor.visitAura2CelesteEs(); - case AURA2PLUTO_EN: - return visitor.visitAura2PlutoEn(); - case FLUX_BREE_EN: - return visitor.visitFluxBreeEn(); - case AURA2ARCAS_EN: - return visitor.visitAura2ArcasEn(); - case FLUX_COLIN_EN: - return visitor.visitFluxColinEn(); - case AURA_ATHENA_EN: - return visitor.visitAuraAthenaEn(); - case AURA2ODYSSEUS_EN: - return visitor.visitAura2OdysseusEn(); - case AURA2PANDORA_EN: - return visitor.visitAura2PandoraEn(); - case FLUX_MILES_EN: - return visitor.visitFluxMilesEn(); - case AURA_ASTERIA_EN: - return visitor.visitAuraAsteriaEn(); - case AURA2ELECTRA_EN: - return visitor.visitAura2ElectraEn(); - case FLUX_GEMMA_EN: - return visitor.visitFluxGemmaEn(); - case AURA2ESTRELLA_ES: - return visitor.visitAura2EstrellaEs(); - case UNKNOWN: - default: - return visitor.visitUnknown(string); - } - } - - @JsonCreator(mode = JsonCreator.Mode.DELEGATING) - public static DeepgramModel valueOf(String value) { - switch (value) { - case "aura-2-sirio-es": - return AURA2SIRIO_ES; - case "aura-2-hera-en": - return AURA2HERA_EN; - case "flux-kelsey-en": - return FLUX_KELSEY_EN; - case "flux-renee-en": - return FLUX_RENEE_EN; - case "flux-sienna-en": - return FLUX_SIENNA_EN; - case "aura-2-harmonia-en": - return AURA2HARMONIA_EN; - case "aura-2-carina-es": - return AURA2CARINA_ES; - case "flux-meena-en": - return FLUX_MEENA_EN; - case "flux-meghan-en": - return FLUX_MEGHAN_EN; - case "aura-zeus-en": - return AURA_ZEUS_EN; - case "aura-2-hermes-en": - return AURA2HERMES_EN; - case "flux-conor-en": - return FLUX_CONOR_EN; - case "aura-2-neptune-en": - return AURA2NEPTUNE_EN; - case "flux-brooke-en": - return FLUX_BROOKE_EN; - case "flux-rufus-en": - return FLUX_RUFUS_EN; - case "flux-wes-en": - return FLUX_WES_EN; - case "aura-2-callista-en": - return AURA2CALLISTA_EN; - case "aura-2-aurora-en": - return AURA2AURORA_EN; - case "aura-2-ophelia-en": - return AURA2OPHELIA_EN; - case "flux-bruce-en": - return FLUX_BRUCE_EN; - case "aura-2-apollo-en": - return AURA2APOLLO_EN; - case "aura-2-delia-en": - return AURA2DELIA_EN; - case "aura-2-mars-en": - return AURA2MARS_EN; - case "aura-hera-en": - return AURA_HERA_EN; - case "flux-maeve-en": - return FLUX_MAEVE_EN; - case "flux-marcus-en": - return FLUX_MARCUS_EN; - case "aura-2-aries-en": - return AURA2ARIES_EN; - case "flux-paige-en": - return FLUX_PAIGE_EN; - case "aura-2-juno-en": - return AURA2JUNO_EN; - case "flux-drew-en": - return FLUX_DREW_EN; - case "aura-2-javier-es": - return AURA2JAVIER_ES; - case "aura-2-andromeda-en": - return AURA2ANDROMEDA_EN; - case "aura-2-saturn-en": - return AURA2SATURN_EN; - case "aura-2-iris-en": - return AURA2IRIS_EN; - case "aura-angus-en": - return AURA_ANGUS_EN; - case "flux-kai-en": - return FLUX_KAI_EN; - case "flux-brittany-en": - return FLUX_BRITTANY_EN; - case "flux-sean-en": - return FLUX_SEAN_EN; - case "aura-2-helena-en": - return AURA2HELENA_EN; - case "flux-haley-en": - return FLUX_HALEY_EN; - case "aura-stella-en": - return AURA_STELLA_EN; - case "flux-jack-en": - return FLUX_JACK_EN; - case "aura-2-draco-en": - return AURA2DRACO_EN; - case "flux-priya-en": - return FLUX_PRIYA_EN; - case "aura-helios-en": - return AURA_HELIOS_EN; - case "aura-2-janus-en": - return AURA2JANUS_EN; - case "aura-2-nestor-es": - return AURA2NESTOR_ES; - case "aura-2-orion-en": - return AURA2ORION_EN; - case "aura-2-minerva-en": - return AURA2MINERVA_EN; - case "aura-2-alvaro-es": - return AURA2ALVARO_ES; - case "aura-perseus-en": - return AURA_PERSEUS_EN; - case "aura-2-vesta-en": - return AURA2VESTA_EN; - case "flux-cole-en": - return FLUX_COLE_EN; - case "aura-2-zeus-en": - return AURA2ZEUS_EN; - case "aura-2-orpheus-en": - return AURA2ORPHEUS_EN; - case "aura-2-thalia-en": - return AURA2THALIA_EN; - case "flux-naveen-en": - return FLUX_NAVEEN_EN; - case "aura-2-asteria-en": - return AURA2ASTERIA_EN; - case "aura-2-selena-es": - return AURA2SELENA_ES; - case "flux-marcelo-en": - return FLUX_MARCELO_EN; - case "flux-elise-en": - return FLUX_ELISE_EN; - case "flux-alexis-en": - return FLUX_ALEXIS_EN; - case "aura-luna-en": - return AURA_LUNA_EN; - case "aura-orpheus-en": - return AURA_ORPHEUS_EN; - case "aura-2-amalthea-en": - return AURA2AMALTHEA_EN; - case "flux-donovan-en": - return FLUX_DONOVAN_EN; - case "aura-2-selene-en": - return AURA2SELENE_EN; - case "flux-tanner-en": - return FLUX_TANNER_EN; - case "flux-sharon-en": - return FLUX_SHARON_EN; - case "aura-2-luna-en": - return AURA2LUNA_EN; - case "aura-2-phoebe-en": - return AURA2PHOEBE_EN; - case "flux-hannah-en": - return FLUX_HANNAH_EN; - case "aura-2-diana-es": - return AURA2DIANA_ES; - case "aura-orion-en": - return AURA_ORION_EN; - case "aura-2-athena-en": - return AURA2ATHENA_EN; - case "aura-arcas-en": - return AURA_ARCAS_EN; - case "aura-2-theia-en": - return AURA2THEIA_EN; - case "flux-wade-en": - return FLUX_WADE_EN; - case "flux-heather-en": - return FLUX_HEATHER_EN; - case "flux-cliff-en": - return FLUX_CLIFF_EN; - case "aura-2-jupiter-en": - return AURA2JUPITER_EN; - case "flux-kit-en": - return FLUX_KIT_EN; - case "aura-2-aquila-es": - return AURA2AQUILA_ES; - case "aura-2-cora-en": - return AURA2CORA_EN; - case "aura-2-cordelia-en": - return AURA2CORDELIA_EN; - case "aura-2-atlas-en": - return AURA2ATLAS_EN; - case "aura-2-hyperion-en": - return AURA2HYPERION_EN; - case "aura-2-celeste-es": - return AURA2CELESTE_ES; - case "aura-2-pluto-en": - return AURA2PLUTO_EN; - case "flux-bree-en": - return FLUX_BREE_EN; - case "aura-2-arcas-en": - return AURA2ARCAS_EN; - case "flux-colin-en": - return FLUX_COLIN_EN; - case "aura-athena-en": - return AURA_ATHENA_EN; - case "aura-2-odysseus-en": - return AURA2ODYSSEUS_EN; - case "aura-2-pandora-en": - return AURA2PANDORA_EN; - case "flux-miles-en": - return FLUX_MILES_EN; - case "aura-asteria-en": - return AURA_ASTERIA_EN; - case "aura-2-electra-en": - return AURA2ELECTRA_EN; - case "flux-gemma-en": - return FLUX_GEMMA_EN; - case "aura-2-estrella-es": - return AURA2ESTRELLA_ES; - default: - return new DeepgramModel(Value.UNKNOWN, value); - } - } - - public enum Value { - AURA_ASTERIA_EN, - - AURA_LUNA_EN, - - AURA_STELLA_EN, - - AURA_ATHENA_EN, - - AURA_HERA_EN, - - AURA_ORION_EN, - - AURA_ARCAS_EN, - - AURA_PERSEUS_EN, - - AURA_ANGUS_EN, - - AURA_ORPHEUS_EN, - - AURA_HELIOS_EN, - - AURA_ZEUS_EN, - - AURA2AMALTHEA_EN, - - AURA2ANDROMEDA_EN, - - AURA2APOLLO_EN, - - AURA2ARCAS_EN, - - AURA2ARIES_EN, - - AURA2ASTERIA_EN, - - AURA2ATHENA_EN, - - AURA2ATLAS_EN, - - AURA2AURORA_EN, - - AURA2CALLISTA_EN, - - AURA2CORA_EN, - - AURA2CORDELIA_EN, - - AURA2DELIA_EN, - - AURA2DRACO_EN, - - AURA2ELECTRA_EN, - - AURA2HARMONIA_EN, - - AURA2HELENA_EN, - - AURA2HERA_EN, - - AURA2HERMES_EN, - - AURA2HYPERION_EN, - - AURA2IRIS_EN, - - AURA2JANUS_EN, - - AURA2JUNO_EN, - - AURA2JUPITER_EN, - - AURA2LUNA_EN, - - AURA2MARS_EN, - - AURA2MINERVA_EN, - - AURA2NEPTUNE_EN, - - AURA2ODYSSEUS_EN, - - AURA2OPHELIA_EN, - - AURA2ORION_EN, - - AURA2ORPHEUS_EN, - - AURA2PANDORA_EN, - - AURA2PHOEBE_EN, - - AURA2PLUTO_EN, - - AURA2SATURN_EN, - - AURA2SELENE_EN, - - AURA2THALIA_EN, - - AURA2THEIA_EN, - - AURA2VESTA_EN, - - AURA2ZEUS_EN, - - AURA2SIRIO_ES, - - AURA2NESTOR_ES, - - AURA2CARINA_ES, - - AURA2CELESTE_ES, - - AURA2ALVARO_ES, - - AURA2DIANA_ES, - - AURA2AQUILA_ES, - - AURA2SELENA_ES, - - AURA2ESTRELLA_ES, - - AURA2JAVIER_ES, - - FLUX_ALEXIS_EN, - - FLUX_BREE_EN, - - FLUX_BRITTANY_EN, - - FLUX_BROOKE_EN, - - FLUX_BRUCE_EN, - - FLUX_CLIFF_EN, - - FLUX_COLE_EN, - - FLUX_COLIN_EN, - - FLUX_CONOR_EN, - - FLUX_DONOVAN_EN, - - FLUX_DREW_EN, - - FLUX_ELISE_EN, - - FLUX_GEMMA_EN, - - FLUX_HALEY_EN, - - FLUX_HANNAH_EN, - - FLUX_HEATHER_EN, - - FLUX_JACK_EN, - - FLUX_KAI_EN, - - FLUX_KELSEY_EN, - - FLUX_KIT_EN, - - FLUX_MAEVE_EN, - - FLUX_MARCELO_EN, - - FLUX_MARCUS_EN, - - FLUX_MEENA_EN, - - FLUX_MEGHAN_EN, - - FLUX_MILES_EN, - - FLUX_NAVEEN_EN, - - FLUX_PAIGE_EN, - - FLUX_PRIYA_EN, - - FLUX_RENEE_EN, - - FLUX_RUFUS_EN, - - FLUX_SEAN_EN, - - FLUX_SHARON_EN, - - FLUX_SIENNA_EN, - - FLUX_TANNER_EN, - - FLUX_WADE_EN, - - FLUX_WES_EN, - - UNKNOWN - } - - public interface Visitor { - T visitAuraAsteriaEn(); - - T visitAuraLunaEn(); - - T visitAuraStellaEn(); - - T visitAuraAthenaEn(); - - T visitAuraHeraEn(); - - T visitAuraOrionEn(); - - T visitAuraArcasEn(); - - T visitAuraPerseusEn(); - - T visitAuraAngusEn(); - - T visitAuraOrpheusEn(); - - T visitAuraHeliosEn(); - - T visitAuraZeusEn(); - - T visitAura2AmaltheaEn(); - - T visitAura2AndromedaEn(); - - T visitAura2ApolloEn(); - - T visitAura2ArcasEn(); - - T visitAura2AriesEn(); - - T visitAura2AsteriaEn(); - - T visitAura2AthenaEn(); - - T visitAura2AtlasEn(); - - T visitAura2AuroraEn(); - - T visitAura2CallistaEn(); - - T visitAura2CoraEn(); - - T visitAura2CordeliaEn(); - - T visitAura2DeliaEn(); - - T visitAura2DracoEn(); - - T visitAura2ElectraEn(); - - T visitAura2HarmoniaEn(); - - T visitAura2HelenaEn(); - - T visitAura2HeraEn(); - - T visitAura2HermesEn(); - - T visitAura2HyperionEn(); - - T visitAura2IrisEn(); - - T visitAura2JanusEn(); - - T visitAura2JunoEn(); - - T visitAura2JupiterEn(); - - T visitAura2LunaEn(); - - T visitAura2MarsEn(); - - T visitAura2MinervaEn(); - - T visitAura2NeptuneEn(); - - T visitAura2OdysseusEn(); - - T visitAura2OpheliaEn(); - - T visitAura2OrionEn(); - - T visitAura2OrpheusEn(); - - T visitAura2PandoraEn(); - - T visitAura2PhoebeEn(); - - T visitAura2PlutoEn(); - - T visitAura2SaturnEn(); - - T visitAura2SeleneEn(); - - T visitAura2ThaliaEn(); - - T visitAura2TheiaEn(); - - T visitAura2VestaEn(); - - T visitAura2ZeusEn(); - - T visitAura2SirioEs(); - - T visitAura2NestorEs(); - - T visitAura2CarinaEs(); - - T visitAura2CelesteEs(); - - T visitAura2AlvaroEs(); - - T visitAura2DianaEs(); - - T visitAura2AquilaEs(); - - T visitAura2SelenaEs(); - - T visitAura2EstrellaEs(); - - T visitAura2JavierEs(); - - T visitFluxAlexisEn(); - - T visitFluxBreeEn(); - - T visitFluxBrittanyEn(); - - T visitFluxBrookeEn(); - - T visitFluxBruceEn(); - - T visitFluxCliffEn(); - - T visitFluxColeEn(); - - T visitFluxColinEn(); - - T visitFluxConorEn(); - - T visitFluxDonovanEn(); - - T visitFluxDrewEn(); - - T visitFluxEliseEn(); - - T visitFluxGemmaEn(); - - T visitFluxHaleyEn(); - - T visitFluxHannahEn(); - - T visitFluxHeatherEn(); - - T visitFluxJackEn(); - - T visitFluxKaiEn(); - - T visitFluxKelseyEn(); - - T visitFluxKitEn(); - - T visitFluxMaeveEn(); - - T visitFluxMarceloEn(); - - T visitFluxMarcusEn(); - - T visitFluxMeenaEn(); - - T visitFluxMeghanEn(); - - T visitFluxMilesEn(); - - T visitFluxNaveenEn(); - - T visitFluxPaigeEn(); - - T visitFluxPriyaEn(); - - T visitFluxReneeEn(); - - T visitFluxRufusEn(); - - T visitFluxSeanEn(); - - T visitFluxSharonEn(); - - T visitFluxSiennaEn(); - - T visitFluxTannerEn(); - - T visitFluxWadeEn(); - - T visitFluxWesEn(); - - T visitUnknown(String unknownType); - } -} diff --git a/src/main/java/com/deepgram/types/SharedIntents.java b/src/main/java/com/deepgram/types/SharedIntents.java index 05799c2..4a04305 100644 --- a/src/main/java/com/deepgram/types/SharedIntents.java +++ b/src/main/java/com/deepgram/types/SharedIntents.java @@ -6,6 +6,7 @@ import com.deepgram.core.ObjectMappers; import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; @@ -36,6 +37,15 @@ public Optional> getSegments() { return segments; } + /** + * @deprecated The API returns segments directly. Use {@link #getSegments()}. + */ + @Deprecated + @JsonIgnore + public Optional getResults() { + return segments.map(SharedIntentsResults::fromCurrent); + } + @java.lang.Override public boolean equals(Object other) { if (this == other) return true; @@ -90,6 +100,23 @@ public Builder segments(List segments) { return this; } + /** + * @deprecated The API returns segments directly. Use {@link #segments(List)}. + */ + @Deprecated + public Builder results(Optional results) { + this.segments = results.flatMap(SharedIntentsResults::toCurrentSegments); + return this; + } + + /** + * @deprecated The API returns segments directly. Use {@link #segments(List)}. + */ + @Deprecated + public Builder results(SharedIntentsResults results) { + return results(Optional.ofNullable(results)); + } + public SharedIntents build() { return new SharedIntents(segments, additionalProperties); } diff --git a/src/main/java/com/deepgram/types/SharedIntentsResults.java b/src/main/java/com/deepgram/types/SharedIntentsResults.java new file mode 100644 index 0000000..35a406a --- /dev/null +++ b/src/main/java/com/deepgram/types/SharedIntentsResults.java @@ -0,0 +1,56 @@ +package com.deepgram.types; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +/** @deprecated Use {@link SharedIntents#getSegments()}. */ +@Deprecated +public final class SharedIntentsResults { + private final Optional intents; + private final Map additionalProperties; + + private SharedIntentsResults(Optional intents, Map additionalProperties) { + this.intents = intents; + this.additionalProperties = additionalProperties; + } + + static SharedIntentsResults fromCurrent(List segments) { + return new SharedIntentsResults(Optional.of(SharedIntentsResultsIntents.fromCurrent(segments)), new HashMap<>()); + } + + Optional> toCurrentSegments() { + return intents.flatMap(SharedIntentsResultsIntents::toCurrentSegments); + } + + public Optional getIntents() { return intents; } + public Map getAdditionalProperties() { return additionalProperties; } + + @Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof SharedIntentsResults && intents.equals(((SharedIntentsResults) other).intents); + } + + @Override + public int hashCode() { return Objects.hash(intents); } + + public static Builder builder() { return new Builder(); } + + public static final class Builder { + private Optional intents = Optional.empty(); + private final Map additionalProperties = new HashMap<>(); + + private Builder() {} + + public Builder from(SharedIntentsResults other) { return intents(other.getIntents()); } + public Builder intents(Optional intents) { this.intents = intents; return this; } + public Builder intents(SharedIntentsResultsIntents intents) { return intents(Optional.ofNullable(intents)); } + public Builder additionalProperty(String key, Object value) { additionalProperties.put(key, value); return this; } + public Builder additionalProperties(Map additionalProperties) { this.additionalProperties.putAll(additionalProperties); return this; } + + public SharedIntentsResults build() { return new SharedIntentsResults(intents, additionalProperties); } + } +} diff --git a/src/main/java/com/deepgram/types/SharedIntentsResultsIntents.java b/src/main/java/com/deepgram/types/SharedIntentsResultsIntents.java new file mode 100644 index 0000000..1a403cf --- /dev/null +++ b/src/main/java/com/deepgram/types/SharedIntentsResultsIntents.java @@ -0,0 +1,64 @@ +package com.deepgram.types; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +/** @deprecated Use {@link SharedIntents#getSegments()}. */ +@Deprecated +public final class SharedIntentsResultsIntents { + private final Optional> segments; + private final Map additionalProperties; + + private SharedIntentsResultsIntents( + Optional> segments, Map additionalProperties) { + this.segments = segments; + this.additionalProperties = additionalProperties; + } + + static SharedIntentsResultsIntents fromCurrent(List segments) { + return new SharedIntentsResultsIntents( + Optional.of(segments.stream() + .map(SharedIntentsResultsIntentsSegmentsItem::fromCurrent) + .collect(Collectors.toList())), + new HashMap<>()); + } + + Optional> toCurrentSegments() { + return segments.map(values -> values.stream() + .map(SharedIntentsResultsIntentsSegmentsItem::toCurrent) + .collect(Collectors.toList())); + } + + public Optional> getSegments() { return segments; } + public Map getAdditionalProperties() { return additionalProperties; } + + @Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof SharedIntentsResultsIntents && segments.equals(((SharedIntentsResultsIntents) other).segments); + } + + @Override + public int hashCode() { return Objects.hash(segments); } + + public static Builder builder() { return new Builder(); } + + public static final class Builder { + private Optional> segments = Optional.empty(); + private final Map additionalProperties = new HashMap<>(); + + private Builder() {} + + public Builder from(SharedIntentsResultsIntents other) { return segments(other.getSegments()); } + public Builder segments(Optional> segments) { this.segments = segments; return this; } + public Builder segments(List segments) { return segments(Optional.ofNullable(segments)); } + public Builder additionalProperty(String key, Object value) { additionalProperties.put(key, value); return this; } + public Builder additionalProperties(Map additionalProperties) { this.additionalProperties.putAll(additionalProperties); return this; } + + public SharedIntentsResultsIntents build() { return new SharedIntentsResultsIntents(segments, additionalProperties); } + } +} diff --git a/src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItem.java b/src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItem.java new file mode 100644 index 0000000..bdaac01 --- /dev/null +++ b/src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItem.java @@ -0,0 +1,106 @@ +package com.deepgram.types; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +/** @deprecated Use {@link SharedIntentsSegmentsItem}. */ +@Deprecated +public final class SharedIntentsResultsIntentsSegmentsItem { + private final Optional text; + private final Optional startWord; + private final Optional endWord; + private final Optional> intents; + private final Map additionalProperties; + + private SharedIntentsResultsIntentsSegmentsItem( + Optional text, + Optional startWord, + Optional endWord, + Optional> intents, + Map additionalProperties) { + this.text = text; + this.startWord = startWord; + this.endWord = endWord; + this.intents = intents; + this.additionalProperties = additionalProperties; + } + + static SharedIntentsResultsIntentsSegmentsItem fromCurrent(SharedIntentsSegmentsItem value) { + return new SharedIntentsResultsIntentsSegmentsItem( + value.getText(), + value.getStartWord(), + value.getEndWord(), + value.getIntents().map(items -> items.stream() + .map(SharedIntentsResultsIntentsSegmentsItemIntentsItem::fromCurrent) + .collect(Collectors.toList())), + value.getAdditionalProperties()); + } + + SharedIntentsSegmentsItem toCurrent() { + return SharedIntentsSegmentsItem.builder() + .text(text) + .startWord(startWord) + .endWord(endWord) + .intents(intents.map(items -> items.stream() + .map(SharedIntentsResultsIntentsSegmentsItemIntentsItem::toCurrent) + .collect(Collectors.toList()))) + .additionalProperties(additionalProperties) + .build(); + } + + public Optional getText() { return text; } + public Optional getStartWord() { return startWord; } + public Optional getEndWord() { return endWord; } + public Optional> getIntents() { return intents; } + public Map getAdditionalProperties() { return additionalProperties; } + + @Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof SharedIntentsResultsIntentsSegmentsItem + && equalTo((SharedIntentsResultsIntentsSegmentsItem) other); + } + + private boolean equalTo(SharedIntentsResultsIntentsSegmentsItem other) { + return text.equals(other.text) && startWord.equals(other.startWord) && endWord.equals(other.endWord) + && intents.equals(other.intents); + } + + @Override + public int hashCode() { return Objects.hash(text, startWord, endWord, intents); } + + public static Builder builder() { return new Builder(); } + + public static final class Builder { + private Optional text = Optional.empty(); + private Optional startWord = Optional.empty(); + private Optional endWord = Optional.empty(); + private Optional> intents = Optional.empty(); + private final Map additionalProperties = new HashMap<>(); + + private Builder() {} + + public Builder from(SharedIntentsResultsIntentsSegmentsItem other) { + return text(other.getText()).startWord(other.getStartWord()).endWord(other.getEndWord()).intents(other.getIntents()); + } + + public Builder text(Optional text) { this.text = text; return this; } + public Builder text(String text) { return text(Optional.ofNullable(text)); } + public Builder startWord(Optional startWord) { this.startWord = startWord; return this; } + public Builder startWord(Double startWord) { return startWord(Optional.ofNullable(startWord)); } + public Builder endWord(Optional endWord) { this.endWord = endWord; return this; } + public Builder endWord(Double endWord) { return endWord(Optional.ofNullable(endWord)); } + public Builder intents(Optional> intents) { this.intents = intents; return this; } + public Builder intents(List intents) { return intents(Optional.ofNullable(intents)); } + public Builder additionalProperty(String key, Object value) { additionalProperties.put(key, value); return this; } + public Builder additionalProperties(Map additionalProperties) { this.additionalProperties.putAll(additionalProperties); return this; } + + public SharedIntentsResultsIntentsSegmentsItem build() { + return new SharedIntentsResultsIntentsSegmentsItem(text, startWord, endWord, intents, additionalProperties); + } + } +} diff --git a/src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItemIntentsItem.java b/src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItemIntentsItem.java new file mode 100644 index 0000000..43c948f --- /dev/null +++ b/src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItemIntentsItem.java @@ -0,0 +1,77 @@ +package com.deepgram.types; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +/** @deprecated Use {@link SharedIntentsSegmentsItemIntentsItem}. */ +@Deprecated +public final class SharedIntentsResultsIntentsSegmentsItemIntentsItem { + private final Optional intent; + private final Optional confidenceScore; + private final Map additionalProperties; + + private SharedIntentsResultsIntentsSegmentsItemIntentsItem( + Optional intent, Optional confidenceScore, Map additionalProperties) { + this.intent = intent; + this.confidenceScore = confidenceScore; + this.additionalProperties = additionalProperties; + } + + static SharedIntentsResultsIntentsSegmentsItemIntentsItem fromCurrent(SharedIntentsSegmentsItemIntentsItem value) { + return new SharedIntentsResultsIntentsSegmentsItemIntentsItem( + value.getIntent(), value.getConfidenceScore(), value.getAdditionalProperties()); + } + + SharedIntentsSegmentsItemIntentsItem toCurrent() { + return SharedIntentsSegmentsItemIntentsItem.builder() + .intent(intent) + .confidenceScore(confidenceScore) + .additionalProperties(additionalProperties) + .build(); + } + + public Optional getIntent() { return intent; } + public Optional getConfidenceScore() { return confidenceScore; } + public Map getAdditionalProperties() { return additionalProperties; } + + @Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof SharedIntentsResultsIntentsSegmentsItemIntentsItem + && equalTo((SharedIntentsResultsIntentsSegmentsItemIntentsItem) other); + } + + private boolean equalTo(SharedIntentsResultsIntentsSegmentsItemIntentsItem other) { + return intent.equals(other.intent) && confidenceScore.equals(other.confidenceScore); + } + + @Override + public int hashCode() { return Objects.hash(intent, confidenceScore); } + + public static Builder builder() { return new Builder(); } + + public static final class Builder { + private Optional intent = Optional.empty(); + private Optional confidenceScore = Optional.empty(); + private final Map additionalProperties = new HashMap<>(); + + private Builder() {} + + public Builder from(SharedIntentsResultsIntentsSegmentsItemIntentsItem other) { + return intent(other.getIntent()).confidenceScore(other.getConfidenceScore()); + } + + public Builder intent(Optional intent) { this.intent = intent; return this; } + public Builder intent(String intent) { return intent(Optional.ofNullable(intent)); } + public Builder confidenceScore(Optional confidenceScore) { this.confidenceScore = confidenceScore; return this; } + public Builder confidenceScore(Float confidenceScore) { return confidenceScore(Optional.ofNullable(confidenceScore)); } + public Builder additionalProperty(String key, Object value) { additionalProperties.put(key, value); return this; } + public Builder additionalProperties(Map additionalProperties) { this.additionalProperties.putAll(additionalProperties); return this; } + + public SharedIntentsResultsIntentsSegmentsItemIntentsItem build() { + return new SharedIntentsResultsIntentsSegmentsItemIntentsItem(intent, confidenceScore, additionalProperties); + } + } +} diff --git a/src/main/java/com/deepgram/types/SharedTopics.java b/src/main/java/com/deepgram/types/SharedTopics.java index 25a75ea..f2e2765 100644 --- a/src/main/java/com/deepgram/types/SharedTopics.java +++ b/src/main/java/com/deepgram/types/SharedTopics.java @@ -6,6 +6,7 @@ import com.deepgram.core.ObjectMappers; import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; @@ -35,6 +36,15 @@ public Optional> getSegments() { return segments; } + /** + * @deprecated The API returns segments directly. Use {@link #getSegments()}. + */ + @Deprecated + @JsonIgnore + public Optional getResults() { + return segments.map(SharedTopicsResults::fromCurrent); + } + @java.lang.Override public boolean equals(Object other) { if (this == other) return true; @@ -89,6 +99,23 @@ public Builder segments(List segments) { return this; } + /** + * @deprecated The API returns segments directly. Use {@link #segments(List)}. + */ + @Deprecated + public Builder results(Optional results) { + this.segments = results.flatMap(SharedTopicsResults::toCurrentSegments); + return this; + } + + /** + * @deprecated The API returns segments directly. Use {@link #segments(List)}. + */ + @Deprecated + public Builder results(SharedTopicsResults results) { + return results(Optional.ofNullable(results)); + } + public SharedTopics build() { return new SharedTopics(segments, additionalProperties); } diff --git a/src/main/java/com/deepgram/types/SharedTopicsResults.java b/src/main/java/com/deepgram/types/SharedTopicsResults.java new file mode 100644 index 0000000..77372bd --- /dev/null +++ b/src/main/java/com/deepgram/types/SharedTopicsResults.java @@ -0,0 +1,56 @@ +package com.deepgram.types; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +/** @deprecated Use {@link SharedTopics#getSegments()}. */ +@Deprecated +public final class SharedTopicsResults { + private final Optional topics; + private final Map additionalProperties; + + private SharedTopicsResults(Optional topics, Map additionalProperties) { + this.topics = topics; + this.additionalProperties = additionalProperties; + } + + static SharedTopicsResults fromCurrent(List segments) { + return new SharedTopicsResults(Optional.of(SharedTopicsResultsTopics.fromCurrent(segments)), new HashMap<>()); + } + + Optional> toCurrentSegments() { + return topics.flatMap(SharedTopicsResultsTopics::toCurrentSegments); + } + + public Optional getTopics() { return topics; } + public Map getAdditionalProperties() { return additionalProperties; } + + @Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof SharedTopicsResults && topics.equals(((SharedTopicsResults) other).topics); + } + + @Override + public int hashCode() { return Objects.hash(topics); } + + public static Builder builder() { return new Builder(); } + + public static final class Builder { + private Optional topics = Optional.empty(); + private final Map additionalProperties = new HashMap<>(); + + private Builder() {} + + public Builder from(SharedTopicsResults other) { return topics(other.getTopics()); } + public Builder topics(Optional topics) { this.topics = topics; return this; } + public Builder topics(SharedTopicsResultsTopics topics) { return topics(Optional.ofNullable(topics)); } + public Builder additionalProperty(String key, Object value) { additionalProperties.put(key, value); return this; } + public Builder additionalProperties(Map additionalProperties) { this.additionalProperties.putAll(additionalProperties); return this; } + + public SharedTopicsResults build() { return new SharedTopicsResults(topics, additionalProperties); } + } +} diff --git a/src/main/java/com/deepgram/types/SharedTopicsResultsTopics.java b/src/main/java/com/deepgram/types/SharedTopicsResultsTopics.java new file mode 100644 index 0000000..6aaa981 --- /dev/null +++ b/src/main/java/com/deepgram/types/SharedTopicsResultsTopics.java @@ -0,0 +1,64 @@ +package com.deepgram.types; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +/** @deprecated Use {@link SharedTopics#getSegments()}. */ +@Deprecated +public final class SharedTopicsResultsTopics { + private final Optional> segments; + private final Map additionalProperties; + + private SharedTopicsResultsTopics( + Optional> segments, Map additionalProperties) { + this.segments = segments; + this.additionalProperties = additionalProperties; + } + + static SharedTopicsResultsTopics fromCurrent(List segments) { + return new SharedTopicsResultsTopics( + Optional.of(segments.stream() + .map(SharedTopicsResultsTopicsSegmentsItem::fromCurrent) + .collect(Collectors.toList())), + new HashMap<>()); + } + + Optional> toCurrentSegments() { + return segments.map(values -> values.stream() + .map(SharedTopicsResultsTopicsSegmentsItem::toCurrent) + .collect(Collectors.toList())); + } + + public Optional> getSegments() { return segments; } + public Map getAdditionalProperties() { return additionalProperties; } + + @Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof SharedTopicsResultsTopics && segments.equals(((SharedTopicsResultsTopics) other).segments); + } + + @Override + public int hashCode() { return Objects.hash(segments); } + + public static Builder builder() { return new Builder(); } + + public static final class Builder { + private Optional> segments = Optional.empty(); + private final Map additionalProperties = new HashMap<>(); + + private Builder() {} + + public Builder from(SharedTopicsResultsTopics other) { return segments(other.getSegments()); } + public Builder segments(Optional> segments) { this.segments = segments; return this; } + public Builder segments(List segments) { return segments(Optional.ofNullable(segments)); } + public Builder additionalProperty(String key, Object value) { additionalProperties.put(key, value); return this; } + public Builder additionalProperties(Map additionalProperties) { this.additionalProperties.putAll(additionalProperties); return this; } + + public SharedTopicsResultsTopics build() { return new SharedTopicsResultsTopics(segments, additionalProperties); } + } +} diff --git a/src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItem.java b/src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItem.java new file mode 100644 index 0000000..da2fedb --- /dev/null +++ b/src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItem.java @@ -0,0 +1,106 @@ +package com.deepgram.types; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +/** @deprecated Use {@link SharedTopicsSegmentsItem}. */ +@Deprecated +public final class SharedTopicsResultsTopicsSegmentsItem { + private final Optional text; + private final Optional startWord; + private final Optional endWord; + private final Optional> topics; + private final Map additionalProperties; + + private SharedTopicsResultsTopicsSegmentsItem( + Optional text, + Optional startWord, + Optional endWord, + Optional> topics, + Map additionalProperties) { + this.text = text; + this.startWord = startWord; + this.endWord = endWord; + this.topics = topics; + this.additionalProperties = additionalProperties; + } + + static SharedTopicsResultsTopicsSegmentsItem fromCurrent(SharedTopicsSegmentsItem value) { + return new SharedTopicsResultsTopicsSegmentsItem( + value.getText(), + value.getStartWord(), + value.getEndWord(), + value.getTopics().map(items -> items.stream() + .map(SharedTopicsResultsTopicsSegmentsItemTopicsItem::fromCurrent) + .collect(Collectors.toList())), + value.getAdditionalProperties()); + } + + SharedTopicsSegmentsItem toCurrent() { + return SharedTopicsSegmentsItem.builder() + .text(text) + .startWord(startWord) + .endWord(endWord) + .topics(topics.map(items -> items.stream() + .map(SharedTopicsResultsTopicsSegmentsItemTopicsItem::toCurrent) + .collect(Collectors.toList()))) + .additionalProperties(additionalProperties) + .build(); + } + + public Optional getText() { return text; } + public Optional getStartWord() { return startWord; } + public Optional getEndWord() { return endWord; } + public Optional> getTopics() { return topics; } + public Map getAdditionalProperties() { return additionalProperties; } + + @Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof SharedTopicsResultsTopicsSegmentsItem + && equalTo((SharedTopicsResultsTopicsSegmentsItem) other); + } + + private boolean equalTo(SharedTopicsResultsTopicsSegmentsItem other) { + return text.equals(other.text) && startWord.equals(other.startWord) && endWord.equals(other.endWord) + && topics.equals(other.topics); + } + + @Override + public int hashCode() { return Objects.hash(text, startWord, endWord, topics); } + + public static Builder builder() { return new Builder(); } + + public static final class Builder { + private Optional text = Optional.empty(); + private Optional startWord = Optional.empty(); + private Optional endWord = Optional.empty(); + private Optional> topics = Optional.empty(); + private final Map additionalProperties = new HashMap<>(); + + private Builder() {} + + public Builder from(SharedTopicsResultsTopicsSegmentsItem other) { + return text(other.getText()).startWord(other.getStartWord()).endWord(other.getEndWord()).topics(other.getTopics()); + } + + public Builder text(Optional text) { this.text = text; return this; } + public Builder text(String text) { return text(Optional.ofNullable(text)); } + public Builder startWord(Optional startWord) { this.startWord = startWord; return this; } + public Builder startWord(Double startWord) { return startWord(Optional.ofNullable(startWord)); } + public Builder endWord(Optional endWord) { this.endWord = endWord; return this; } + public Builder endWord(Double endWord) { return endWord(Optional.ofNullable(endWord)); } + public Builder topics(Optional> topics) { this.topics = topics; return this; } + public Builder topics(List topics) { return topics(Optional.ofNullable(topics)); } + public Builder additionalProperty(String key, Object value) { additionalProperties.put(key, value); return this; } + public Builder additionalProperties(Map additionalProperties) { this.additionalProperties.putAll(additionalProperties); return this; } + + public SharedTopicsResultsTopicsSegmentsItem build() { + return new SharedTopicsResultsTopicsSegmentsItem(text, startWord, endWord, topics, additionalProperties); + } + } +} diff --git a/src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItemTopicsItem.java b/src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItemTopicsItem.java new file mode 100644 index 0000000..1fe70db --- /dev/null +++ b/src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItemTopicsItem.java @@ -0,0 +1,110 @@ +package com.deepgram.types; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +/** @deprecated Use {@link SharedTopicsSegmentsItemTopicsItem}. */ +@Deprecated +public final class SharedTopicsResultsTopicsSegmentsItemTopicsItem { + private final Optional topic; + private final Optional confidenceScore; + private final Map additionalProperties; + + private SharedTopicsResultsTopicsSegmentsItemTopicsItem( + Optional topic, Optional confidenceScore, Map additionalProperties) { + this.topic = topic; + this.confidenceScore = confidenceScore; + this.additionalProperties = additionalProperties; + } + + static SharedTopicsResultsTopicsSegmentsItemTopicsItem fromCurrent(SharedTopicsSegmentsItemTopicsItem value) { + return new SharedTopicsResultsTopicsSegmentsItemTopicsItem( + value.getTopic(), value.getConfidenceScore(), value.getAdditionalProperties()); + } + + SharedTopicsSegmentsItemTopicsItem toCurrent() { + return SharedTopicsSegmentsItemTopicsItem.builder() + .topic(topic) + .confidenceScore(confidenceScore) + .additionalProperties(additionalProperties) + .build(); + } + + public Optional getTopic() { + return topic; + } + + public Optional getConfidenceScore() { + return confidenceScore; + } + + public Map getAdditionalProperties() { + return additionalProperties; + } + + @Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof SharedTopicsResultsTopicsSegmentsItemTopicsItem + && equalTo((SharedTopicsResultsTopicsSegmentsItemTopicsItem) other); + } + + private boolean equalTo(SharedTopicsResultsTopicsSegmentsItemTopicsItem other) { + return topic.equals(other.topic) && confidenceScore.equals(other.confidenceScore); + } + + @Override + public int hashCode() { + return Objects.hash(topic, confidenceScore); + } + + public static Builder builder() { + return new Builder(); + } + + public static final class Builder { + private Optional topic = Optional.empty(); + private Optional confidenceScore = Optional.empty(); + private final Map additionalProperties = new HashMap<>(); + + private Builder() {} + + public Builder from(SharedTopicsResultsTopicsSegmentsItemTopicsItem other) { + return topic(other.getTopic()).confidenceScore(other.getConfidenceScore()); + } + + public Builder topic(Optional topic) { + this.topic = topic; + return this; + } + + public Builder topic(String topic) { + return topic(Optional.ofNullable(topic)); + } + + public Builder confidenceScore(Optional confidenceScore) { + this.confidenceScore = confidenceScore; + return this; + } + + public Builder confidenceScore(Float confidenceScore) { + return confidenceScore(Optional.ofNullable(confidenceScore)); + } + + public Builder additionalProperty(String key, Object value) { + additionalProperties.put(key, value); + return this; + } + + public Builder additionalProperties(Map additionalProperties) { + this.additionalProperties.putAll(additionalProperties); + return this; + } + + public SharedTopicsResultsTopicsSegmentsItemTopicsItem build() { + return new SharedTopicsResultsTopicsSegmentsItemTopicsItem(topic, confidenceScore, additionalProperties); + } + } +} diff --git a/src/test/java/com/deepgram/RegenTypesTest.java b/src/test/java/com/deepgram/RegenTypesTest.java index e0a44b5..a5d58d9 100644 --- a/src/test/java/com/deepgram/RegenTypesTest.java +++ b/src/test/java/com/deepgram/RegenTypesTest.java @@ -21,6 +21,7 @@ import com.deepgram.resources.listen.v2.types.ListenV2TurnInfoWordsItem; import com.deepgram.resources.listen.v2.types.ListenV2Warning; import com.deepgram.resources.speak.v2.types.SpeakV2Close; +import com.deepgram.resources.speak.v2.types.SpeakV2ConfigureFailureCode; import com.deepgram.resources.speak.v2.types.SpeakV2Flush; import com.deepgram.types.Deepgram; import com.deepgram.types.DeepgramListenProviderV2; @@ -32,7 +33,9 @@ import com.deepgram.types.ListenV1ResponseResultsChannelsItemAlternativesItemWordsItem; import com.deepgram.types.ListenV2Redact; import com.deepgram.types.SharedIntents; +import com.deepgram.types.SharedIntentsResultsIntentsSegmentsItem; import com.deepgram.types.SharedTopics; +import com.deepgram.types.SharedTopicsResultsTopicsSegmentsItem; import com.deepgram.types.ThinkSettingsV1FunctionsItem; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.Arrays; @@ -381,8 +384,8 @@ void wordsItemSpeakerConfidenceAbsent() throws Exception { } /** - * Coverage for the 2026-09-30 correction that removes the nonexistent nested {@code results} - * wrappers from Topics and Intents response objects. + * Coverage for the 2026-09-30 correction that exposes direct segments while preserving the + * removed nested {@code results} API as a deprecated source-compatible facade. */ @Nested @DisplayName("2026-09-30 Topics and Intents response shapes") @@ -421,6 +424,75 @@ void intentsDeserializeDirectSegments() throws Exception { }); }); } + + @Test + @DisplayName("SharedTopics exposes legacy results traversal over direct segments") + void topicsLegacyResultsFacade() throws Exception { + SharedTopics topics = MAPPER.readValue( + "{\"segments\":[{\"text\":\"Spacewalk\",\"topics\":[{\"topic\":\"Spacewalk\"}]}]}", + SharedTopics.class); + + assertThat(topics.getResults()).hasValueSatisfying(results -> { + assertThat(results.getTopics().flatMap(values -> values.getSegments())).hasValueSatisfying(segments -> { + SharedTopicsResultsTopicsSegmentsItem segment = segments.get(0); + assertThat(segment.getText()).contains("Spacewalk"); + }); + }); + } + + @Test + @DisplayName("SharedIntents exposes legacy results traversal over direct segments") + void intentsLegacyResultsFacade() throws Exception { + SharedIntents intents = MAPPER.readValue( + "{\"segments\":[{\"text\":\"Book a flight\",\"intents\":[{\"intent\":\"Book travel\"}]}]}", + SharedIntents.class); + + assertThat(intents.getResults()).hasValueSatisfying(results -> { + assertThat(results.getIntents().flatMap(values -> values.getSegments())).hasValueSatisfying(segments -> { + SharedIntentsResultsIntentsSegmentsItem segment = segments.get(0); + assertThat(segment.getText()).contains("Book a flight"); + }); + }); + } + } + + @Nested + @DisplayName("SpeakV2 ConfigureFailure visitor compatibility") + class ConfigureFailureVisitorCompatibility { + + @Test + @DisplayName("control combination invalid uses visitUnknown when an older visitor omits it") + void controlCombinationInvalidUsesUnknownVisitorMethod() { + SpeakV2ConfigureFailureCode.Visitor visitor = new SpeakV2ConfigureFailureCode.Visitor<>() { + @Override + public String visitSpeedOutOfRange() { + return "speed-out-of-range"; + } + + @Override + public String visitSpeedIncrementInvalid() { + return "speed-increment-invalid"; + } + + @Override + public String visitSpeedNotSupported() { + return "speed-not-supported"; + } + + @Override + public String visitInternalError() { + return "internal-error"; + } + + @Override + public String visitUnknown(String unknownType) { + return "unknown:" + unknownType; + } + }; + + assertThat(SpeakV2ConfigureFailureCode.CONTROL_COMBINATION_INVALID.visit(visitor)) + .isEqualTo("unknown:CONTROL_COMBINATION_INVALID"); + } } @Nested From 0f85e635e633c0b5384da4808af2398524303dc7 Mon Sep 17 00:00:00 2001 From: Greg Holmes Date: Wed, 14 Oct 2026 12:23:43 +0100 Subject: [PATCH 6/8] chore(regen): align Java release metadata --- .fern/metadata.json | 4 ++-- src/main/java/com/deepgram/core/ClientOptions.java | 12 +++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/.fern/metadata.json b/.fern/metadata.json index d4e496a..3c25483 100644 --- a/.fern/metadata.json +++ b/.fern/metadata.json @@ -15,5 +15,5 @@ "originGitCommit": "59a99c27e5f91158072fc98b3567fc88c3315f67", "originGitCommitIsDirty": true, "invokedBy": "manual", - "sdkVersion": "0.11.2" -} \ No newline at end of file + "sdkVersion": "0.11.1" +} diff --git a/src/main/java/com/deepgram/core/ClientOptions.java b/src/main/java/com/deepgram/core/ClientOptions.java index b20db7f..aceddaa 100644 --- a/src/main/java/com/deepgram/core/ClientOptions.java +++ b/src/main/java/com/deepgram/core/ClientOptions.java @@ -63,10 +63,10 @@ private ClientOptions( this.headers.putAll(headers); this.headers.putAll(new HashMap() { { - put("User-Agent", "com.deepgram:deepgram-java-sdk/0.11.2"); // x-release-please-version + put("User-Agent", "com.deepgram:deepgram-java-sdk/0.11.1"); // x-release-please-version put("X-Fern-Language", "JAVA"); put("X-Fern-SDK-Name", "com.deepgram:deepgram-java-sdk"); - put("X-Fern-SDK-Version", "0.11.2"); // x-release-please-version + put("X-Fern-SDK-Version", "0.11.1"); // x-release-please-version } }); this.headerSuppliers = headerSuppliers; @@ -144,10 +144,12 @@ public Optional retryJitterFactor() { * OkHttpClient itself; an OkHttpClient supplied via httpClient is left running, since the * caller owns its lifecycle. *

- * In-flight calls are not cancelled or awaited, and any request issued after this method - * returns fails with a {@code RejectedExecutionException}. Options derived from this one via + * In-flight calls are not cancelled or awaited. When this client owns the underlying + * OkHttpClient, requests issued after shutdown can fail with a + * {@code RejectedExecutionException}. Options derived from this one via * {@code Builder.from(...)} share the same dispatcher and connection pool, so closing either - * releases them for both. Calling this method more than once has no further effect. + * releases them for both. A caller-supplied OkHttpClient remains running. Calling this method + * more than once has no further effect. *

* WebSocket clients created from this client that are still connected are disconnected * first (whether or not the OkHttpClient is owned), so they stop reconnecting before the From 62f854ccc63b1ed541c0ba0c138425bca50bcc8f Mon Sep 17 00:00:00 2001 From: Greg Holmes Date: Wed, 14 Oct 2026 12:44:51 +0100 Subject: [PATCH 7/8] chore(regen): retain direct Topics and Intents API --- .fernignore | 13 --- AGENTS.md | 1 - .../com/deepgram/types/SharedIntents.java | 27 ----- .../deepgram/types/SharedIntentsResults.java | 56 --------- .../types/SharedIntentsResultsIntents.java | 64 ---------- ...aredIntentsResultsIntentsSegmentsItem.java | 106 ----------------- ...ResultsIntentsSegmentsItemIntentsItem.java | 77 ------------ .../java/com/deepgram/types/SharedTopics.java | 27 ----- .../deepgram/types/SharedTopicsResults.java | 56 --------- .../types/SharedTopicsResultsTopics.java | 64 ---------- ...SharedTopicsResultsTopicsSegmentsItem.java | 106 ----------------- ...csResultsTopicsSegmentsItemTopicsItem.java | 110 ------------------ .../java/com/deepgram/RegenTypesTest.java | 35 +----- 13 files changed, 2 insertions(+), 740 deletions(-) delete mode 100644 src/main/java/com/deepgram/types/SharedIntentsResults.java delete mode 100644 src/main/java/com/deepgram/types/SharedIntentsResultsIntents.java delete mode 100644 src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItem.java delete mode 100644 src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItemIntentsItem.java delete mode 100644 src/main/java/com/deepgram/types/SharedTopicsResults.java delete mode 100644 src/main/java/com/deepgram/types/SharedTopicsResultsTopics.java delete mode 100644 src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItem.java delete mode 100644 src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItemTopicsItem.java diff --git a/.fernignore b/.fernignore index 672b6b1..001477f 100644 --- a/.fernignore +++ b/.fernignore @@ -98,19 +98,6 @@ src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UpdateListenListenPro src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentListenProvider.java src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentContextListenProvider.java -# Backward-compatible Topics/Intents results facades preserve the removed traversal and -# renamed item types while the generated response models continue to use direct segments. -src/main/java/com/deepgram/types/SharedTopics.java -src/main/java/com/deepgram/types/SharedTopicsResults.java -src/main/java/com/deepgram/types/SharedTopicsResultsTopics.java -src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItem.java -src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItemTopicsItem.java -src/main/java/com/deepgram/types/SharedIntents.java -src/main/java/com/deepgram/types/SharedIntentsResults.java -src/main/java/com/deepgram/types/SharedIntentsResultsIntents.java -src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItem.java -src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItemIntentsItem.java - # Preserve binary-compatible Visitor implementations from before this generated enum added # CONTROL_COMBINATION_INVALID. The default method routes old visitors through visitUnknown. src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2ConfigureFailureCode.java diff --git a/AGENTS.md b/AGENTS.md index 33fd192..fdb40f5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -55,7 +55,6 @@ Current temporarily frozen files: - Fields-less message types carrying a manual `hashCode()` patch (Fern generates `equals()` but no `hashCode()` for these, violating the Object contract): `src/main/java/com/deepgram/resources/listen/v2/types/ListenV2CloseStream.java`, `src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ForceEndTurn.java`, `src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Close.java`, `src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Flush.java`, and the `AgentV1*` event types `src/main/java/com/deepgram/resources/agent/v1/types/{AgentV1ListenUpdated,AgentV1SpeakUpdated,AgentV1AgentAudioDone,AgentV1SettingsApplied,AgentV1UserStartedSpeaking,AgentV1KeepAlive,AgentV1ThinkUpdated,AgentV1PromptUpdated,AgentV1ForceEndTurn}.java`. Use the standard `.bak` swap/restore workflow during regen review; drop the patches and unfreeze all of them once the generator emits a matching equals/hashCode pair for fields-less types (tracked as an upstream Fern request). - `src/main/java/com/deepgram/types/DeepgramModel.java` - restores the `FLUX_RENEE_EN` constant that generator 4.18.0 dropped. The voice is live: `POST /v2/speak?model=flux-renee-en` returns 200 with valid audio, and the name resolves in the server's model registry (an invented `flux-*` name is rejected with `INVALID_QUERY_PARAMETER`), so the removal is a spec regression rather than a retirement, and dropping the constant would break 0.8.0 callers for nothing. Five touchpoints: the constant, the `Value` enum entry, the `visit()` case, the `valueOf()` case, and the `Visitor` method. **This file is unlike the other temporarily frozen ones — it receives frequent additive spec changes (4.18.0 alone added 25 constants), so on the next regen do NOT restore the `.bak` wholesale.** Diff the `.bak` against the newly generated file, carry forward every new voice, and re-apply only the `FLUX_RENEE_EN` touchpoints. Drop the patch and unfreeze once the spec lists the voice again (tracked as an upstream spec request). - Union default-variant fix on the agent listen-provider unions: `src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UpdateListenListenProvider.java`, `src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentListenProvider.java`, `src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentContextListenProvider.java`. `version` is an optional discriminator, so a provider payload without it is valid (and is what 0.7.x emits), but Fern points `@JsonTypeInfo` `defaultImpl` at the empty-bodied `_UnknownValue`, so such a payload deserializes to an unknown variant carrying `null` — `getProvider()` returns `null` and re-serialization emits `{"provider":null}`, silently dropping the provider on the wire. Patched to `defaultImpl = V2Value` on each; guarded by `src/test/java/com/deepgram/AgentSettingsProviderDefaultTest.java`. Use the standard `.bak` swap/restore workflow during regen review; drop the patches and unfreeze once the generator stops defaulting unions to the empty `_UnknownValue` (tracked as an upstream Fern request). -- `src/main/java/com/deepgram/types/SharedTopics.java`, `SharedIntents.java`, and the eight `Shared{Topics,Intents}Results...` facade types preserve the pre-0.11 `results.*.segments` traversal and renamed item classes while retaining the generated direct `segments` payload model. The facades translate legacy builders and accessors to the current generated types and are deliberately excluded from JSON serialization. Guarded by `src/test/java/com/deepgram/RegenTypesTest.java`. Keep these frozen until the next major release. - `src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2ConfigureFailureCode.java` makes `Visitor.visitControlCombinationInvalid()` a default method that delegates to `visitUnknown("CONTROL_COMBINATION_INVALID")`. This preserves source compatibility for visitors compiled against the pre-controls API while retaining the new generated enum value. Guarded by `src/test/java/com/deepgram/RegenTypesTest.java`. Keep frozen until the next major release. ### Prepare repo for regeneration diff --git a/src/main/java/com/deepgram/types/SharedIntents.java b/src/main/java/com/deepgram/types/SharedIntents.java index 4a04305..05799c2 100644 --- a/src/main/java/com/deepgram/types/SharedIntents.java +++ b/src/main/java/com/deepgram/types/SharedIntents.java @@ -6,7 +6,6 @@ import com.deepgram.core.ObjectMappers; import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.annotation.JsonAnySetter; -import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; @@ -37,15 +36,6 @@ public Optional> getSegments() { return segments; } - /** - * @deprecated The API returns segments directly. Use {@link #getSegments()}. - */ - @Deprecated - @JsonIgnore - public Optional getResults() { - return segments.map(SharedIntentsResults::fromCurrent); - } - @java.lang.Override public boolean equals(Object other) { if (this == other) return true; @@ -100,23 +90,6 @@ public Builder segments(List segments) { return this; } - /** - * @deprecated The API returns segments directly. Use {@link #segments(List)}. - */ - @Deprecated - public Builder results(Optional results) { - this.segments = results.flatMap(SharedIntentsResults::toCurrentSegments); - return this; - } - - /** - * @deprecated The API returns segments directly. Use {@link #segments(List)}. - */ - @Deprecated - public Builder results(SharedIntentsResults results) { - return results(Optional.ofNullable(results)); - } - public SharedIntents build() { return new SharedIntents(segments, additionalProperties); } diff --git a/src/main/java/com/deepgram/types/SharedIntentsResults.java b/src/main/java/com/deepgram/types/SharedIntentsResults.java deleted file mode 100644 index 35a406a..0000000 --- a/src/main/java/com/deepgram/types/SharedIntentsResults.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.deepgram.types; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; - -/** @deprecated Use {@link SharedIntents#getSegments()}. */ -@Deprecated -public final class SharedIntentsResults { - private final Optional intents; - private final Map additionalProperties; - - private SharedIntentsResults(Optional intents, Map additionalProperties) { - this.intents = intents; - this.additionalProperties = additionalProperties; - } - - static SharedIntentsResults fromCurrent(List segments) { - return new SharedIntentsResults(Optional.of(SharedIntentsResultsIntents.fromCurrent(segments)), new HashMap<>()); - } - - Optional> toCurrentSegments() { - return intents.flatMap(SharedIntentsResultsIntents::toCurrentSegments); - } - - public Optional getIntents() { return intents; } - public Map getAdditionalProperties() { return additionalProperties; } - - @Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof SharedIntentsResults && intents.equals(((SharedIntentsResults) other).intents); - } - - @Override - public int hashCode() { return Objects.hash(intents); } - - public static Builder builder() { return new Builder(); } - - public static final class Builder { - private Optional intents = Optional.empty(); - private final Map additionalProperties = new HashMap<>(); - - private Builder() {} - - public Builder from(SharedIntentsResults other) { return intents(other.getIntents()); } - public Builder intents(Optional intents) { this.intents = intents; return this; } - public Builder intents(SharedIntentsResultsIntents intents) { return intents(Optional.ofNullable(intents)); } - public Builder additionalProperty(String key, Object value) { additionalProperties.put(key, value); return this; } - public Builder additionalProperties(Map additionalProperties) { this.additionalProperties.putAll(additionalProperties); return this; } - - public SharedIntentsResults build() { return new SharedIntentsResults(intents, additionalProperties); } - } -} diff --git a/src/main/java/com/deepgram/types/SharedIntentsResultsIntents.java b/src/main/java/com/deepgram/types/SharedIntentsResultsIntents.java deleted file mode 100644 index 1a403cf..0000000 --- a/src/main/java/com/deepgram/types/SharedIntentsResultsIntents.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.deepgram.types; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.stream.Collectors; - -/** @deprecated Use {@link SharedIntents#getSegments()}. */ -@Deprecated -public final class SharedIntentsResultsIntents { - private final Optional> segments; - private final Map additionalProperties; - - private SharedIntentsResultsIntents( - Optional> segments, Map additionalProperties) { - this.segments = segments; - this.additionalProperties = additionalProperties; - } - - static SharedIntentsResultsIntents fromCurrent(List segments) { - return new SharedIntentsResultsIntents( - Optional.of(segments.stream() - .map(SharedIntentsResultsIntentsSegmentsItem::fromCurrent) - .collect(Collectors.toList())), - new HashMap<>()); - } - - Optional> toCurrentSegments() { - return segments.map(values -> values.stream() - .map(SharedIntentsResultsIntentsSegmentsItem::toCurrent) - .collect(Collectors.toList())); - } - - public Optional> getSegments() { return segments; } - public Map getAdditionalProperties() { return additionalProperties; } - - @Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof SharedIntentsResultsIntents && segments.equals(((SharedIntentsResultsIntents) other).segments); - } - - @Override - public int hashCode() { return Objects.hash(segments); } - - public static Builder builder() { return new Builder(); } - - public static final class Builder { - private Optional> segments = Optional.empty(); - private final Map additionalProperties = new HashMap<>(); - - private Builder() {} - - public Builder from(SharedIntentsResultsIntents other) { return segments(other.getSegments()); } - public Builder segments(Optional> segments) { this.segments = segments; return this; } - public Builder segments(List segments) { return segments(Optional.ofNullable(segments)); } - public Builder additionalProperty(String key, Object value) { additionalProperties.put(key, value); return this; } - public Builder additionalProperties(Map additionalProperties) { this.additionalProperties.putAll(additionalProperties); return this; } - - public SharedIntentsResultsIntents build() { return new SharedIntentsResultsIntents(segments, additionalProperties); } - } -} diff --git a/src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItem.java b/src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItem.java deleted file mode 100644 index bdaac01..0000000 --- a/src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItem.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.deepgram.types; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.stream.Collectors; - -/** @deprecated Use {@link SharedIntentsSegmentsItem}. */ -@Deprecated -public final class SharedIntentsResultsIntentsSegmentsItem { - private final Optional text; - private final Optional startWord; - private final Optional endWord; - private final Optional> intents; - private final Map additionalProperties; - - private SharedIntentsResultsIntentsSegmentsItem( - Optional text, - Optional startWord, - Optional endWord, - Optional> intents, - Map additionalProperties) { - this.text = text; - this.startWord = startWord; - this.endWord = endWord; - this.intents = intents; - this.additionalProperties = additionalProperties; - } - - static SharedIntentsResultsIntentsSegmentsItem fromCurrent(SharedIntentsSegmentsItem value) { - return new SharedIntentsResultsIntentsSegmentsItem( - value.getText(), - value.getStartWord(), - value.getEndWord(), - value.getIntents().map(items -> items.stream() - .map(SharedIntentsResultsIntentsSegmentsItemIntentsItem::fromCurrent) - .collect(Collectors.toList())), - value.getAdditionalProperties()); - } - - SharedIntentsSegmentsItem toCurrent() { - return SharedIntentsSegmentsItem.builder() - .text(text) - .startWord(startWord) - .endWord(endWord) - .intents(intents.map(items -> items.stream() - .map(SharedIntentsResultsIntentsSegmentsItemIntentsItem::toCurrent) - .collect(Collectors.toList()))) - .additionalProperties(additionalProperties) - .build(); - } - - public Optional getText() { return text; } - public Optional getStartWord() { return startWord; } - public Optional getEndWord() { return endWord; } - public Optional> getIntents() { return intents; } - public Map getAdditionalProperties() { return additionalProperties; } - - @Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof SharedIntentsResultsIntentsSegmentsItem - && equalTo((SharedIntentsResultsIntentsSegmentsItem) other); - } - - private boolean equalTo(SharedIntentsResultsIntentsSegmentsItem other) { - return text.equals(other.text) && startWord.equals(other.startWord) && endWord.equals(other.endWord) - && intents.equals(other.intents); - } - - @Override - public int hashCode() { return Objects.hash(text, startWord, endWord, intents); } - - public static Builder builder() { return new Builder(); } - - public static final class Builder { - private Optional text = Optional.empty(); - private Optional startWord = Optional.empty(); - private Optional endWord = Optional.empty(); - private Optional> intents = Optional.empty(); - private final Map additionalProperties = new HashMap<>(); - - private Builder() {} - - public Builder from(SharedIntentsResultsIntentsSegmentsItem other) { - return text(other.getText()).startWord(other.getStartWord()).endWord(other.getEndWord()).intents(other.getIntents()); - } - - public Builder text(Optional text) { this.text = text; return this; } - public Builder text(String text) { return text(Optional.ofNullable(text)); } - public Builder startWord(Optional startWord) { this.startWord = startWord; return this; } - public Builder startWord(Double startWord) { return startWord(Optional.ofNullable(startWord)); } - public Builder endWord(Optional endWord) { this.endWord = endWord; return this; } - public Builder endWord(Double endWord) { return endWord(Optional.ofNullable(endWord)); } - public Builder intents(Optional> intents) { this.intents = intents; return this; } - public Builder intents(List intents) { return intents(Optional.ofNullable(intents)); } - public Builder additionalProperty(String key, Object value) { additionalProperties.put(key, value); return this; } - public Builder additionalProperties(Map additionalProperties) { this.additionalProperties.putAll(additionalProperties); return this; } - - public SharedIntentsResultsIntentsSegmentsItem build() { - return new SharedIntentsResultsIntentsSegmentsItem(text, startWord, endWord, intents, additionalProperties); - } - } -} diff --git a/src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItemIntentsItem.java b/src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItemIntentsItem.java deleted file mode 100644 index 43c948f..0000000 --- a/src/main/java/com/deepgram/types/SharedIntentsResultsIntentsSegmentsItemIntentsItem.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.deepgram.types; - -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; - -/** @deprecated Use {@link SharedIntentsSegmentsItemIntentsItem}. */ -@Deprecated -public final class SharedIntentsResultsIntentsSegmentsItemIntentsItem { - private final Optional intent; - private final Optional confidenceScore; - private final Map additionalProperties; - - private SharedIntentsResultsIntentsSegmentsItemIntentsItem( - Optional intent, Optional confidenceScore, Map additionalProperties) { - this.intent = intent; - this.confidenceScore = confidenceScore; - this.additionalProperties = additionalProperties; - } - - static SharedIntentsResultsIntentsSegmentsItemIntentsItem fromCurrent(SharedIntentsSegmentsItemIntentsItem value) { - return new SharedIntentsResultsIntentsSegmentsItemIntentsItem( - value.getIntent(), value.getConfidenceScore(), value.getAdditionalProperties()); - } - - SharedIntentsSegmentsItemIntentsItem toCurrent() { - return SharedIntentsSegmentsItemIntentsItem.builder() - .intent(intent) - .confidenceScore(confidenceScore) - .additionalProperties(additionalProperties) - .build(); - } - - public Optional getIntent() { return intent; } - public Optional getConfidenceScore() { return confidenceScore; } - public Map getAdditionalProperties() { return additionalProperties; } - - @Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof SharedIntentsResultsIntentsSegmentsItemIntentsItem - && equalTo((SharedIntentsResultsIntentsSegmentsItemIntentsItem) other); - } - - private boolean equalTo(SharedIntentsResultsIntentsSegmentsItemIntentsItem other) { - return intent.equals(other.intent) && confidenceScore.equals(other.confidenceScore); - } - - @Override - public int hashCode() { return Objects.hash(intent, confidenceScore); } - - public static Builder builder() { return new Builder(); } - - public static final class Builder { - private Optional intent = Optional.empty(); - private Optional confidenceScore = Optional.empty(); - private final Map additionalProperties = new HashMap<>(); - - private Builder() {} - - public Builder from(SharedIntentsResultsIntentsSegmentsItemIntentsItem other) { - return intent(other.getIntent()).confidenceScore(other.getConfidenceScore()); - } - - public Builder intent(Optional intent) { this.intent = intent; return this; } - public Builder intent(String intent) { return intent(Optional.ofNullable(intent)); } - public Builder confidenceScore(Optional confidenceScore) { this.confidenceScore = confidenceScore; return this; } - public Builder confidenceScore(Float confidenceScore) { return confidenceScore(Optional.ofNullable(confidenceScore)); } - public Builder additionalProperty(String key, Object value) { additionalProperties.put(key, value); return this; } - public Builder additionalProperties(Map additionalProperties) { this.additionalProperties.putAll(additionalProperties); return this; } - - public SharedIntentsResultsIntentsSegmentsItemIntentsItem build() { - return new SharedIntentsResultsIntentsSegmentsItemIntentsItem(intent, confidenceScore, additionalProperties); - } - } -} diff --git a/src/main/java/com/deepgram/types/SharedTopics.java b/src/main/java/com/deepgram/types/SharedTopics.java index f2e2765..25a75ea 100644 --- a/src/main/java/com/deepgram/types/SharedTopics.java +++ b/src/main/java/com/deepgram/types/SharedTopics.java @@ -6,7 +6,6 @@ import com.deepgram.core.ObjectMappers; import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.annotation.JsonAnySetter; -import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; @@ -36,15 +35,6 @@ public Optional> getSegments() { return segments; } - /** - * @deprecated The API returns segments directly. Use {@link #getSegments()}. - */ - @Deprecated - @JsonIgnore - public Optional getResults() { - return segments.map(SharedTopicsResults::fromCurrent); - } - @java.lang.Override public boolean equals(Object other) { if (this == other) return true; @@ -99,23 +89,6 @@ public Builder segments(List segments) { return this; } - /** - * @deprecated The API returns segments directly. Use {@link #segments(List)}. - */ - @Deprecated - public Builder results(Optional results) { - this.segments = results.flatMap(SharedTopicsResults::toCurrentSegments); - return this; - } - - /** - * @deprecated The API returns segments directly. Use {@link #segments(List)}. - */ - @Deprecated - public Builder results(SharedTopicsResults results) { - return results(Optional.ofNullable(results)); - } - public SharedTopics build() { return new SharedTopics(segments, additionalProperties); } diff --git a/src/main/java/com/deepgram/types/SharedTopicsResults.java b/src/main/java/com/deepgram/types/SharedTopicsResults.java deleted file mode 100644 index 77372bd..0000000 --- a/src/main/java/com/deepgram/types/SharedTopicsResults.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.deepgram.types; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; - -/** @deprecated Use {@link SharedTopics#getSegments()}. */ -@Deprecated -public final class SharedTopicsResults { - private final Optional topics; - private final Map additionalProperties; - - private SharedTopicsResults(Optional topics, Map additionalProperties) { - this.topics = topics; - this.additionalProperties = additionalProperties; - } - - static SharedTopicsResults fromCurrent(List segments) { - return new SharedTopicsResults(Optional.of(SharedTopicsResultsTopics.fromCurrent(segments)), new HashMap<>()); - } - - Optional> toCurrentSegments() { - return topics.flatMap(SharedTopicsResultsTopics::toCurrentSegments); - } - - public Optional getTopics() { return topics; } - public Map getAdditionalProperties() { return additionalProperties; } - - @Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof SharedTopicsResults && topics.equals(((SharedTopicsResults) other).topics); - } - - @Override - public int hashCode() { return Objects.hash(topics); } - - public static Builder builder() { return new Builder(); } - - public static final class Builder { - private Optional topics = Optional.empty(); - private final Map additionalProperties = new HashMap<>(); - - private Builder() {} - - public Builder from(SharedTopicsResults other) { return topics(other.getTopics()); } - public Builder topics(Optional topics) { this.topics = topics; return this; } - public Builder topics(SharedTopicsResultsTopics topics) { return topics(Optional.ofNullable(topics)); } - public Builder additionalProperty(String key, Object value) { additionalProperties.put(key, value); return this; } - public Builder additionalProperties(Map additionalProperties) { this.additionalProperties.putAll(additionalProperties); return this; } - - public SharedTopicsResults build() { return new SharedTopicsResults(topics, additionalProperties); } - } -} diff --git a/src/main/java/com/deepgram/types/SharedTopicsResultsTopics.java b/src/main/java/com/deepgram/types/SharedTopicsResultsTopics.java deleted file mode 100644 index 6aaa981..0000000 --- a/src/main/java/com/deepgram/types/SharedTopicsResultsTopics.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.deepgram.types; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.stream.Collectors; - -/** @deprecated Use {@link SharedTopics#getSegments()}. */ -@Deprecated -public final class SharedTopicsResultsTopics { - private final Optional> segments; - private final Map additionalProperties; - - private SharedTopicsResultsTopics( - Optional> segments, Map additionalProperties) { - this.segments = segments; - this.additionalProperties = additionalProperties; - } - - static SharedTopicsResultsTopics fromCurrent(List segments) { - return new SharedTopicsResultsTopics( - Optional.of(segments.stream() - .map(SharedTopicsResultsTopicsSegmentsItem::fromCurrent) - .collect(Collectors.toList())), - new HashMap<>()); - } - - Optional> toCurrentSegments() { - return segments.map(values -> values.stream() - .map(SharedTopicsResultsTopicsSegmentsItem::toCurrent) - .collect(Collectors.toList())); - } - - public Optional> getSegments() { return segments; } - public Map getAdditionalProperties() { return additionalProperties; } - - @Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof SharedTopicsResultsTopics && segments.equals(((SharedTopicsResultsTopics) other).segments); - } - - @Override - public int hashCode() { return Objects.hash(segments); } - - public static Builder builder() { return new Builder(); } - - public static final class Builder { - private Optional> segments = Optional.empty(); - private final Map additionalProperties = new HashMap<>(); - - private Builder() {} - - public Builder from(SharedTopicsResultsTopics other) { return segments(other.getSegments()); } - public Builder segments(Optional> segments) { this.segments = segments; return this; } - public Builder segments(List segments) { return segments(Optional.ofNullable(segments)); } - public Builder additionalProperty(String key, Object value) { additionalProperties.put(key, value); return this; } - public Builder additionalProperties(Map additionalProperties) { this.additionalProperties.putAll(additionalProperties); return this; } - - public SharedTopicsResultsTopics build() { return new SharedTopicsResultsTopics(segments, additionalProperties); } - } -} diff --git a/src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItem.java b/src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItem.java deleted file mode 100644 index da2fedb..0000000 --- a/src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItem.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.deepgram.types; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.stream.Collectors; - -/** @deprecated Use {@link SharedTopicsSegmentsItem}. */ -@Deprecated -public final class SharedTopicsResultsTopicsSegmentsItem { - private final Optional text; - private final Optional startWord; - private final Optional endWord; - private final Optional> topics; - private final Map additionalProperties; - - private SharedTopicsResultsTopicsSegmentsItem( - Optional text, - Optional startWord, - Optional endWord, - Optional> topics, - Map additionalProperties) { - this.text = text; - this.startWord = startWord; - this.endWord = endWord; - this.topics = topics; - this.additionalProperties = additionalProperties; - } - - static SharedTopicsResultsTopicsSegmentsItem fromCurrent(SharedTopicsSegmentsItem value) { - return new SharedTopicsResultsTopicsSegmentsItem( - value.getText(), - value.getStartWord(), - value.getEndWord(), - value.getTopics().map(items -> items.stream() - .map(SharedTopicsResultsTopicsSegmentsItemTopicsItem::fromCurrent) - .collect(Collectors.toList())), - value.getAdditionalProperties()); - } - - SharedTopicsSegmentsItem toCurrent() { - return SharedTopicsSegmentsItem.builder() - .text(text) - .startWord(startWord) - .endWord(endWord) - .topics(topics.map(items -> items.stream() - .map(SharedTopicsResultsTopicsSegmentsItemTopicsItem::toCurrent) - .collect(Collectors.toList()))) - .additionalProperties(additionalProperties) - .build(); - } - - public Optional getText() { return text; } - public Optional getStartWord() { return startWord; } - public Optional getEndWord() { return endWord; } - public Optional> getTopics() { return topics; } - public Map getAdditionalProperties() { return additionalProperties; } - - @Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof SharedTopicsResultsTopicsSegmentsItem - && equalTo((SharedTopicsResultsTopicsSegmentsItem) other); - } - - private boolean equalTo(SharedTopicsResultsTopicsSegmentsItem other) { - return text.equals(other.text) && startWord.equals(other.startWord) && endWord.equals(other.endWord) - && topics.equals(other.topics); - } - - @Override - public int hashCode() { return Objects.hash(text, startWord, endWord, topics); } - - public static Builder builder() { return new Builder(); } - - public static final class Builder { - private Optional text = Optional.empty(); - private Optional startWord = Optional.empty(); - private Optional endWord = Optional.empty(); - private Optional> topics = Optional.empty(); - private final Map additionalProperties = new HashMap<>(); - - private Builder() {} - - public Builder from(SharedTopicsResultsTopicsSegmentsItem other) { - return text(other.getText()).startWord(other.getStartWord()).endWord(other.getEndWord()).topics(other.getTopics()); - } - - public Builder text(Optional text) { this.text = text; return this; } - public Builder text(String text) { return text(Optional.ofNullable(text)); } - public Builder startWord(Optional startWord) { this.startWord = startWord; return this; } - public Builder startWord(Double startWord) { return startWord(Optional.ofNullable(startWord)); } - public Builder endWord(Optional endWord) { this.endWord = endWord; return this; } - public Builder endWord(Double endWord) { return endWord(Optional.ofNullable(endWord)); } - public Builder topics(Optional> topics) { this.topics = topics; return this; } - public Builder topics(List topics) { return topics(Optional.ofNullable(topics)); } - public Builder additionalProperty(String key, Object value) { additionalProperties.put(key, value); return this; } - public Builder additionalProperties(Map additionalProperties) { this.additionalProperties.putAll(additionalProperties); return this; } - - public SharedTopicsResultsTopicsSegmentsItem build() { - return new SharedTopicsResultsTopicsSegmentsItem(text, startWord, endWord, topics, additionalProperties); - } - } -} diff --git a/src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItemTopicsItem.java b/src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItemTopicsItem.java deleted file mode 100644 index 1fe70db..0000000 --- a/src/main/java/com/deepgram/types/SharedTopicsResultsTopicsSegmentsItemTopicsItem.java +++ /dev/null @@ -1,110 +0,0 @@ -package com.deepgram.types; - -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; - -/** @deprecated Use {@link SharedTopicsSegmentsItemTopicsItem}. */ -@Deprecated -public final class SharedTopicsResultsTopicsSegmentsItemTopicsItem { - private final Optional topic; - private final Optional confidenceScore; - private final Map additionalProperties; - - private SharedTopicsResultsTopicsSegmentsItemTopicsItem( - Optional topic, Optional confidenceScore, Map additionalProperties) { - this.topic = topic; - this.confidenceScore = confidenceScore; - this.additionalProperties = additionalProperties; - } - - static SharedTopicsResultsTopicsSegmentsItemTopicsItem fromCurrent(SharedTopicsSegmentsItemTopicsItem value) { - return new SharedTopicsResultsTopicsSegmentsItemTopicsItem( - value.getTopic(), value.getConfidenceScore(), value.getAdditionalProperties()); - } - - SharedTopicsSegmentsItemTopicsItem toCurrent() { - return SharedTopicsSegmentsItemTopicsItem.builder() - .topic(topic) - .confidenceScore(confidenceScore) - .additionalProperties(additionalProperties) - .build(); - } - - public Optional getTopic() { - return topic; - } - - public Optional getConfidenceScore() { - return confidenceScore; - } - - public Map getAdditionalProperties() { - return additionalProperties; - } - - @Override - public boolean equals(Object other) { - if (this == other) return true; - return other instanceof SharedTopicsResultsTopicsSegmentsItemTopicsItem - && equalTo((SharedTopicsResultsTopicsSegmentsItemTopicsItem) other); - } - - private boolean equalTo(SharedTopicsResultsTopicsSegmentsItemTopicsItem other) { - return topic.equals(other.topic) && confidenceScore.equals(other.confidenceScore); - } - - @Override - public int hashCode() { - return Objects.hash(topic, confidenceScore); - } - - public static Builder builder() { - return new Builder(); - } - - public static final class Builder { - private Optional topic = Optional.empty(); - private Optional confidenceScore = Optional.empty(); - private final Map additionalProperties = new HashMap<>(); - - private Builder() {} - - public Builder from(SharedTopicsResultsTopicsSegmentsItemTopicsItem other) { - return topic(other.getTopic()).confidenceScore(other.getConfidenceScore()); - } - - public Builder topic(Optional topic) { - this.topic = topic; - return this; - } - - public Builder topic(String topic) { - return topic(Optional.ofNullable(topic)); - } - - public Builder confidenceScore(Optional confidenceScore) { - this.confidenceScore = confidenceScore; - return this; - } - - public Builder confidenceScore(Float confidenceScore) { - return confidenceScore(Optional.ofNullable(confidenceScore)); - } - - public Builder additionalProperty(String key, Object value) { - additionalProperties.put(key, value); - return this; - } - - public Builder additionalProperties(Map additionalProperties) { - this.additionalProperties.putAll(additionalProperties); - return this; - } - - public SharedTopicsResultsTopicsSegmentsItemTopicsItem build() { - return new SharedTopicsResultsTopicsSegmentsItemTopicsItem(topic, confidenceScore, additionalProperties); - } - } -} diff --git a/src/test/java/com/deepgram/RegenTypesTest.java b/src/test/java/com/deepgram/RegenTypesTest.java index a5d58d9..554853d 100644 --- a/src/test/java/com/deepgram/RegenTypesTest.java +++ b/src/test/java/com/deepgram/RegenTypesTest.java @@ -33,9 +33,7 @@ import com.deepgram.types.ListenV1ResponseResultsChannelsItemAlternativesItemWordsItem; import com.deepgram.types.ListenV2Redact; import com.deepgram.types.SharedIntents; -import com.deepgram.types.SharedIntentsResultsIntentsSegmentsItem; import com.deepgram.types.SharedTopics; -import com.deepgram.types.SharedTopicsResultsTopicsSegmentsItem; import com.deepgram.types.ThinkSettingsV1FunctionsItem; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.Arrays; @@ -384,8 +382,8 @@ void wordsItemSpeakerConfidenceAbsent() throws Exception { } /** - * Coverage for the 2026-09-30 correction that exposes direct segments while preserving the - * removed nested {@code results} API as a deprecated source-compatible facade. + * Coverage for the 2026-09-30 correction that removes the nonexistent nested {@code results} + * wrappers from Topics and Intents response objects. */ @Nested @DisplayName("2026-09-30 Topics and Intents response shapes") @@ -425,35 +423,6 @@ void intentsDeserializeDirectSegments() throws Exception { }); } - @Test - @DisplayName("SharedTopics exposes legacy results traversal over direct segments") - void topicsLegacyResultsFacade() throws Exception { - SharedTopics topics = MAPPER.readValue( - "{\"segments\":[{\"text\":\"Spacewalk\",\"topics\":[{\"topic\":\"Spacewalk\"}]}]}", - SharedTopics.class); - - assertThat(topics.getResults()).hasValueSatisfying(results -> { - assertThat(results.getTopics().flatMap(values -> values.getSegments())).hasValueSatisfying(segments -> { - SharedTopicsResultsTopicsSegmentsItem segment = segments.get(0); - assertThat(segment.getText()).contains("Spacewalk"); - }); - }); - } - - @Test - @DisplayName("SharedIntents exposes legacy results traversal over direct segments") - void intentsLegacyResultsFacade() throws Exception { - SharedIntents intents = MAPPER.readValue( - "{\"segments\":[{\"text\":\"Book a flight\",\"intents\":[{\"intent\":\"Book travel\"}]}]}", - SharedIntents.class); - - assertThat(intents.getResults()).hasValueSatisfying(results -> { - assertThat(results.getIntents().flatMap(values -> values.getSegments())).hasValueSatisfying(segments -> { - SharedIntentsResultsIntentsSegmentsItem segment = segments.get(0); - assertThat(segment.getText()).contains("Book a flight"); - }); - }); - } } @Nested From c63d88fabdd3b380ece73118bdc8ddebcc53c6dd Mon Sep 17 00:00:00 2001 From: Corey Weathers Date: Wed, 14 Oct 2026 10:11:58 -0400 Subject: [PATCH 8/8] docs(regen): correct close() and keyterm-limit docs, clarify Renee deprecation - Restore the accurate ClientOptions.close() Javadoc: synchronous requests still run after close(); only asynchronous requests hit the rejected dispatcher. - Make the FLUX_RENEE_EN deprecation note actionable (unlisted voice, prefer a listed one from GET /v2/models), and annotate the v0.8 to v0.9 migration guide. - Update AGENTS.md: Renee was delisted on purpose, so drop it at the next major release; add the .bak workflow to the SpeakV2ConfigureFailureCode entry. - README and LiveReconfigure example: an over-limit keyterm update does not close the stream (verified in prod); the server may send a ConfigureFailure, which the V1 client reports to onError. Co-Authored-By: Claude Opus 5.5 --- AGENTS.md | 4 ++-- README.md | 4 ++-- docs/Migrating-v0.8-to-v0.9.md | 2 ++ examples/listen/LiveReconfigure.java | 5 +++-- src/main/java/com/deepgram/core/ClientOptions.java | 6 +++--- src/main/java/com/deepgram/types/DeepgramModel.java | 10 ++++++++-- 6 files changed, 20 insertions(+), 11 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index fdb40f5..ecec18a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -53,9 +53,9 @@ Current temporarily frozen files: - `src/main/java/com/deepgram/resources/speak/v2/websocket/V2WebSocketClient.java` and `src/main/java/com/deepgram/resources/listen/v2/websocket/V2WebSocketClient.java` - forward-compat patch (both clients). Fern's generated `handleIncomingMessage` dispatcher routes any unrecognized message type to `onError` with "Update your SDK version...", which makes a benign new server control frame look fatal to a deployed client. Patched so the unrecognized-type branch is a no-op — the raw frame is already delivered via `onMessage(String)` earlier in the method, so consumers still see it. Mirrors the JS/Python SDKs' forward-compat behavior and is regression-guarded by `src/test/java/com/deepgram/SpeakV2ForwardCompatTest.java` and `src/test/java/com/deepgram/ListenV2ForwardCompatTest.java`. These two clients also carry the streaming query-param patches described in the next entry. Use the standard `.bak` swap/restore workflow during regen review; re-apply the no-op to both after regen, and unfreeze once the generator stops treating unknown frames as errors. - `src/main/java/com/deepgram/resources/listen/v1/websocket/V1WebSocketClient.java` and `src/main/java/com/deepgram/resources/speak/v1/websocket/V1WebSocketClient.java` (and the v2 clients above) - streaming query-param patches on the generated `connect()` builders. Two fixes: (1) multi-value serialization — array-valued params (listen: `keyterm`, `keywords`, `replace`, `search`, `tag`, `extra`, `language_hint`; speak: `tag`) were serialized with `String.valueOf(union.get())`, collapsing a `List` into one param (`keyterm=[a, b]`) instead of repeats (`keyterm=a&keyterm=b`); (2) an `additionalProperties` escape hatch — the builder exposes `additionalProperty(key, value)` for unmodeled params (e.g. `no_delay`) but `connect()` never emitted them to the URL. Both patched to route through `QueryStringMapper(arraysAsRepeats=true)`, matching the REST path. Listen V1 also forwards a parsed server `Error` to `onError` as a `ListenV1ErrorException` (carrying the typed `ListenV1Error`) when no `onErrorMessage` handler is registered, preserving the prior generic error-handler behavior. Use the standard `.bak` swap/restore workflow during regen review; re-apply after regen and unfreeze once the generator emits array params as repeats and serializes `additionalProperties` on the WS `connect()` path (tracked as an upstream Fern request). - Fields-less message types carrying a manual `hashCode()` patch (Fern generates `equals()` but no `hashCode()` for these, violating the Object contract): `src/main/java/com/deepgram/resources/listen/v2/types/ListenV2CloseStream.java`, `src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ForceEndTurn.java`, `src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Close.java`, `src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Flush.java`, and the `AgentV1*` event types `src/main/java/com/deepgram/resources/agent/v1/types/{AgentV1ListenUpdated,AgentV1SpeakUpdated,AgentV1AgentAudioDone,AgentV1SettingsApplied,AgentV1UserStartedSpeaking,AgentV1KeepAlive,AgentV1ThinkUpdated,AgentV1PromptUpdated,AgentV1ForceEndTurn}.java`. Use the standard `.bak` swap/restore workflow during regen review; drop the patches and unfreeze all of them once the generator emits a matching equals/hashCode pair for fields-less types (tracked as an upstream Fern request). -- `src/main/java/com/deepgram/types/DeepgramModel.java` - restores the `FLUX_RENEE_EN` constant that generator 4.18.0 dropped. The voice is live: `POST /v2/speak?model=flux-renee-en` returns 200 with valid audio, and the name resolves in the server's model registry (an invented `flux-*` name is rejected with `INVALID_QUERY_PARAMETER`), so the removal is a spec regression rather than a retirement, and dropping the constant would break 0.8.0 callers for nothing. Five touchpoints: the constant, the `Value` enum entry, the `visit()` case, the `valueOf()` case, and the `Visitor` method. **This file is unlike the other temporarily frozen ones — it receives frequent additive spec changes (4.18.0 alone added 25 constants), so on the next regen do NOT restore the `.bak` wholesale.** Diff the `.bak` against the newly generated file, carry forward every new voice, and re-apply only the `FLUX_RENEE_EN` touchpoints. Drop the patch and unfreeze once the spec lists the voice again (tracked as an upstream spec request). +- `src/main/java/com/deepgram/types/DeepgramModel.java` - restores the `FLUX_RENEE_EN` constant that generator 4.18.0 dropped. Renee is an unlisted voice: the spec owner removed it from the catalog on purpose (#project-flux-tts, 2026-08-19), but it still synthesizes (`POST /v2/speak?model=flux-renee-en` returns 200 with valid audio), so dropping the constant would be a source break for 0.8.0+ callers over a catalog delisting alone. The constant and its `Visitor` method are marked `@Deprecated` with a note pointing callers to a listed voice. Five touchpoints: the constant, the `Value` enum entry, the `visit()` case, the `valueOf()` case, and the `Visitor` method (the constant and `Visitor` method carry the `@Deprecated` tag and Javadoc). **This file is unlike the other temporarily frozen ones — it receives frequent additive spec changes (4.18.0 alone added 25 constants), so on the next regen do NOT restore the `.bak` wholesale.** Diff the `.bak` against the newly generated file, carry forward every new voice, and re-apply only the `FLUX_RENEE_EN` touchpoints. The spec will not list the voice again, so drop the Renee touchpoints at the next major release; keep the file frozen until then for the reasons above. - Union default-variant fix on the agent listen-provider unions: `src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UpdateListenListenProvider.java`, `src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentListenProvider.java`, `src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentContextListenProvider.java`. `version` is an optional discriminator, so a provider payload without it is valid (and is what 0.7.x emits), but Fern points `@JsonTypeInfo` `defaultImpl` at the empty-bodied `_UnknownValue`, so such a payload deserializes to an unknown variant carrying `null` — `getProvider()` returns `null` and re-serialization emits `{"provider":null}`, silently dropping the provider on the wire. Patched to `defaultImpl = V2Value` on each; guarded by `src/test/java/com/deepgram/AgentSettingsProviderDefaultTest.java`. Use the standard `.bak` swap/restore workflow during regen review; drop the patches and unfreeze once the generator stops defaulting unions to the empty `_UnknownValue` (tracked as an upstream Fern request). -- `src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2ConfigureFailureCode.java` makes `Visitor.visitControlCombinationInvalid()` a default method that delegates to `visitUnknown("CONTROL_COMBINATION_INVALID")`. This preserves source compatibility for visitors compiled against the pre-controls API while retaining the new generated enum value. Guarded by `src/test/java/com/deepgram/RegenTypesTest.java`. Keep frozen until the next major release. +- `src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2ConfigureFailureCode.java` makes `Visitor.visitControlCombinationInvalid()` a default method that delegates to `visitUnknown("CONTROL_COMBINATION_INVALID")`. This restores source compatibility for `Visitor` implementations written against 0.8.0–0.10.x, before the value existed (0.11.0 shipped the method as abstract and listed it as breaking), while retaining the new generated enum value. Guarded by `src/test/java/com/deepgram/RegenTypesTest.java`. Use the standard `.bak` swap/restore workflow during regen review so new failure codes from the spec are carried forward, and re-apply only the default method. Keep frozen until the next major release. ### Prepare repo for regeneration diff --git a/README.md b/README.md index 21204b2..aeade6c 100644 --- a/README.md +++ b/README.md @@ -302,8 +302,8 @@ ws.connect(V1ConnectOptions.builder() .get(10, TimeUnit.SECONDS); // Update Nova-3 keyterms and numerals without reconnecting. Keep the keyterm list under the -// 500-token limit: an over-limit update currently stops transcription without an Error, and -// the server closes the stream. +// 500-token limit: an over-limit update does not close the stream, and the server may reply +// with a ConfigureFailure (CONFIGURE_KEYTERM_LIMIT_EXCEEDED), which this client reports to onError. ws.sendConfigure(ListenV1Configure.builder() .keyterms(List.of("Deepgram")) .features(Map.of("numerals", true)) diff --git a/docs/Migrating-v0.8-to-v0.9.md b/docs/Migrating-v0.8-to-v0.9.md index 68c9c24..916d6cc 100644 --- a/docs/Migrating-v0.8-to-v0.9.md +++ b/docs/Migrating-v0.8-to-v0.9.md @@ -183,6 +183,8 @@ ConversationHistoryMessage msg = ConversationHistoryMessage.builder() This is called out only because the generator dropped `FLUX_RENEE_EN` in this cycle and the SDK deliberately does not ship that removal. The voice is live: `POST /v2/speak?model=flux-renee-en` returns `200` with valid audio, and the name resolves in the server's model registry (an invented `flux-*` name is rejected with `INVALID_QUERY_PARAMETER`). The constant is restored and frozen, so existing references keep compiling. +> **Later update:** `flux-renee-en` is an unlisted voice, so releases after 0.11.1 mark `DeepgramModel.FLUX_RENEE_EN` `@Deprecated`. The voice still synthesizes and the constant still compiles; prefer a listed Flux voice from `GET /v2/models` for new code. + `DeepgramModel` remains a forward-compatible enum, so if you need to send a value the current SDK does not model, `DeepgramModel.valueOf("some-model-name")` still works. ### Speak V2 Connect Speed diff --git a/examples/listen/LiveReconfigure.java b/examples/listen/LiveReconfigure.java index 6da7fcc..af027be 100644 --- a/examples/listen/LiveReconfigure.java +++ b/examples/listen/LiveReconfigure.java @@ -15,8 +15,9 @@ /** * Reconfigures an active Nova-3 Listen V1 stream without reconnecting. * - *

Keep the keyterm list under the 500-token limit: an over-limit update currently stops transcription without an - * {@code Error}, and the server closes the stream. + *

Keep the keyterm list under the 500-token limit: an over-limit update does not close the stream, and the server + * may reply with a {@code ConfigureFailure} ({@code CONFIGURE_KEYTERM_LIMIT_EXCEEDED}), which this client reports to + * {@code onError}. * *

Usage: {@code DEEPGRAM_API_KEY=... java LiveReconfigure} */ diff --git a/src/main/java/com/deepgram/core/ClientOptions.java b/src/main/java/com/deepgram/core/ClientOptions.java index aceddaa..66dfa86 100644 --- a/src/main/java/com/deepgram/core/ClientOptions.java +++ b/src/main/java/com/deepgram/core/ClientOptions.java @@ -144,9 +144,9 @@ public Optional retryJitterFactor() { * OkHttpClient itself; an OkHttpClient supplied via httpClient is left running, since the * caller owns its lifecycle. *

- * In-flight calls are not cancelled or awaited. When this client owns the underlying - * OkHttpClient, requests issued after shutdown can fail with a - * {@code RejectedExecutionException}. Options derived from this one via + * In-flight calls are not cancelled or awaited. When this client owns its OkHttpClient, later + * asynchronous HTTP requests can fail when the dispatcher rejects work, while synchronous + * requests may still run. Options derived from this one via * {@code Builder.from(...)} share the same dispatcher and connection pool, so closing either * releases them for both. A caller-supplied OkHttpClient remains running. Calling this method * more than once has no further effect. diff --git a/src/main/java/com/deepgram/types/DeepgramModel.java b/src/main/java/com/deepgram/types/DeepgramModel.java index 974c3fa..9fa2f8b 100644 --- a/src/main/java/com/deepgram/types/DeepgramModel.java +++ b/src/main/java/com/deepgram/types/DeepgramModel.java @@ -13,7 +13,10 @@ public final class DeepgramModel { public static final DeepgramModel FLUX_KELSEY_EN = new DeepgramModel(Value.FLUX_KELSEY_EN, "flux-kelsey-en"); - /** @deprecated This live voice is absent from the generated model catalog. */ + /** + * @deprecated {@code flux-renee-en} is an unlisted voice and may be removed in a future major + * release. Prefer a listed Flux voice; {@code GET /v2/models} returns the current catalog. + */ @Deprecated public static final DeepgramModel FLUX_RENEE_EN = new DeepgramModel(Value.FLUX_RENEE_EN, "flux-renee-en"); @@ -1032,7 +1035,10 @@ public interface Visitor { T visitFluxKelseyEn(); - /** @deprecated This live voice is absent from the generated model catalog. */ + /** + * @deprecated {@code flux-renee-en} is an unlisted voice and may be removed in a future major + * release. Prefer a listed Flux voice; {@code GET /v2/models} returns the current catalog. + */ @Deprecated T visitFluxReneeEn();