From 4eb0dfa45278656462c69ea20573745d630b9559 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 8 Sep 2025 19:15:59 +0000 Subject: [PATCH 1/3] feat(api): ship the RealtimeGA API shape Updates types to use the GA shape for Realtime API --- .stats.yml | 6 +- .../models/realtime/AudioTranscription.kt | 388 ++ .../models/realtime/ConversationItem.kt | 34 +- .../models/realtime/ConversationItemAdded.kt | 15 +- .../models/realtime/ConversationItemDone.kt | 7 +- ...emInputAudioTranscriptionCompletedEvent.kt | 23 +- ...onItemInputAudioTranscriptionDeltaEvent.kt | 23 +- .../realtime/ConversationItemTruncateEvent.kt | 4 +- .../realtime/InputAudioBufferAppendEvent.kt | 12 +- .../com/openai/models/realtime/Models.kt | 365 ++ .../models/realtime/NoiseReductionType.kt | 138 + .../models/realtime/RealtimeAudioConfig.kt | 2568 +-------- .../realtime/RealtimeAudioConfigInput.kt | 499 ++ .../realtime/RealtimeAudioConfigOutput.kt | 449 ++ .../models/realtime/RealtimeAudioFormats.kt | 1182 ++++ .../RealtimeAudioInputTurnDetection.kt | 793 +++ .../models/realtime/RealtimeClientEvent.kt | 184 +- ...ealtimeConversationItemAssistantMessage.kt | 143 +- .../RealtimeConversationItemFunctionCall.kt | 27 +- ...ltimeConversationItemFunctionCallOutput.kt | 27 +- .../RealtimeConversationItemSystemMessage.kt | 27 +- .../RealtimeConversationItemUserMessage.kt | 276 +- .../models/realtime/RealtimeResponse.kt | 1157 ++-- ...t => RealtimeResponseCreateAudioOutput.kt} | 324 +- .../realtime/RealtimeResponseCreateMcpTool.kt | 2294 ++++++++ .../realtime/RealtimeResponseCreateParams.kt | 1832 ++++++ .../models/realtime/RealtimeResponseUsage.kt | 12 +- .../RealtimeResponseUsageInputTokenDetails.kt | 352 +- .../models/realtime/RealtimeServerEvent.kt | 175 +- .../openai/models/realtime/RealtimeSession.kt | 919 +-- .../realtime/RealtimeSessionCreateRequest.kt | 580 +- .../realtime/RealtimeToolsConfigUnion.kt | 373 +- .../models/realtime/RealtimeTracingConfig.kt | 24 +- .../RealtimeTranscriptionSessionAudio.kt | 166 + .../RealtimeTranscriptionSessionAudioInput.kt | 508 ++ ...scriptionSessionAudioInputTurnDetection.kt | 795 +++ ...altimeTranscriptionSessionCreateRequest.kt | 1707 +----- .../models/realtime/RealtimeTruncation.kt | 355 +- .../RealtimeTruncationRetentionRatio.kt | 232 + .../models/realtime/ResponseCancelEvent.kt | 3 +- .../models/realtime/ResponseCreateEvent.kt | 2457 +------- .../models/realtime/ResponseDoneEvent.kt | 6 + .../models/realtime/SessionCreatedEvent.kt | 292 +- .../models/realtime/SessionUpdateEvent.kt | 320 +- .../models/realtime/SessionUpdatedEvent.kt | 292 +- .../realtime/TranscriptionSessionCreated.kt | 1898 +----- .../realtime/TranscriptionSessionUpdate.kt | 1289 ++++- .../TranscriptionSessionUpdatedEvent.kt | 1898 +----- .../clientsecrets/ClientSecretCreateParams.kt | 69 +- .../ClientSecretCreateResponse.kt | 1960 +------ .../RealtimeSessionClientSecret.kt | 216 + .../RealtimeSessionCreateResponse.kt | 5087 +++++++++++++---- ...ealtimeTranscriptionSessionClientSecret.kt | 223 + ...ltimeTranscriptionSessionCreateResponse.kt | 546 ++ ...scriptionSessionInputAudioTranscription.kt | 402 ++ ...altimeTranscriptionSessionTurnDetection.kt | 307 + .../realtime/ClientSecretServiceAsync.kt | 2 +- .../blocking/realtime/ClientSecretService.kt | 2 +- .../models/realtime/AudioTranscriptionTest.kt | 44 + .../models/realtime/ConversationItemTest.kt | 12 +- .../com/openai/models/realtime/ModelsTest.kt | 45 + .../realtime/RealtimeAudioConfigInputTest.kt | 131 + .../realtime/RealtimeAudioConfigOutputTest.kt | 63 + .../realtime/RealtimeAudioConfigTest.kt | 102 +- .../realtime/RealtimeAudioFormatsTest.kt | 135 + .../RealtimeAudioInputTurnDetectionTest.kt | 62 + .../realtime/RealtimeClientEventTest.kt | 256 +- .../RealtimeClientSecretConfigTest.kt | 54 - ...imeConversationItemAssistantMessageTest.kt | 12 +- ...RealtimeConversationItemUserMessageTest.kt | 6 + .../RealtimeResponseCreateAudioOutputTest.kt | 70 + .../RealtimeResponseCreateMcpToolTest.kt | 136 + .../RealtimeResponseCreateParamsTest.kt | 223 + .../models/realtime/RealtimeResponseTest.kt | 90 +- ...ltimeResponseUsageInputTokenDetailsTest.kt | 25 + .../realtime/RealtimeResponseUsageTest.kt | 24 + .../realtime/RealtimeServerEventTest.kt | 842 +-- .../RealtimeSessionCreateRequestTest.kt | 174 +- .../models/realtime/RealtimeSessionTest.kt | 30 +- .../realtime/RealtimeToolsConfigUnionTest.kt | 8 +- ...ltimeTranscriptionSessionAudioInputTest.kt | 136 + ...ptionSessionAudioInputTurnDetectionTest.kt | 66 + .../RealtimeTranscriptionSessionAudioTest.kt | 155 + ...meTranscriptionSessionCreateRequestTest.kt | 229 +- .../RealtimeTruncationRetentionRatioTest.kt | 35 + .../models/realtime/RealtimeTruncationTest.kt | 11 +- .../realtime/ResponseCreateEventTest.kt | 90 +- .../realtime/ResponseCreatedEventTest.kt | 89 +- .../models/realtime/ResponseDoneEventTest.kt | 89 +- .../realtime/SessionCreatedEventTest.kt | 349 +- .../models/realtime/SessionUpdateEventTest.kt | 310 +- .../realtime/SessionUpdatedEventTest.kt | 349 +- .../TranscriptionSessionCreatedTest.kt | 219 +- .../TranscriptionSessionUpdateTest.kt | 100 +- .../TranscriptionSessionUpdatedEventTest.kt | 223 +- .../ClientSecretCreateParamsTest.kt | 198 +- .../ClientSecretCreateResponseTest.kt | 253 +- .../RealtimeSessionClientSecretTest.kt | 35 + .../RealtimeSessionCreateResponseTest.kt | 246 +- ...imeTranscriptionSessionClientSecretTest.kt | 36 + ...eTranscriptionSessionCreateResponseTest.kt | 111 + ...ptionSessionInputAudioTranscriptionTest.kt | 47 + ...meTranscriptionSessionTurnDetectionTest.kt | 48 + .../realtime/ClientSecretServiceAsyncTest.kt | 74 +- .../realtime/ClientSecretServiceTest.kt | 74 +- 105 files changed, 24150 insertions(+), 18230 deletions(-) create mode 100644 openai-java-core/src/main/kotlin/com/openai/models/realtime/AudioTranscription.kt create mode 100644 openai-java-core/src/main/kotlin/com/openai/models/realtime/Models.kt create mode 100644 openai-java-core/src/main/kotlin/com/openai/models/realtime/NoiseReductionType.kt create mode 100644 openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeAudioConfigInput.kt create mode 100644 openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeAudioConfigOutput.kt create mode 100644 openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeAudioFormats.kt create mode 100644 openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeAudioInputTurnDetection.kt rename openai-java-core/src/main/kotlin/com/openai/models/realtime/{RealtimeClientSecretConfig.kt => RealtimeResponseCreateAudioOutput.kt} (51%) create mode 100644 openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeResponseCreateMcpTool.kt create mode 100644 openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeResponseCreateParams.kt create mode 100644 openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeTranscriptionSessionAudio.kt create mode 100644 openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeTranscriptionSessionAudioInput.kt create mode 100644 openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeTranscriptionSessionAudioInputTurnDetection.kt create mode 100644 openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeTruncationRetentionRatio.kt create mode 100644 openai-java-core/src/main/kotlin/com/openai/models/realtime/clientsecrets/RealtimeSessionClientSecret.kt create mode 100644 openai-java-core/src/main/kotlin/com/openai/models/realtime/clientsecrets/RealtimeTranscriptionSessionClientSecret.kt create mode 100644 openai-java-core/src/main/kotlin/com/openai/models/realtime/clientsecrets/RealtimeTranscriptionSessionCreateResponse.kt create mode 100644 openai-java-core/src/main/kotlin/com/openai/models/realtime/clientsecrets/RealtimeTranscriptionSessionInputAudioTranscription.kt create mode 100644 openai-java-core/src/main/kotlin/com/openai/models/realtime/clientsecrets/RealtimeTranscriptionSessionTurnDetection.kt create mode 100644 openai-java-core/src/test/kotlin/com/openai/models/realtime/AudioTranscriptionTest.kt create mode 100644 openai-java-core/src/test/kotlin/com/openai/models/realtime/ModelsTest.kt create mode 100644 openai-java-core/src/test/kotlin/com/openai/models/realtime/RealtimeAudioConfigInputTest.kt create mode 100644 openai-java-core/src/test/kotlin/com/openai/models/realtime/RealtimeAudioConfigOutputTest.kt create mode 100644 openai-java-core/src/test/kotlin/com/openai/models/realtime/RealtimeAudioFormatsTest.kt create mode 100644 openai-java-core/src/test/kotlin/com/openai/models/realtime/RealtimeAudioInputTurnDetectionTest.kt delete mode 100644 openai-java-core/src/test/kotlin/com/openai/models/realtime/RealtimeClientSecretConfigTest.kt create mode 100644 openai-java-core/src/test/kotlin/com/openai/models/realtime/RealtimeResponseCreateAudioOutputTest.kt create mode 100644 openai-java-core/src/test/kotlin/com/openai/models/realtime/RealtimeResponseCreateMcpToolTest.kt create mode 100644 openai-java-core/src/test/kotlin/com/openai/models/realtime/RealtimeResponseCreateParamsTest.kt create mode 100644 openai-java-core/src/test/kotlin/com/openai/models/realtime/RealtimeTranscriptionSessionAudioInputTest.kt create mode 100644 openai-java-core/src/test/kotlin/com/openai/models/realtime/RealtimeTranscriptionSessionAudioInputTurnDetectionTest.kt create mode 100644 openai-java-core/src/test/kotlin/com/openai/models/realtime/RealtimeTranscriptionSessionAudioTest.kt create mode 100644 openai-java-core/src/test/kotlin/com/openai/models/realtime/RealtimeTruncationRetentionRatioTest.kt create mode 100644 openai-java-core/src/test/kotlin/com/openai/models/realtime/clientsecrets/RealtimeSessionClientSecretTest.kt create mode 100644 openai-java-core/src/test/kotlin/com/openai/models/realtime/clientsecrets/RealtimeTranscriptionSessionClientSecretTest.kt create mode 100644 openai-java-core/src/test/kotlin/com/openai/models/realtime/clientsecrets/RealtimeTranscriptionSessionCreateResponseTest.kt create mode 100644 openai-java-core/src/test/kotlin/com/openai/models/realtime/clientsecrets/RealtimeTranscriptionSessionInputAudioTranscriptionTest.kt create mode 100644 openai-java-core/src/test/kotlin/com/openai/models/realtime/clientsecrets/RealtimeTranscriptionSessionTurnDetectionTest.kt diff --git a/.stats.yml b/.stats.yml index c41be6ee..36a3c7f5 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 118 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-51afd6abbcb18c3086f62993f9379c18443b9e516cbc0548ddfb932e835657f8.yml -openapi_spec_hash: dae6afeaefa15cb8700c7a870531e06f -config_hash: b854932c0ea24b400bdd64e4376936bd +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-7807ec6037efcee1af7decbfd3974a42b761fb6c6a71b4050fe43484d7fcbac4.yml +openapi_spec_hash: da6851e3891ad2659a50ed6a736fd32a +config_hash: 74d955cdc2377213f5268ea309090f6c diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/AudioTranscription.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/AudioTranscription.kt new file mode 100644 index 00000000..5955af1c --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/AudioTranscription.kt @@ -0,0 +1,388 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.realtime + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.Enum +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class AudioTranscription +private constructor( + private val language: JsonField, + private val model: JsonField, + private val prompt: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("language") @ExcludeMissing language: JsonField = JsonMissing.of(), + @JsonProperty("model") @ExcludeMissing model: JsonField = JsonMissing.of(), + @JsonProperty("prompt") @ExcludeMissing prompt: JsonField = JsonMissing.of(), + ) : this(language, model, prompt, mutableMapOf()) + + /** + * The language of the input audio. Supplying the input language in + * [ISO-639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) (e.g. `en`) format will + * improve accuracy and latency. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun language(): Optional = language.getOptional("language") + + /** + * The model to use for transcription. Current options are `whisper-1`, + * `gpt-4o-transcribe-latest`, `gpt-4o-mini-transcribe`, and `gpt-4o-transcribe`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun model(): Optional = model.getOptional("model") + + /** + * An optional text to guide the model's style or continue a previous audio segment. For + * `whisper-1`, the + * [prompt is a list of keywords](https://platform.openai.com/docs/guides/speech-to-text#prompting). + * For `gpt-4o-transcribe` models, the prompt is a free text string, for example "expect words + * related to technology". + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun prompt(): Optional = prompt.getOptional("prompt") + + /** + * Returns the raw JSON value of [language]. + * + * Unlike [language], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("language") @ExcludeMissing fun _language(): JsonField = language + + /** + * Returns the raw JSON value of [model]. + * + * Unlike [model], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("model") @ExcludeMissing fun _model(): JsonField = model + + /** + * Returns the raw JSON value of [prompt]. + * + * Unlike [prompt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("prompt") @ExcludeMissing fun _prompt(): JsonField = prompt + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [AudioTranscription]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AudioTranscription]. */ + class Builder internal constructor() { + + private var language: JsonField = JsonMissing.of() + private var model: JsonField = JsonMissing.of() + private var prompt: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(audioTranscription: AudioTranscription) = apply { + language = audioTranscription.language + model = audioTranscription.model + prompt = audioTranscription.prompt + additionalProperties = audioTranscription.additionalProperties.toMutableMap() + } + + /** + * The language of the input audio. Supplying the input language in + * [ISO-639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) (e.g. `en`) format + * will improve accuracy and latency. + */ + fun language(language: String) = language(JsonField.of(language)) + + /** + * Sets [Builder.language] to an arbitrary JSON value. + * + * You should usually call [Builder.language] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun language(language: JsonField) = apply { this.language = language } + + /** + * The model to use for transcription. Current options are `whisper-1`, + * `gpt-4o-transcribe-latest`, `gpt-4o-mini-transcribe`, and `gpt-4o-transcribe`. + */ + fun model(model: Model) = model(JsonField.of(model)) + + /** + * Sets [Builder.model] to an arbitrary JSON value. + * + * You should usually call [Builder.model] with a well-typed [Model] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun model(model: JsonField) = apply { this.model = model } + + /** + * An optional text to guide the model's style or continue a previous audio segment. For + * `whisper-1`, the + * [prompt is a list of keywords](https://platform.openai.com/docs/guides/speech-to-text#prompting). + * For `gpt-4o-transcribe` models, the prompt is a free text string, for example "expect + * words related to technology". + */ + fun prompt(prompt: String) = prompt(JsonField.of(prompt)) + + /** + * Sets [Builder.prompt] to an arbitrary JSON value. + * + * You should usually call [Builder.prompt] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun prompt(prompt: JsonField) = apply { this.prompt = prompt } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [AudioTranscription]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AudioTranscription = + AudioTranscription(language, model, prompt, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): AudioTranscription = apply { + if (validated) { + return@apply + } + + language() + model().ifPresent { it.validate() } + prompt() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (language.asKnown().isPresent) 1 else 0) + + (model.asKnown().getOrNull()?.validity() ?: 0) + + (if (prompt.asKnown().isPresent) 1 else 0) + + /** + * The model to use for transcription. Current options are `whisper-1`, + * `gpt-4o-transcribe-latest`, `gpt-4o-mini-transcribe`, and `gpt-4o-transcribe`. + */ + class Model @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val WHISPER_1 = of("whisper-1") + + @JvmField val GPT_4O_TRANSCRIBE_LATEST = of("gpt-4o-transcribe-latest") + + @JvmField val GPT_4O_MINI_TRANSCRIBE = of("gpt-4o-mini-transcribe") + + @JvmField val GPT_4O_TRANSCRIBE = of("gpt-4o-transcribe") + + @JvmStatic fun of(value: String) = Model(JsonField.of(value)) + } + + /** An enum containing [Model]'s known values. */ + enum class Known { + WHISPER_1, + GPT_4O_TRANSCRIBE_LATEST, + GPT_4O_MINI_TRANSCRIBE, + GPT_4O_TRANSCRIBE, + } + + /** + * An enum containing [Model]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Model] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + WHISPER_1, + GPT_4O_TRANSCRIBE_LATEST, + GPT_4O_MINI_TRANSCRIBE, + GPT_4O_TRANSCRIBE, + /** An enum member indicating that [Model] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + WHISPER_1 -> Value.WHISPER_1 + GPT_4O_TRANSCRIBE_LATEST -> Value.GPT_4O_TRANSCRIBE_LATEST + GPT_4O_MINI_TRANSCRIBE -> Value.GPT_4O_MINI_TRANSCRIBE + GPT_4O_TRANSCRIBE -> Value.GPT_4O_TRANSCRIBE + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + WHISPER_1 -> Known.WHISPER_1 + GPT_4O_TRANSCRIBE_LATEST -> Known.GPT_4O_TRANSCRIBE_LATEST + GPT_4O_MINI_TRANSCRIBE -> Known.GPT_4O_MINI_TRANSCRIBE + GPT_4O_TRANSCRIBE -> Known.GPT_4O_TRANSCRIBE + else -> throw OpenAIInvalidDataException("Unknown Model: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): Model = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Model && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AudioTranscription && + language == other.language && + model == other.model && + prompt == other.prompt && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(language, model, prompt, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AudioTranscription{language=$language, model=$model, prompt=$prompt, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/ConversationItem.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/ConversationItem.kt index 7763fd5b..cc06d932 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/ConversationItem.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/ConversationItem.kt @@ -39,7 +39,13 @@ private constructor( private val _json: JsonValue? = null, ) { - /** A system message item in a Realtime conversation. */ + /** + * A system message in a Realtime conversation can be used to provide additional context or + * instructions to the model. This is similar but distinct from the instruction prompt provided + * at the start of a conversation, as system messages can be added at any point in the + * conversation. For major changes to the conversation's behavior, use instructions, but for + * smaller updates (e.g. "the user is now asking about a different topic"), use system messages. + */ fun realtimeConversationItemSystemMessage(): Optional = Optional.ofNullable(realtimeConversationItemSystemMessage) @@ -95,7 +101,13 @@ private constructor( fun isMcpApprovalRequest(): Boolean = mcpApprovalRequest != null - /** A system message item in a Realtime conversation. */ + /** + * A system message in a Realtime conversation can be used to provide additional context or + * instructions to the model. This is similar but distinct from the instruction prompt provided + * at the start of a conversation, as system messages can be added at any point in the + * conversation. For major changes to the conversation's behavior, use instructions, but for + * smaller updates (e.g. "the user is now asking about a different topic"), use system messages. + */ fun asRealtimeConversationItemSystemMessage(): RealtimeConversationItemSystemMessage = realtimeConversationItemSystemMessage.getOrThrow("realtimeConversationItemSystemMessage") @@ -325,7 +337,14 @@ private constructor( companion object { - /** A system message item in a Realtime conversation. */ + /** + * A system message in a Realtime conversation can be used to provide additional context or + * instructions to the model. This is similar but distinct from the instruction prompt + * provided at the start of a conversation, as system messages can be added at any point in + * the conversation. For major changes to the conversation's behavior, use instructions, but + * for smaller updates (e.g. "the user is now asking about a different topic"), use system + * messages. + */ @JvmStatic fun ofRealtimeConversationItemSystemMessage( realtimeConversationItemSystemMessage: RealtimeConversationItemSystemMessage @@ -389,7 +408,14 @@ private constructor( */ interface Visitor { - /** A system message item in a Realtime conversation. */ + /** + * A system message in a Realtime conversation can be used to provide additional context or + * instructions to the model. This is similar but distinct from the instruction prompt + * provided at the start of a conversation, as system messages can be added at any point in + * the conversation. For major changes to the conversation's behavior, use instructions, but + * for smaller updates (e.g. "the user is now asking about a different topic"), use system + * messages. + */ fun visitRealtimeConversationItemSystemMessage( realtimeConversationItemSystemMessage: RealtimeConversationItemSystemMessage ): T diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/ConversationItemAdded.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/ConversationItemAdded.kt index 934ffca4..128b5499 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/ConversationItemAdded.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/ConversationItemAdded.kt @@ -17,7 +17,20 @@ import java.util.Objects import java.util.Optional import kotlin.jvm.optionals.getOrNull -/** Returned when a conversation item is added. */ +/** + * Sent by the server when an Item is added to the default Conversation. This can happen in several + * cases: + * - When the client sends a `conversation.item.create` event. + * - When the input audio buffer is committed. In this case the item will be a user message + * containing the audio from the buffer. + * - When the model is generating a Response. In this case the `conversation.item.added` event will + * be sent when the model starts generating a specific Item, and thus it will not yet have any + * content (and `status` will be `in_progress`). + * + * The event will include the full content of the Item (except when model is generating a Response) + * except for audio data, which can be retrieved separately with a `conversation.item.retrieve` + * event if necessary. + */ class ConversationItemAdded private constructor( private val eventId: JsonField, diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/ConversationItemDone.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/ConversationItemDone.kt index 33722214..7c26e1da 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/ConversationItemDone.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/ConversationItemDone.kt @@ -17,7 +17,12 @@ import java.util.Objects import java.util.Optional import kotlin.jvm.optionals.getOrNull -/** Returned when a conversation item is finalized. */ +/** + * Returned when a conversation item is finalized. + * + * The event will include the full content of the Item except for audio data, which can be retrieved + * separately with a `conversation.item.retrieve` event if needed. + */ class ConversationItemDone private constructor( private val eventId: JsonField, diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/ConversationItemInputAudioTranscriptionCompletedEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/ConversationItemInputAudioTranscriptionCompletedEvent.kt index 5375b6f2..38fb62fb 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/ConversationItemInputAudioTranscriptionCompletedEvent.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/ConversationItemInputAudioTranscriptionCompletedEvent.kt @@ -32,9 +32,9 @@ import kotlin.jvm.optionals.getOrNull /** * This event is the output of audio transcription for user audio written to the user audio buffer. - * Transcription begins when the input audio buffer is committed by the client or server (in - * `server_vad` mode). Transcription runs asynchronously with Response creation, so this event may - * come before or after the Response events. + * Transcription begins when the input audio buffer is committed by the client or server (when VAD + * is enabled). Transcription runs asynchronously with Response creation, so this event may come + * before or after the Response events. * * Realtime API models accept audio natively, and thus input transcription is a separate process run * on a separate ASR (Automatic Speech Recognition) model. The transcript may diverge somewhat from @@ -86,7 +86,7 @@ private constructor( fun eventId(): String = eventId.getRequired("event_id") /** - * The ID of the user message item containing the audio. + * The ID of the item containing the audio that is being transcribed. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected value). @@ -115,7 +115,8 @@ private constructor( @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type /** - * Usage statistics for the transcription. + * Usage statistics for the transcription, this is billed according to the ASR model's pricing + * rather than the realtime model's pricing. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected value). @@ -262,7 +263,7 @@ private constructor( */ fun eventId(eventId: JsonField) = apply { this.eventId = eventId } - /** The ID of the user message item containing the audio. */ + /** The ID of the item containing the audio that is being transcribed. */ fun itemId(itemId: String) = itemId(JsonField.of(itemId)) /** @@ -299,7 +300,10 @@ private constructor( */ fun type(type: JsonValue) = apply { this.type = type } - /** Usage statistics for the transcription. */ + /** + * Usage statistics for the transcription, this is billed according to the ASR model's + * pricing rather than the realtime model's pricing. + */ fun usage(usage: Usage) = usage(JsonField.of(usage)) /** @@ -448,7 +452,10 @@ private constructor( (usage.asKnown().getOrNull()?.validity() ?: 0) + (logprobs.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) - /** Usage statistics for the transcription. */ + /** + * Usage statistics for the transcription, this is billed according to the ASR model's pricing + * rather than the realtime model's pricing. + */ @JsonDeserialize(using = Usage.Deserializer::class) @JsonSerialize(using = Usage.Serializer::class) class Usage diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/ConversationItemInputAudioTranscriptionDeltaEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/ConversationItemInputAudioTranscriptionDeltaEvent.kt index 68db339f..1e3379ac 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/ConversationItemInputAudioTranscriptionDeltaEvent.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/ConversationItemInputAudioTranscriptionDeltaEvent.kt @@ -19,7 +19,10 @@ import java.util.Objects import java.util.Optional import kotlin.jvm.optionals.getOrNull -/** Returned when the text value of an input audio transcription content part is updated. */ +/** + * Returned when the text value of an input audio transcription content part is updated with + * incremental transcription results. + */ class ConversationItemInputAudioTranscriptionDeltaEvent private constructor( private val eventId: JsonField, @@ -54,7 +57,7 @@ private constructor( fun eventId(): String = eventId.getRequired("event_id") /** - * The ID of the item. + * The ID of the item containing the audio that is being transcribed. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected value). @@ -91,7 +94,11 @@ private constructor( fun delta(): Optional = delta.getOptional("delta") /** - * The log probabilities of the transcription. + * The log probabilities of the transcription. These can be enabled by configurating the session + * with `"include": ["item.input_audio_transcription.logprobs"]`. Each entry in the array + * corresponds a log probability of which token would be selected for this chunk of + * transcription. This can help to identify if it was possible there were multiple valid options + * for a given chunk of transcription. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -206,7 +213,7 @@ private constructor( */ fun eventId(eventId: JsonField) = apply { this.eventId = eventId } - /** The ID of the item. */ + /** The ID of the item containing the audio that is being transcribed. */ fun itemId(itemId: String) = itemId(JsonField.of(itemId)) /** @@ -254,7 +261,13 @@ private constructor( */ fun delta(delta: JsonField) = apply { this.delta = delta } - /** The log probabilities of the transcription. */ + /** + * The log probabilities of the transcription. These can be enabled by configurating the + * session with `"include": ["item.input_audio_transcription.logprobs"]`. Each entry in the + * array corresponds a log probability of which token would be selected for this chunk of + * transcription. This can help to identify if it was possible there were multiple valid + * options for a given chunk of transcription. + */ fun logprobs(logprobs: List?) = logprobs(JsonField.ofNullable(logprobs)) /** Alias for calling [Builder.logprobs] with `logprobs.orElse(null)`. */ diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/ConversationItemTruncateEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/ConversationItemTruncateEvent.kt index 2efb7e05..1c23121e 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/ConversationItemTruncateEvent.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/ConversationItemTruncateEvent.kt @@ -60,7 +60,7 @@ private constructor( fun audioEndMs(): Long = audioEndMs.getRequired("audio_end_ms") /** - * The index of the content part to truncate. Set this to 0. + * The index of the content part to truncate. Set this to `0`. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected value). @@ -189,7 +189,7 @@ private constructor( */ fun audioEndMs(audioEndMs: JsonField) = apply { this.audioEndMs = audioEndMs } - /** The index of the content part to truncate. Set this to 0. */ + /** The index of the content part to truncate. Set this to `0`. */ fun contentIndex(contentIndex: Long) = contentIndex(JsonField.of(contentIndex)) /** diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/InputAudioBufferAppendEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/InputAudioBufferAppendEvent.kt index dfd1ef84..3a6d49d8 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/InputAudioBufferAppendEvent.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/InputAudioBufferAppendEvent.kt @@ -18,13 +18,17 @@ import java.util.Optional /** * Send this event to append audio bytes to the input audio buffer. The audio buffer is temporary - * storage you can write to and later commit. In Server VAD mode, the audio buffer is used to detect - * speech and the server will decide when to commit. When Server VAD is disabled, you must commit - * the audio buffer manually. + * storage you can write to and later commit. A "commit" will create a new user message item in the + * conversation history from the buffer content and clear the buffer. Input audio transcription (if + * enabled) will be generated when the buffer is committed. + * + * If VAD is enabled the audio buffer is used to detect speech and the server will decide when to + * commit. When Server VAD is disabled, you must commit the audio buffer manually. Input audio noise + * reduction operates on writes to the audio buffer. * * The client may choose how much audio to place in each event up to a maximum of 15 MiB, for * example streaming smaller chunks from the client may allow the VAD to be more responsive. Unlike - * made other client events, the server will not send a confirmation response to this event. + * most other client events, the server will not send a confirmation response to this event. */ class InputAudioBufferAppendEvent private constructor( diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/Models.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/Models.kt new file mode 100644 index 00000000..fe1f7695 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/Models.kt @@ -0,0 +1,365 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.realtime + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.Enum +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class Models +private constructor( + private val description: JsonField, + private val name: JsonField, + private val parameters: JsonValue, + private val type: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("description") + @ExcludeMissing + description: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("parameters") @ExcludeMissing parameters: JsonValue = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + ) : this(description, name, parameters, type, mutableMapOf()) + + /** + * The description of the function, including guidance on when and how to call it, and guidance + * about what to tell the user when calling (if anything). + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = description.getOptional("description") + + /** + * The name of the function. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun name(): Optional = name.getOptional("name") + + /** Parameters of the function in JSON Schema. */ + @JsonProperty("parameters") @ExcludeMissing fun _parameters(): JsonValue = parameters + + /** + * The type of the tool, i.e. `function`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun type(): Optional = type.getOptional("type") + + /** + * Returns the raw JSON value of [description]. + * + * Unlike [description], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("description") @ExcludeMissing fun _description(): JsonField = description + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Models]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Models]. */ + class Builder internal constructor() { + + private var description: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var parameters: JsonValue = JsonMissing.of() + private var type: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(models: Models) = apply { + description = models.description + name = models.name + parameters = models.parameters + type = models.type + additionalProperties = models.additionalProperties.toMutableMap() + } + + /** + * The description of the function, including guidance on when and how to call it, and + * guidance about what to tell the user when calling (if anything). + */ + fun description(description: String) = description(JsonField.of(description)) + + /** + * Sets [Builder.description] to an arbitrary JSON value. + * + * You should usually call [Builder.description] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun description(description: JsonField) = apply { this.description = description } + + /** The name of the function. */ + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** Parameters of the function in JSON Schema. */ + fun parameters(parameters: JsonValue) = apply { this.parameters = parameters } + + /** The type of the tool, i.e. `function`. */ + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Models]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Models = + Models(description, name, parameters, type, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Models = apply { + if (validated) { + return@apply + } + + description() + name() + type().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (description.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + /** The type of the tool, i.e. `function`. */ + class Type @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val FUNCTION = of("function") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + FUNCTION + } + + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + FUNCTION, + /** An enum member indicating that [Type] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + FUNCTION -> Value.FUNCTION + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + FUNCTION -> Known.FUNCTION + else -> throw OpenAIInvalidDataException("Unknown Type: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): Type = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Type && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Models && + description == other.description && + name == other.name && + parameters == other.parameters && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(description, name, parameters, type, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Models{description=$description, name=$name, parameters=$parameters, type=$type, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/NoiseReductionType.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/NoiseReductionType.kt new file mode 100644 index 00000000..7b9326ba --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/NoiseReductionType.kt @@ -0,0 +1,138 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.realtime + +import com.fasterxml.jackson.annotation.JsonCreator +import com.openai.core.Enum +import com.openai.core.JsonField +import com.openai.errors.OpenAIInvalidDataException + +/** + * Type of noise reduction. `near_field` is for close-talking microphones such as headphones, + * `far_field` is for far-field microphones such as laptop or conference room microphones. + */ +class NoiseReductionType @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't match + * any known member, and you want to know that value. For example, if the SDK is on an older + * version than the API, then the API may respond with new members that the SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val NEAR_FIELD = of("near_field") + + @JvmField val FAR_FIELD = of("far_field") + + @JvmStatic fun of(value: String) = NoiseReductionType(JsonField.of(value)) + } + + /** An enum containing [NoiseReductionType]'s known values. */ + enum class Known { + NEAR_FIELD, + FAR_FIELD, + } + + /** + * An enum containing [NoiseReductionType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [NoiseReductionType] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the SDK + * is on an older version than the API, then the API may respond with new members that the SDK + * is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + NEAR_FIELD, + FAR_FIELD, + /** + * An enum member indicating that [NoiseReductionType] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] if + * the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want to + * throw for the unknown case. + */ + fun value(): Value = + when (this) { + NEAR_FIELD -> Value.NEAR_FIELD + FAR_FIELD -> Value.FAR_FIELD + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't want + * to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known member. + */ + fun known(): Known = + when (this) { + NEAR_FIELD -> Known.NEAR_FIELD + FAR_FIELD -> Known.FAR_FIELD + else -> throw OpenAIInvalidDataException("Unknown NoiseReductionType: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging and + * generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the expected + * primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): NoiseReductionType = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is NoiseReductionType && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeAudioConfig.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeAudioConfig.kt index 05494d46..42084721 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeAudioConfig.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeAudioConfig.kt @@ -6,7 +6,6 @@ import com.fasterxml.jackson.annotation.JsonAnyGetter import com.fasterxml.jackson.annotation.JsonAnySetter import com.fasterxml.jackson.annotation.JsonCreator import com.fasterxml.jackson.annotation.JsonProperty -import com.openai.core.Enum import com.openai.core.ExcludeMissing import com.openai.core.JsonField import com.openai.core.JsonMissing @@ -20,42 +19,48 @@ import kotlin.jvm.optionals.getOrNull /** Configuration for input and output audio. */ class RealtimeAudioConfig private constructor( - private val input: JsonField, - private val output: JsonField, + private val input: JsonField, + private val output: JsonField, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( - @JsonProperty("input") @ExcludeMissing input: JsonField = JsonMissing.of(), - @JsonProperty("output") @ExcludeMissing output: JsonField = JsonMissing.of(), + @JsonProperty("input") + @ExcludeMissing + input: JsonField = JsonMissing.of(), + @JsonProperty("output") + @ExcludeMissing + output: JsonField = JsonMissing.of(), ) : this(input, output, mutableMapOf()) /** * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). */ - fun input(): Optional = input.getOptional("input") + fun input(): Optional = input.getOptional("input") /** * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). */ - fun output(): Optional = output.getOptional("output") + fun output(): Optional = output.getOptional("output") /** * Returns the raw JSON value of [input]. * * Unlike [input], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("input") @ExcludeMissing fun _input(): JsonField = input + @JsonProperty("input") @ExcludeMissing fun _input(): JsonField = input /** * Returns the raw JSON value of [output]. * * Unlike [output], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("output") @ExcludeMissing fun _output(): JsonField = output + @JsonProperty("output") + @ExcludeMissing + fun _output(): JsonField = output @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { @@ -78,8 +83,8 @@ private constructor( /** A builder for [RealtimeAudioConfig]. */ class Builder internal constructor() { - private var input: JsonField = JsonMissing.of() - private var output: JsonField = JsonMissing.of() + private var input: JsonField = JsonMissing.of() + private var output: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic @@ -89,25 +94,27 @@ private constructor( additionalProperties = realtimeAudioConfig.additionalProperties.toMutableMap() } - fun input(input: Input) = input(JsonField.of(input)) + fun input(input: RealtimeAudioConfigInput) = input(JsonField.of(input)) /** * Sets [Builder.input] to an arbitrary JSON value. * - * You should usually call [Builder.input] with a well-typed [Input] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. + * You should usually call [Builder.input] with a well-typed [RealtimeAudioConfigInput] + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. */ - fun input(input: JsonField) = apply { this.input = input } + fun input(input: JsonField) = apply { this.input = input } - fun output(output: Output) = output(JsonField.of(output)) + fun output(output: RealtimeAudioConfigOutput) = output(JsonField.of(output)) /** * Sets [Builder.output] to an arbitrary JSON value. * - * You should usually call [Builder.output] with a well-typed [Output] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. + * You should usually call [Builder.output] with a well-typed [RealtimeAudioConfigOutput] + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. */ - fun output(output: JsonField) = apply { this.output = output } + fun output(output: JsonField) = apply { this.output = output } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() @@ -167,2529 +174,6 @@ private constructor( (input.asKnown().getOrNull()?.validity() ?: 0) + (output.asKnown().getOrNull()?.validity() ?: 0) - class Input - private constructor( - private val format: JsonField, - private val noiseReduction: JsonField, - private val transcription: JsonField, - private val turnDetection: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("format") @ExcludeMissing format: JsonField = JsonMissing.of(), - @JsonProperty("noise_reduction") - @ExcludeMissing - noiseReduction: JsonField = JsonMissing.of(), - @JsonProperty("transcription") - @ExcludeMissing - transcription: JsonField = JsonMissing.of(), - @JsonProperty("turn_detection") - @ExcludeMissing - turnDetection: JsonField = JsonMissing.of(), - ) : this(format, noiseReduction, transcription, turnDetection, mutableMapOf()) - - /** - * The format of input audio. Options are `pcm16`, `g711_ulaw`, or `g711_alaw`. For `pcm16`, - * input audio must be 16-bit PCM at a 24kHz sample rate, single channel (mono), and - * little-endian byte order. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun format(): Optional = format.getOptional("format") - - /** - * Configuration for input audio noise reduction. This can be set to `null` to turn off. - * Noise reduction filters audio added to the input audio buffer before it is sent to VAD - * and the model. Filtering the audio can improve VAD and turn detection accuracy (reducing - * false positives) and model performance by improving perception of the input audio. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun noiseReduction(): Optional = - noiseReduction.getOptional("noise_reduction") - - /** - * Configuration for input audio transcription, defaults to off and can be set to `null` to - * turn off once on. Input audio transcription is not native to the model, since the model - * consumes audio directly. Transcription runs asynchronously through - * [the /audio/transcriptions endpoint](https://platform.openai.com/docs/api-reference/audio/createTranscription) - * and should be treated as guidance of input audio content rather than precisely what the - * model heard. The client can optionally set the language and prompt for transcription, - * these offer additional guidance to the transcription service. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun transcription(): Optional = transcription.getOptional("transcription") - - /** - * Configuration for turn detection, ether Server VAD or Semantic VAD. This can be set to - * `null` to turn off, in which case the client must manually trigger model response. Server - * VAD means that the model will detect the start and end of speech based on audio volume - * and respond at the end of user speech. Semantic VAD is more advanced and uses a turn - * detection model (in conjunction with VAD) to semantically estimate whether the user has - * finished speaking, then dynamically sets a timeout based on this probability. For - * example, if user audio trails off with "uhhm", the model will score a low probability of - * turn end and wait longer for the user to continue speaking. This can be useful for more - * natural conversations, but may have a higher latency. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun turnDetection(): Optional = turnDetection.getOptional("turn_detection") - - /** - * Returns the raw JSON value of [format]. - * - * Unlike [format], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("format") @ExcludeMissing fun _format(): JsonField = format - - /** - * Returns the raw JSON value of [noiseReduction]. - * - * Unlike [noiseReduction], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("noise_reduction") - @ExcludeMissing - fun _noiseReduction(): JsonField = noiseReduction - - /** - * Returns the raw JSON value of [transcription]. - * - * Unlike [transcription], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("transcription") - @ExcludeMissing - fun _transcription(): JsonField = transcription - - /** - * Returns the raw JSON value of [turnDetection]. - * - * Unlike [turnDetection], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("turn_detection") - @ExcludeMissing - fun _turnDetection(): JsonField = turnDetection - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** Returns a mutable builder for constructing an instance of [Input]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Input]. */ - class Builder internal constructor() { - - private var format: JsonField = JsonMissing.of() - private var noiseReduction: JsonField = JsonMissing.of() - private var transcription: JsonField = JsonMissing.of() - private var turnDetection: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(input: Input) = apply { - format = input.format - noiseReduction = input.noiseReduction - transcription = input.transcription - turnDetection = input.turnDetection - additionalProperties = input.additionalProperties.toMutableMap() - } - - /** - * The format of input audio. Options are `pcm16`, `g711_ulaw`, or `g711_alaw`. For - * `pcm16`, input audio must be 16-bit PCM at a 24kHz sample rate, single channel - * (mono), and little-endian byte order. - */ - fun format(format: Format) = format(JsonField.of(format)) - - /** - * Sets [Builder.format] to an arbitrary JSON value. - * - * You should usually call [Builder.format] with a well-typed [Format] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun format(format: JsonField) = apply { this.format = format } - - /** - * Configuration for input audio noise reduction. This can be set to `null` to turn off. - * Noise reduction filters audio added to the input audio buffer before it is sent to - * VAD and the model. Filtering the audio can improve VAD and turn detection accuracy - * (reducing false positives) and model performance by improving perception of the input - * audio. - */ - fun noiseReduction(noiseReduction: NoiseReduction) = - noiseReduction(JsonField.of(noiseReduction)) - - /** - * Sets [Builder.noiseReduction] to an arbitrary JSON value. - * - * You should usually call [Builder.noiseReduction] with a well-typed [NoiseReduction] - * value instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun noiseReduction(noiseReduction: JsonField) = apply { - this.noiseReduction = noiseReduction - } - - /** - * Configuration for input audio transcription, defaults to off and can be set to `null` - * to turn off once on. Input audio transcription is not native to the model, since the - * model consumes audio directly. Transcription runs asynchronously through - * [the /audio/transcriptions endpoint](https://platform.openai.com/docs/api-reference/audio/createTranscription) - * and should be treated as guidance of input audio content rather than precisely what - * the model heard. The client can optionally set the language and prompt for - * transcription, these offer additional guidance to the transcription service. - */ - fun transcription(transcription: Transcription) = - transcription(JsonField.of(transcription)) - - /** - * Sets [Builder.transcription] to an arbitrary JSON value. - * - * You should usually call [Builder.transcription] with a well-typed [Transcription] - * value instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun transcription(transcription: JsonField) = apply { - this.transcription = transcription - } - - /** - * Configuration for turn detection, ether Server VAD or Semantic VAD. This can be set - * to `null` to turn off, in which case the client must manually trigger model response. - * Server VAD means that the model will detect the start and end of speech based on - * audio volume and respond at the end of user speech. Semantic VAD is more advanced and - * uses a turn detection model (in conjunction with VAD) to semantically estimate - * whether the user has finished speaking, then dynamically sets a timeout based on this - * probability. For example, if user audio trails off with "uhhm", the model will score - * a low probability of turn end and wait longer for the user to continue speaking. This - * can be useful for more natural conversations, but may have a higher latency. - */ - fun turnDetection(turnDetection: TurnDetection) = - turnDetection(JsonField.of(turnDetection)) - - /** - * Sets [Builder.turnDetection] to an arbitrary JSON value. - * - * You should usually call [Builder.turnDetection] with a well-typed [TurnDetection] - * value instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun turnDetection(turnDetection: JsonField) = apply { - this.turnDetection = turnDetection - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [Input]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Input = - Input( - format, - noiseReduction, - transcription, - turnDetection, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): Input = apply { - if (validated) { - return@apply - } - - format().ifPresent { it.validate() } - noiseReduction().ifPresent { it.validate() } - transcription().ifPresent { it.validate() } - turnDetection().ifPresent { it.validate() } - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (format.asKnown().getOrNull()?.validity() ?: 0) + - (noiseReduction.asKnown().getOrNull()?.validity() ?: 0) + - (transcription.asKnown().getOrNull()?.validity() ?: 0) + - (turnDetection.asKnown().getOrNull()?.validity() ?: 0) - - /** - * The format of input audio. Options are `pcm16`, `g711_ulaw`, or `g711_alaw`. For `pcm16`, - * input audio must be 16-bit PCM at a 24kHz sample rate, single channel (mono), and - * little-endian byte order. - */ - class Format @JsonCreator private constructor(private val value: JsonField) : Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that doesn't - * match any known member, and you want to know that value. For example, if the SDK is - * on an older version than the API, then the API may respond with new members that the - * SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val PCM16 = of("pcm16") - - @JvmField val G711_ULAW = of("g711_ulaw") - - @JvmField val G711_ALAW = of("g711_alaw") - - @JvmStatic fun of(value: String) = Format(JsonField.of(value)) - } - - /** An enum containing [Format]'s known values. */ - enum class Known { - PCM16, - G711_ULAW, - G711_ALAW, - } - - /** - * An enum containing [Format]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Format] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, if - * the SDK is on an older version than the API, then the API may respond with new - * members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - PCM16, - G711_ULAW, - G711_ALAW, - /** - * An enum member indicating that [Format] was instantiated with an unknown value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if you - * want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - PCM16 -> Value.PCM16 - G711_ULAW -> Value.G711_ULAW - G711_ALAW -> Value.G711_ALAW - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and - * don't want to throw for the unknown case. - * - * @throws OpenAIInvalidDataException if this class instance's value is a not a known - * member. - */ - fun known(): Known = - when (this) { - PCM16 -> Known.PCM16 - G711_ULAW -> Known.G711_ULAW - G711_ALAW -> Known.G711_ALAW - else -> throw OpenAIInvalidDataException("Unknown Format: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for - * debugging and generally doesn't throw. - * - * @throws OpenAIInvalidDataException if this class instance's value does not have the - * expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - OpenAIInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): Format = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Format && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - /** - * Configuration for input audio noise reduction. This can be set to `null` to turn off. - * Noise reduction filters audio added to the input audio buffer before it is sent to VAD - * and the model. Filtering the audio can improve VAD and turn detection accuracy (reducing - * false positives) and model performance by improving perception of the input audio. - */ - class NoiseReduction - private constructor( - private val type: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of() - ) : this(type, mutableMapOf()) - - /** - * Type of noise reduction. `near_field` is for close-talking microphones such as - * headphones, `far_field` is for far-field microphones such as laptop or conference - * room microphones. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun type(): Optional = type.getOptional("type") - - /** - * Returns the raw JSON value of [type]. - * - * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** Returns a mutable builder for constructing an instance of [NoiseReduction]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [NoiseReduction]. */ - class Builder internal constructor() { - - private var type: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(noiseReduction: NoiseReduction) = apply { - type = noiseReduction.type - additionalProperties = noiseReduction.additionalProperties.toMutableMap() - } - - /** - * Type of noise reduction. `near_field` is for close-talking microphones such as - * headphones, `far_field` is for far-field microphones such as laptop or conference - * room microphones. - */ - fun type(type: Type) = type(JsonField.of(type)) - - /** - * Sets [Builder.type] to an arbitrary JSON value. - * - * You should usually call [Builder.type] with a well-typed [Type] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun type(type: JsonField) = apply { this.type = type } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [NoiseReduction]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): NoiseReduction = - NoiseReduction(type, additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false - - fun validate(): NoiseReduction = apply { - if (validated) { - return@apply - } - - type().ifPresent { it.validate() } - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = (type.asKnown().getOrNull()?.validity() ?: 0) - - /** - * Type of noise reduction. `near_field` is for close-talking microphones such as - * headphones, `far_field` is for far-field microphones such as laptop or conference - * room microphones. - */ - class Type @JsonCreator private constructor(private val value: JsonField) : - Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that - * doesn't match any known member, and you want to know that value. For example, if - * the SDK is on an older version than the API, then the API may respond with new - * members that the SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val NEAR_FIELD = of("near_field") - - @JvmField val FAR_FIELD = of("far_field") - - @JvmStatic fun of(value: String) = Type(JsonField.of(value)) - } - - /** An enum containing [Type]'s known values. */ - enum class Known { - NEAR_FIELD, - FAR_FIELD, - } - - /** - * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Type] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, - * if the SDK is on an older version than the API, then the API may respond with - * new members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - NEAR_FIELD, - FAR_FIELD, - /** - * An enum member indicating that [Type] was instantiated with an unknown value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if - * you want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - NEAR_FIELD -> Value.NEAR_FIELD - FAR_FIELD -> Value.FAR_FIELD - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and - * don't want to throw for the unknown case. - * - * @throws OpenAIInvalidDataException if this class instance's value is a not a - * known member. - */ - fun known(): Known = - when (this) { - NEAR_FIELD -> Known.NEAR_FIELD - FAR_FIELD -> Known.FAR_FIELD - else -> throw OpenAIInvalidDataException("Unknown Type: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for - * debugging and generally doesn't throw. - * - * @throws OpenAIInvalidDataException if this class instance's value does not have - * the expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - OpenAIInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): Type = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is NoiseReduction && - type == other.type && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { Objects.hash(type, additionalProperties) } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "NoiseReduction{type=$type, additionalProperties=$additionalProperties}" - } - - /** - * Configuration for input audio transcription, defaults to off and can be set to `null` to - * turn off once on. Input audio transcription is not native to the model, since the model - * consumes audio directly. Transcription runs asynchronously through - * [the /audio/transcriptions endpoint](https://platform.openai.com/docs/api-reference/audio/createTranscription) - * and should be treated as guidance of input audio content rather than precisely what the - * model heard. The client can optionally set the language and prompt for transcription, - * these offer additional guidance to the transcription service. - */ - class Transcription - private constructor( - private val language: JsonField, - private val model: JsonField, - private val prompt: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("language") - @ExcludeMissing - language: JsonField = JsonMissing.of(), - @JsonProperty("model") @ExcludeMissing model: JsonField = JsonMissing.of(), - @JsonProperty("prompt") @ExcludeMissing prompt: JsonField = JsonMissing.of(), - ) : this(language, model, prompt, mutableMapOf()) - - /** - * The language of the input audio. Supplying the input language in - * [ISO-639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) (e.g. `en`) format - * will improve accuracy and latency. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun language(): Optional = language.getOptional("language") - - /** - * The model to use for transcription. Current options are `whisper-1`, - * `gpt-4o-transcribe-latest`, `gpt-4o-mini-transcribe`, `gpt-4o-transcribe`, and - * `gpt-4o-transcribe-diarize`. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun model(): Optional = model.getOptional("model") - - /** - * An optional text to guide the model's style or continue a previous audio segment. For - * `whisper-1`, the - * [prompt is a list of keywords](https://platform.openai.com/docs/guides/speech-to-text#prompting). - * For `gpt-4o-transcribe` models, the prompt is a free text string, for example "expect - * words related to technology". - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun prompt(): Optional = prompt.getOptional("prompt") - - /** - * Returns the raw JSON value of [language]. - * - * Unlike [language], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("language") @ExcludeMissing fun _language(): JsonField = language - - /** - * Returns the raw JSON value of [model]. - * - * Unlike [model], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("model") @ExcludeMissing fun _model(): JsonField = model - - /** - * Returns the raw JSON value of [prompt]. - * - * Unlike [prompt], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("prompt") @ExcludeMissing fun _prompt(): JsonField = prompt - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** Returns a mutable builder for constructing an instance of [Transcription]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Transcription]. */ - class Builder internal constructor() { - - private var language: JsonField = JsonMissing.of() - private var model: JsonField = JsonMissing.of() - private var prompt: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(transcription: Transcription) = apply { - language = transcription.language - model = transcription.model - prompt = transcription.prompt - additionalProperties = transcription.additionalProperties.toMutableMap() - } - - /** - * The language of the input audio. Supplying the input language in - * [ISO-639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) (e.g. `en`) - * format will improve accuracy and latency. - */ - fun language(language: String) = language(JsonField.of(language)) - - /** - * Sets [Builder.language] to an arbitrary JSON value. - * - * You should usually call [Builder.language] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun language(language: JsonField) = apply { this.language = language } - - /** - * The model to use for transcription. Current options are `whisper-1`, - * `gpt-4o-transcribe-latest`, `gpt-4o-mini-transcribe`, `gpt-4o-transcribe`, and - * `gpt-4o-transcribe-diarize`. - */ - fun model(model: Model) = model(JsonField.of(model)) - - /** - * Sets [Builder.model] to an arbitrary JSON value. - * - * You should usually call [Builder.model] with a well-typed [Model] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun model(model: JsonField) = apply { this.model = model } - - /** - * An optional text to guide the model's style or continue a previous audio segment. - * For `whisper-1`, the - * [prompt is a list of keywords](https://platform.openai.com/docs/guides/speech-to-text#prompting). - * For `gpt-4o-transcribe` models, the prompt is a free text string, for example - * "expect words related to technology". - */ - fun prompt(prompt: String) = prompt(JsonField.of(prompt)) - - /** - * Sets [Builder.prompt] to an arbitrary JSON value. - * - * You should usually call [Builder.prompt] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun prompt(prompt: JsonField) = apply { this.prompt = prompt } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [Transcription]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Transcription = - Transcription(language, model, prompt, additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false - - fun validate(): Transcription = apply { - if (validated) { - return@apply - } - - language() - model().ifPresent { it.validate() } - prompt() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (if (language.asKnown().isPresent) 1 else 0) + - (model.asKnown().getOrNull()?.validity() ?: 0) + - (if (prompt.asKnown().isPresent) 1 else 0) - - /** - * The model to use for transcription. Current options are `whisper-1`, - * `gpt-4o-transcribe-latest`, `gpt-4o-mini-transcribe`, `gpt-4o-transcribe`, and - * `gpt-4o-transcribe-diarize`. - */ - class Model @JsonCreator private constructor(private val value: JsonField) : - Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that - * doesn't match any known member, and you want to know that value. For example, if - * the SDK is on an older version than the API, then the API may respond with new - * members that the SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val WHISPER_1 = of("whisper-1") - - @JvmField val GPT_4O_TRANSCRIBE_LATEST = of("gpt-4o-transcribe-latest") - - @JvmField val GPT_4O_MINI_TRANSCRIBE = of("gpt-4o-mini-transcribe") - - @JvmField val GPT_4O_TRANSCRIBE = of("gpt-4o-transcribe") - - @JvmField val GPT_4O_TRANSCRIBE_DIARIZE = of("gpt-4o-transcribe-diarize") - - @JvmStatic fun of(value: String) = Model(JsonField.of(value)) - } - - /** An enum containing [Model]'s known values. */ - enum class Known { - WHISPER_1, - GPT_4O_TRANSCRIBE_LATEST, - GPT_4O_MINI_TRANSCRIBE, - GPT_4O_TRANSCRIBE, - GPT_4O_TRANSCRIBE_DIARIZE, - } - - /** - * An enum containing [Model]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Model] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, - * if the SDK is on an older version than the API, then the API may respond with - * new members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - WHISPER_1, - GPT_4O_TRANSCRIBE_LATEST, - GPT_4O_MINI_TRANSCRIBE, - GPT_4O_TRANSCRIBE, - GPT_4O_TRANSCRIBE_DIARIZE, - /** - * An enum member indicating that [Model] was instantiated with an unknown - * value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if - * you want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - WHISPER_1 -> Value.WHISPER_1 - GPT_4O_TRANSCRIBE_LATEST -> Value.GPT_4O_TRANSCRIBE_LATEST - GPT_4O_MINI_TRANSCRIBE -> Value.GPT_4O_MINI_TRANSCRIBE - GPT_4O_TRANSCRIBE -> Value.GPT_4O_TRANSCRIBE - GPT_4O_TRANSCRIBE_DIARIZE -> Value.GPT_4O_TRANSCRIBE_DIARIZE - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and - * don't want to throw for the unknown case. - * - * @throws OpenAIInvalidDataException if this class instance's value is a not a - * known member. - */ - fun known(): Known = - when (this) { - WHISPER_1 -> Known.WHISPER_1 - GPT_4O_TRANSCRIBE_LATEST -> Known.GPT_4O_TRANSCRIBE_LATEST - GPT_4O_MINI_TRANSCRIBE -> Known.GPT_4O_MINI_TRANSCRIBE - GPT_4O_TRANSCRIBE -> Known.GPT_4O_TRANSCRIBE - GPT_4O_TRANSCRIBE_DIARIZE -> Known.GPT_4O_TRANSCRIBE_DIARIZE - else -> throw OpenAIInvalidDataException("Unknown Model: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for - * debugging and generally doesn't throw. - * - * @throws OpenAIInvalidDataException if this class instance's value does not have - * the expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - OpenAIInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): Model = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Model && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Transcription && - language == other.language && - model == other.model && - prompt == other.prompt && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash(language, model, prompt, additionalProperties) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Transcription{language=$language, model=$model, prompt=$prompt, additionalProperties=$additionalProperties}" - } - - /** - * Configuration for turn detection, ether Server VAD or Semantic VAD. This can be set to - * `null` to turn off, in which case the client must manually trigger model response. Server - * VAD means that the model will detect the start and end of speech based on audio volume - * and respond at the end of user speech. Semantic VAD is more advanced and uses a turn - * detection model (in conjunction with VAD) to semantically estimate whether the user has - * finished speaking, then dynamically sets a timeout based on this probability. For - * example, if user audio trails off with "uhhm", the model will score a low probability of - * turn end and wait longer for the user to continue speaking. This can be useful for more - * natural conversations, but may have a higher latency. - */ - class TurnDetection - private constructor( - private val createResponse: JsonField, - private val eagerness: JsonField, - private val idleTimeoutMs: JsonField, - private val interruptResponse: JsonField, - private val prefixPaddingMs: JsonField, - private val silenceDurationMs: JsonField, - private val threshold: JsonField, - private val type: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("create_response") - @ExcludeMissing - createResponse: JsonField = JsonMissing.of(), - @JsonProperty("eagerness") - @ExcludeMissing - eagerness: JsonField = JsonMissing.of(), - @JsonProperty("idle_timeout_ms") - @ExcludeMissing - idleTimeoutMs: JsonField = JsonMissing.of(), - @JsonProperty("interrupt_response") - @ExcludeMissing - interruptResponse: JsonField = JsonMissing.of(), - @JsonProperty("prefix_padding_ms") - @ExcludeMissing - prefixPaddingMs: JsonField = JsonMissing.of(), - @JsonProperty("silence_duration_ms") - @ExcludeMissing - silenceDurationMs: JsonField = JsonMissing.of(), - @JsonProperty("threshold") - @ExcludeMissing - threshold: JsonField = JsonMissing.of(), - @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), - ) : this( - createResponse, - eagerness, - idleTimeoutMs, - interruptResponse, - prefixPaddingMs, - silenceDurationMs, - threshold, - type, - mutableMapOf(), - ) - - /** - * Whether or not to automatically generate a response when a VAD stop event occurs. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun createResponse(): Optional = createResponse.getOptional("create_response") - - /** - * Used only for `semantic_vad` mode. The eagerness of the model to respond. `low` will - * wait longer for the user to continue speaking, `high` will respond more quickly. - * `auto` is the default and is equivalent to `medium`. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun eagerness(): Optional = eagerness.getOptional("eagerness") - - /** - * Optional idle timeout after which turn detection will auto-timeout when no additional - * audio is received. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun idleTimeoutMs(): Optional = idleTimeoutMs.getOptional("idle_timeout_ms") - - /** - * Whether or not to automatically interrupt any ongoing response with output to the - * default conversation (i.e. `conversation` of `auto`) when a VAD start event occurs. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun interruptResponse(): Optional = - interruptResponse.getOptional("interrupt_response") - - /** - * Used only for `server_vad` mode. Amount of audio to include before the VAD detected - * speech (in milliseconds). Defaults to 300ms. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun prefixPaddingMs(): Optional = prefixPaddingMs.getOptional("prefix_padding_ms") - - /** - * Used only for `server_vad` mode. Duration of silence to detect speech stop (in - * milliseconds). Defaults to 500ms. With shorter values the model will respond more - * quickly, but may jump in on short pauses from the user. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun silenceDurationMs(): Optional = - silenceDurationMs.getOptional("silence_duration_ms") - - /** - * Used only for `server_vad` mode. Activation threshold for VAD (0.0 to 1.0), this - * defaults to 0.5. A higher threshold will require louder audio to activate the model, - * and thus might perform better in noisy environments. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun threshold(): Optional = threshold.getOptional("threshold") - - /** - * Type of turn detection. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun type(): Optional = type.getOptional("type") - - /** - * Returns the raw JSON value of [createResponse]. - * - * Unlike [createResponse], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("create_response") - @ExcludeMissing - fun _createResponse(): JsonField = createResponse - - /** - * Returns the raw JSON value of [eagerness]. - * - * Unlike [eagerness], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("eagerness") - @ExcludeMissing - fun _eagerness(): JsonField = eagerness - - /** - * Returns the raw JSON value of [idleTimeoutMs]. - * - * Unlike [idleTimeoutMs], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("idle_timeout_ms") - @ExcludeMissing - fun _idleTimeoutMs(): JsonField = idleTimeoutMs - - /** - * Returns the raw JSON value of [interruptResponse]. - * - * Unlike [interruptResponse], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("interrupt_response") - @ExcludeMissing - fun _interruptResponse(): JsonField = interruptResponse - - /** - * Returns the raw JSON value of [prefixPaddingMs]. - * - * Unlike [prefixPaddingMs], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("prefix_padding_ms") - @ExcludeMissing - fun _prefixPaddingMs(): JsonField = prefixPaddingMs - - /** - * Returns the raw JSON value of [silenceDurationMs]. - * - * Unlike [silenceDurationMs], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("silence_duration_ms") - @ExcludeMissing - fun _silenceDurationMs(): JsonField = silenceDurationMs - - /** - * Returns the raw JSON value of [threshold]. - * - * Unlike [threshold], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("threshold") - @ExcludeMissing - fun _threshold(): JsonField = threshold - - /** - * Returns the raw JSON value of [type]. - * - * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** Returns a mutable builder for constructing an instance of [TurnDetection]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [TurnDetection]. */ - class Builder internal constructor() { - - private var createResponse: JsonField = JsonMissing.of() - private var eagerness: JsonField = JsonMissing.of() - private var idleTimeoutMs: JsonField = JsonMissing.of() - private var interruptResponse: JsonField = JsonMissing.of() - private var prefixPaddingMs: JsonField = JsonMissing.of() - private var silenceDurationMs: JsonField = JsonMissing.of() - private var threshold: JsonField = JsonMissing.of() - private var type: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(turnDetection: TurnDetection) = apply { - createResponse = turnDetection.createResponse - eagerness = turnDetection.eagerness - idleTimeoutMs = turnDetection.idleTimeoutMs - interruptResponse = turnDetection.interruptResponse - prefixPaddingMs = turnDetection.prefixPaddingMs - silenceDurationMs = turnDetection.silenceDurationMs - threshold = turnDetection.threshold - type = turnDetection.type - additionalProperties = turnDetection.additionalProperties.toMutableMap() - } - - /** - * Whether or not to automatically generate a response when a VAD stop event occurs. - */ - fun createResponse(createResponse: Boolean) = - createResponse(JsonField.of(createResponse)) - - /** - * Sets [Builder.createResponse] to an arbitrary JSON value. - * - * You should usually call [Builder.createResponse] with a well-typed [Boolean] - * value instead. This method is primarily for setting the field to an undocumented - * or not yet supported value. - */ - fun createResponse(createResponse: JsonField) = apply { - this.createResponse = createResponse - } - - /** - * Used only for `semantic_vad` mode. The eagerness of the model to respond. `low` - * will wait longer for the user to continue speaking, `high` will respond more - * quickly. `auto` is the default and is equivalent to `medium`. - */ - fun eagerness(eagerness: Eagerness) = eagerness(JsonField.of(eagerness)) - - /** - * Sets [Builder.eagerness] to an arbitrary JSON value. - * - * You should usually call [Builder.eagerness] with a well-typed [Eagerness] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun eagerness(eagerness: JsonField) = apply { - this.eagerness = eagerness - } - - /** - * Optional idle timeout after which turn detection will auto-timeout when no - * additional audio is received. - */ - fun idleTimeoutMs(idleTimeoutMs: Long?) = - idleTimeoutMs(JsonField.ofNullable(idleTimeoutMs)) - - /** - * Alias for [Builder.idleTimeoutMs]. - * - * This unboxed primitive overload exists for backwards compatibility. - */ - fun idleTimeoutMs(idleTimeoutMs: Long) = idleTimeoutMs(idleTimeoutMs as Long?) - - /** Alias for calling [Builder.idleTimeoutMs] with `idleTimeoutMs.orElse(null)`. */ - fun idleTimeoutMs(idleTimeoutMs: Optional) = - idleTimeoutMs(idleTimeoutMs.getOrNull()) - - /** - * Sets [Builder.idleTimeoutMs] to an arbitrary JSON value. - * - * You should usually call [Builder.idleTimeoutMs] with a well-typed [Long] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun idleTimeoutMs(idleTimeoutMs: JsonField) = apply { - this.idleTimeoutMs = idleTimeoutMs - } - - /** - * Whether or not to automatically interrupt any ongoing response with output to the - * default conversation (i.e. `conversation` of `auto`) when a VAD start event - * occurs. - */ - fun interruptResponse(interruptResponse: Boolean) = - interruptResponse(JsonField.of(interruptResponse)) - - /** - * Sets [Builder.interruptResponse] to an arbitrary JSON value. - * - * You should usually call [Builder.interruptResponse] with a well-typed [Boolean] - * value instead. This method is primarily for setting the field to an undocumented - * or not yet supported value. - */ - fun interruptResponse(interruptResponse: JsonField) = apply { - this.interruptResponse = interruptResponse - } - - /** - * Used only for `server_vad` mode. Amount of audio to include before the VAD - * detected speech (in milliseconds). Defaults to 300ms. - */ - fun prefixPaddingMs(prefixPaddingMs: Long) = - prefixPaddingMs(JsonField.of(prefixPaddingMs)) - - /** - * Sets [Builder.prefixPaddingMs] to an arbitrary JSON value. - * - * You should usually call [Builder.prefixPaddingMs] with a well-typed [Long] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun prefixPaddingMs(prefixPaddingMs: JsonField) = apply { - this.prefixPaddingMs = prefixPaddingMs - } - - /** - * Used only for `server_vad` mode. Duration of silence to detect speech stop (in - * milliseconds). Defaults to 500ms. With shorter values the model will respond more - * quickly, but may jump in on short pauses from the user. - */ - fun silenceDurationMs(silenceDurationMs: Long) = - silenceDurationMs(JsonField.of(silenceDurationMs)) - - /** - * Sets [Builder.silenceDurationMs] to an arbitrary JSON value. - * - * You should usually call [Builder.silenceDurationMs] with a well-typed [Long] - * value instead. This method is primarily for setting the field to an undocumented - * or not yet supported value. - */ - fun silenceDurationMs(silenceDurationMs: JsonField) = apply { - this.silenceDurationMs = silenceDurationMs - } - - /** - * Used only for `server_vad` mode. Activation threshold for VAD (0.0 to 1.0), this - * defaults to 0.5. A higher threshold will require louder audio to activate the - * model, and thus might perform better in noisy environments. - */ - fun threshold(threshold: Double) = threshold(JsonField.of(threshold)) - - /** - * Sets [Builder.threshold] to an arbitrary JSON value. - * - * You should usually call [Builder.threshold] with a well-typed [Double] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun threshold(threshold: JsonField) = apply { this.threshold = threshold } - - /** Type of turn detection. */ - fun type(type: Type) = type(JsonField.of(type)) - - /** - * Sets [Builder.type] to an arbitrary JSON value. - * - * You should usually call [Builder.type] with a well-typed [Type] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun type(type: JsonField) = apply { this.type = type } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [TurnDetection]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): TurnDetection = - TurnDetection( - createResponse, - eagerness, - idleTimeoutMs, - interruptResponse, - prefixPaddingMs, - silenceDurationMs, - threshold, - type, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): TurnDetection = apply { - if (validated) { - return@apply - } - - createResponse() - eagerness().ifPresent { it.validate() } - idleTimeoutMs() - interruptResponse() - prefixPaddingMs() - silenceDurationMs() - threshold() - type().ifPresent { it.validate() } - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (if (createResponse.asKnown().isPresent) 1 else 0) + - (eagerness.asKnown().getOrNull()?.validity() ?: 0) + - (if (idleTimeoutMs.asKnown().isPresent) 1 else 0) + - (if (interruptResponse.asKnown().isPresent) 1 else 0) + - (if (prefixPaddingMs.asKnown().isPresent) 1 else 0) + - (if (silenceDurationMs.asKnown().isPresent) 1 else 0) + - (if (threshold.asKnown().isPresent) 1 else 0) + - (type.asKnown().getOrNull()?.validity() ?: 0) - - /** - * Used only for `semantic_vad` mode. The eagerness of the model to respond. `low` will - * wait longer for the user to continue speaking, `high` will respond more quickly. - * `auto` is the default and is equivalent to `medium`. - */ - class Eagerness @JsonCreator private constructor(private val value: JsonField) : - Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that - * doesn't match any known member, and you want to know that value. For example, if - * the SDK is on an older version than the API, then the API may respond with new - * members that the SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val LOW = of("low") - - @JvmField val MEDIUM = of("medium") - - @JvmField val HIGH = of("high") - - @JvmField val AUTO = of("auto") - - @JvmStatic fun of(value: String) = Eagerness(JsonField.of(value)) - } - - /** An enum containing [Eagerness]'s known values. */ - enum class Known { - LOW, - MEDIUM, - HIGH, - AUTO, - } - - /** - * An enum containing [Eagerness]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Eagerness] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, - * if the SDK is on an older version than the API, then the API may respond with - * new members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - LOW, - MEDIUM, - HIGH, - AUTO, - /** - * An enum member indicating that [Eagerness] was instantiated with an unknown - * value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if - * you want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - LOW -> Value.LOW - MEDIUM -> Value.MEDIUM - HIGH -> Value.HIGH - AUTO -> Value.AUTO - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and - * don't want to throw for the unknown case. - * - * @throws OpenAIInvalidDataException if this class instance's value is a not a - * known member. - */ - fun known(): Known = - when (this) { - LOW -> Known.LOW - MEDIUM -> Known.MEDIUM - HIGH -> Known.HIGH - AUTO -> Known.AUTO - else -> throw OpenAIInvalidDataException("Unknown Eagerness: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for - * debugging and generally doesn't throw. - * - * @throws OpenAIInvalidDataException if this class instance's value does not have - * the expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - OpenAIInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): Eagerness = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Eagerness && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - /** Type of turn detection. */ - class Type @JsonCreator private constructor(private val value: JsonField) : - Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that - * doesn't match any known member, and you want to know that value. For example, if - * the SDK is on an older version than the API, then the API may respond with new - * members that the SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val SERVER_VAD = of("server_vad") - - @JvmField val SEMANTIC_VAD = of("semantic_vad") - - @JvmStatic fun of(value: String) = Type(JsonField.of(value)) - } - - /** An enum containing [Type]'s known values. */ - enum class Known { - SERVER_VAD, - SEMANTIC_VAD, - } - - /** - * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Type] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, - * if the SDK is on an older version than the API, then the API may respond with - * new members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - SERVER_VAD, - SEMANTIC_VAD, - /** - * An enum member indicating that [Type] was instantiated with an unknown value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if - * you want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - SERVER_VAD -> Value.SERVER_VAD - SEMANTIC_VAD -> Value.SEMANTIC_VAD - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and - * don't want to throw for the unknown case. - * - * @throws OpenAIInvalidDataException if this class instance's value is a not a - * known member. - */ - fun known(): Known = - when (this) { - SERVER_VAD -> Known.SERVER_VAD - SEMANTIC_VAD -> Known.SEMANTIC_VAD - else -> throw OpenAIInvalidDataException("Unknown Type: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for - * debugging and generally doesn't throw. - * - * @throws OpenAIInvalidDataException if this class instance's value does not have - * the expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - OpenAIInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): Type = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is TurnDetection && - createResponse == other.createResponse && - eagerness == other.eagerness && - idleTimeoutMs == other.idleTimeoutMs && - interruptResponse == other.interruptResponse && - prefixPaddingMs == other.prefixPaddingMs && - silenceDurationMs == other.silenceDurationMs && - threshold == other.threshold && - type == other.type && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash( - createResponse, - eagerness, - idleTimeoutMs, - interruptResponse, - prefixPaddingMs, - silenceDurationMs, - threshold, - type, - additionalProperties, - ) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "TurnDetection{createResponse=$createResponse, eagerness=$eagerness, idleTimeoutMs=$idleTimeoutMs, interruptResponse=$interruptResponse, prefixPaddingMs=$prefixPaddingMs, silenceDurationMs=$silenceDurationMs, threshold=$threshold, type=$type, additionalProperties=$additionalProperties}" - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Input && - format == other.format && - noiseReduction == other.noiseReduction && - transcription == other.transcription && - turnDetection == other.turnDetection && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash(format, noiseReduction, transcription, turnDetection, additionalProperties) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Input{format=$format, noiseReduction=$noiseReduction, transcription=$transcription, turnDetection=$turnDetection, additionalProperties=$additionalProperties}" - } - - class Output - private constructor( - private val format: JsonField, - private val speed: JsonField, - private val voice: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("format") @ExcludeMissing format: JsonField = JsonMissing.of(), - @JsonProperty("speed") @ExcludeMissing speed: JsonField = JsonMissing.of(), - @JsonProperty("voice") @ExcludeMissing voice: JsonField = JsonMissing.of(), - ) : this(format, speed, voice, mutableMapOf()) - - /** - * The format of output audio. Options are `pcm16`, `g711_ulaw`, or `g711_alaw`. For - * `pcm16`, output audio is sampled at a rate of 24kHz. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun format(): Optional = format.getOptional("format") - - /** - * The speed of the model's spoken response. 1.0 is the default speed. 0.25 is the minimum - * speed. 1.5 is the maximum speed. This value can only be changed in between model turns, - * not while a response is in progress. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun speed(): Optional = speed.getOptional("speed") - - /** - * The voice the model uses to respond. Voice cannot be changed during the session once the - * model has responded with audio at least once. Current voice options are `alloy`, `ash`, - * `ballad`, `coral`, `echo`, `sage`, `shimmer`, `verse`, `marin`, and `cedar`. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun voice(): Optional = voice.getOptional("voice") - - /** - * Returns the raw JSON value of [format]. - * - * Unlike [format], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("format") @ExcludeMissing fun _format(): JsonField = format - - /** - * Returns the raw JSON value of [speed]. - * - * Unlike [speed], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("speed") @ExcludeMissing fun _speed(): JsonField = speed - - /** - * Returns the raw JSON value of [voice]. - * - * Unlike [voice], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("voice") @ExcludeMissing fun _voice(): JsonField = voice - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** Returns a mutable builder for constructing an instance of [Output]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Output]. */ - class Builder internal constructor() { - - private var format: JsonField = JsonMissing.of() - private var speed: JsonField = JsonMissing.of() - private var voice: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(output: Output) = apply { - format = output.format - speed = output.speed - voice = output.voice - additionalProperties = output.additionalProperties.toMutableMap() - } - - /** - * The format of output audio. Options are `pcm16`, `g711_ulaw`, or `g711_alaw`. For - * `pcm16`, output audio is sampled at a rate of 24kHz. - */ - fun format(format: Format) = format(JsonField.of(format)) - - /** - * Sets [Builder.format] to an arbitrary JSON value. - * - * You should usually call [Builder.format] with a well-typed [Format] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun format(format: JsonField) = apply { this.format = format } - - /** - * The speed of the model's spoken response. 1.0 is the default speed. 0.25 is the - * minimum speed. 1.5 is the maximum speed. This value can only be changed in between - * model turns, not while a response is in progress. - */ - fun speed(speed: Double) = speed(JsonField.of(speed)) - - /** - * Sets [Builder.speed] to an arbitrary JSON value. - * - * You should usually call [Builder.speed] with a well-typed [Double] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun speed(speed: JsonField) = apply { this.speed = speed } - - /** - * The voice the model uses to respond. Voice cannot be changed during the session once - * the model has responded with audio at least once. Current voice options are `alloy`, - * `ash`, `ballad`, `coral`, `echo`, `sage`, `shimmer`, `verse`, `marin`, and `cedar`. - */ - fun voice(voice: Voice) = voice(JsonField.of(voice)) - - /** - * Sets [Builder.voice] to an arbitrary JSON value. - * - * You should usually call [Builder.voice] with a well-typed [Voice] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun voice(voice: JsonField) = apply { this.voice = voice } - - /** - * Sets [voice] to an arbitrary [String]. - * - * You should usually call [voice] with a well-typed [Voice] constant instead. This - * method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun voice(value: String) = voice(Voice.of(value)) - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [Output]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Output = Output(format, speed, voice, additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false - - fun validate(): Output = apply { - if (validated) { - return@apply - } - - format().ifPresent { it.validate() } - speed() - voice() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (format.asKnown().getOrNull()?.validity() ?: 0) + - (if (speed.asKnown().isPresent) 1 else 0) + - (if (voice.asKnown().isPresent) 1 else 0) - - /** - * The format of output audio. Options are `pcm16`, `g711_ulaw`, or `g711_alaw`. For - * `pcm16`, output audio is sampled at a rate of 24kHz. - */ - class Format @JsonCreator private constructor(private val value: JsonField) : Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that doesn't - * match any known member, and you want to know that value. For example, if the SDK is - * on an older version than the API, then the API may respond with new members that the - * SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val PCM16 = of("pcm16") - - @JvmField val G711_ULAW = of("g711_ulaw") - - @JvmField val G711_ALAW = of("g711_alaw") - - @JvmStatic fun of(value: String) = Format(JsonField.of(value)) - } - - /** An enum containing [Format]'s known values. */ - enum class Known { - PCM16, - G711_ULAW, - G711_ALAW, - } - - /** - * An enum containing [Format]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Format] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, if - * the SDK is on an older version than the API, then the API may respond with new - * members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - PCM16, - G711_ULAW, - G711_ALAW, - /** - * An enum member indicating that [Format] was instantiated with an unknown value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if you - * want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - PCM16 -> Value.PCM16 - G711_ULAW -> Value.G711_ULAW - G711_ALAW -> Value.G711_ALAW - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and - * don't want to throw for the unknown case. - * - * @throws OpenAIInvalidDataException if this class instance's value is a not a known - * member. - */ - fun known(): Known = - when (this) { - PCM16 -> Known.PCM16 - G711_ULAW -> Known.G711_ULAW - G711_ALAW -> Known.G711_ALAW - else -> throw OpenAIInvalidDataException("Unknown Format: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for - * debugging and generally doesn't throw. - * - * @throws OpenAIInvalidDataException if this class instance's value does not have the - * expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - OpenAIInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): Format = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Format && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - /** - * The voice the model uses to respond. Voice cannot be changed during the session once the - * model has responded with audio at least once. Current voice options are `alloy`, `ash`, - * `ballad`, `coral`, `echo`, `sage`, `shimmer`, `verse`, `marin`, and `cedar`. - */ - class Voice @JsonCreator private constructor(private val value: JsonField) : Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that doesn't - * match any known member, and you want to know that value. For example, if the SDK is - * on an older version than the API, then the API may respond with new members that the - * SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val ALLOY = of("alloy") - - @JvmField val ASH = of("ash") - - @JvmField val BALLAD = of("ballad") - - @JvmField val CORAL = of("coral") - - @JvmField val ECHO = of("echo") - - @JvmField val SAGE = of("sage") - - @JvmField val SHIMMER = of("shimmer") - - @JvmField val VERSE = of("verse") - - @JvmField val MARIN = of("marin") - - @JvmField val CEDAR = of("cedar") - - @JvmStatic fun of(value: String) = Voice(JsonField.of(value)) - } - - /** An enum containing [Voice]'s known values. */ - enum class Known { - ALLOY, - ASH, - BALLAD, - CORAL, - ECHO, - SAGE, - SHIMMER, - VERSE, - MARIN, - CEDAR, - } - - /** - * An enum containing [Voice]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Voice] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, if - * the SDK is on an older version than the API, then the API may respond with new - * members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - ALLOY, - ASH, - BALLAD, - CORAL, - ECHO, - SAGE, - SHIMMER, - VERSE, - MARIN, - CEDAR, - /** - * An enum member indicating that [Voice] was instantiated with an unknown value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if you - * want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - ALLOY -> Value.ALLOY - ASH -> Value.ASH - BALLAD -> Value.BALLAD - CORAL -> Value.CORAL - ECHO -> Value.ECHO - SAGE -> Value.SAGE - SHIMMER -> Value.SHIMMER - VERSE -> Value.VERSE - MARIN -> Value.MARIN - CEDAR -> Value.CEDAR - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and - * don't want to throw for the unknown case. - * - * @throws OpenAIInvalidDataException if this class instance's value is a not a known - * member. - */ - fun known(): Known = - when (this) { - ALLOY -> Known.ALLOY - ASH -> Known.ASH - BALLAD -> Known.BALLAD - CORAL -> Known.CORAL - ECHO -> Known.ECHO - SAGE -> Known.SAGE - SHIMMER -> Known.SHIMMER - VERSE -> Known.VERSE - MARIN -> Known.MARIN - CEDAR -> Known.CEDAR - else -> throw OpenAIInvalidDataException("Unknown Voice: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for - * debugging and generally doesn't throw. - * - * @throws OpenAIInvalidDataException if this class instance's value does not have the - * expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - OpenAIInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): Voice = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Voice && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Output && - format == other.format && - speed == other.speed && - voice == other.voice && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash(format, speed, voice, additionalProperties) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Output{format=$format, speed=$speed, voice=$voice, additionalProperties=$additionalProperties}" - } - override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeAudioConfigInput.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeAudioConfigInput.kt new file mode 100644 index 00000000..3f72a49f --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeAudioConfigInput.kt @@ -0,0 +1,499 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.realtime + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class RealtimeAudioConfigInput +private constructor( + private val format: JsonField, + private val noiseReduction: JsonField, + private val transcription: JsonField, + private val turnDetection: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("format") + @ExcludeMissing + format: JsonField = JsonMissing.of(), + @JsonProperty("noise_reduction") + @ExcludeMissing + noiseReduction: JsonField = JsonMissing.of(), + @JsonProperty("transcription") + @ExcludeMissing + transcription: JsonField = JsonMissing.of(), + @JsonProperty("turn_detection") + @ExcludeMissing + turnDetection: JsonField = JsonMissing.of(), + ) : this(format, noiseReduction, transcription, turnDetection, mutableMapOf()) + + /** + * The format of the input audio. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun format(): Optional = format.getOptional("format") + + /** + * Configuration for input audio noise reduction. This can be set to `null` to turn off. Noise + * reduction filters audio added to the input audio buffer before it is sent to VAD and the + * model. Filtering the audio can improve VAD and turn detection accuracy (reducing false + * positives) and model performance by improving perception of the input audio. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun noiseReduction(): Optional = noiseReduction.getOptional("noise_reduction") + + /** + * Configuration for input audio transcription, defaults to off and can be set to `null` to turn + * off once on. Input audio transcription is not native to the model, since the model consumes + * audio directly. Transcription runs asynchronously through + * [the /audio/transcriptions endpoint](https://platform.openai.com/docs/api-reference/audio/createTranscription) + * and should be treated as guidance of input audio content rather than precisely what the model + * heard. The client can optionally set the language and prompt for transcription, these offer + * additional guidance to the transcription service. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun transcription(): Optional = transcription.getOptional("transcription") + + /** + * Configuration for turn detection, ether Server VAD or Semantic VAD. This can be set to `null` + * to turn off, in which case the client must manually trigger model response. Server VAD means + * that the model will detect the start and end of speech based on audio volume and respond at + * the end of user speech. Semantic VAD is more advanced and uses a turn detection model (in + * conjunction with VAD) to semantically estimate whether the user has finished speaking, then + * dynamically sets a timeout based on this probability. For example, if user audio trails off + * with "uhhm", the model will score a low probability of turn end and wait longer for the user + * to continue speaking. This can be useful for more natural conversations, but may have a + * higher latency. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun turnDetection(): Optional = + turnDetection.getOptional("turn_detection") + + /** + * Returns the raw JSON value of [format]. + * + * Unlike [format], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("format") @ExcludeMissing fun _format(): JsonField = format + + /** + * Returns the raw JSON value of [noiseReduction]. + * + * Unlike [noiseReduction], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("noise_reduction") + @ExcludeMissing + fun _noiseReduction(): JsonField = noiseReduction + + /** + * Returns the raw JSON value of [transcription]. + * + * Unlike [transcription], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("transcription") + @ExcludeMissing + fun _transcription(): JsonField = transcription + + /** + * Returns the raw JSON value of [turnDetection]. + * + * Unlike [turnDetection], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("turn_detection") + @ExcludeMissing + fun _turnDetection(): JsonField = turnDetection + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [RealtimeAudioConfigInput]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [RealtimeAudioConfigInput]. */ + class Builder internal constructor() { + + private var format: JsonField = JsonMissing.of() + private var noiseReduction: JsonField = JsonMissing.of() + private var transcription: JsonField = JsonMissing.of() + private var turnDetection: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(realtimeAudioConfigInput: RealtimeAudioConfigInput) = apply { + format = realtimeAudioConfigInput.format + noiseReduction = realtimeAudioConfigInput.noiseReduction + transcription = realtimeAudioConfigInput.transcription + turnDetection = realtimeAudioConfigInput.turnDetection + additionalProperties = realtimeAudioConfigInput.additionalProperties.toMutableMap() + } + + /** The format of the input audio. */ + fun format(format: RealtimeAudioFormats) = format(JsonField.of(format)) + + /** + * Sets [Builder.format] to an arbitrary JSON value. + * + * You should usually call [Builder.format] with a well-typed [RealtimeAudioFormats] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun format(format: JsonField) = apply { this.format = format } + + /** Alias for calling [format] with `RealtimeAudioFormats.ofAudioPcm(audioPcm)`. */ + fun format(audioPcm: RealtimeAudioFormats.AudioPcm) = + format(RealtimeAudioFormats.ofAudioPcm(audioPcm)) + + /** Alias for calling [format] with `RealtimeAudioFormats.ofAudioPcmu(audioPcmu)`. */ + fun format(audioPcmu: RealtimeAudioFormats.AudioPcmu) = + format(RealtimeAudioFormats.ofAudioPcmu(audioPcmu)) + + /** Alias for calling [format] with `RealtimeAudioFormats.ofAudioPcma(audioPcma)`. */ + fun format(audioPcma: RealtimeAudioFormats.AudioPcma) = + format(RealtimeAudioFormats.ofAudioPcma(audioPcma)) + + /** + * Configuration for input audio noise reduction. This can be set to `null` to turn off. + * Noise reduction filters audio added to the input audio buffer before it is sent to VAD + * and the model. Filtering the audio can improve VAD and turn detection accuracy (reducing + * false positives) and model performance by improving perception of the input audio. + */ + fun noiseReduction(noiseReduction: NoiseReduction) = + noiseReduction(JsonField.of(noiseReduction)) + + /** + * Sets [Builder.noiseReduction] to an arbitrary JSON value. + * + * You should usually call [Builder.noiseReduction] with a well-typed [NoiseReduction] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun noiseReduction(noiseReduction: JsonField) = apply { + this.noiseReduction = noiseReduction + } + + /** + * Configuration for input audio transcription, defaults to off and can be set to `null` to + * turn off once on. Input audio transcription is not native to the model, since the model + * consumes audio directly. Transcription runs asynchronously through + * [the /audio/transcriptions endpoint](https://platform.openai.com/docs/api-reference/audio/createTranscription) + * and should be treated as guidance of input audio content rather than precisely what the + * model heard. The client can optionally set the language and prompt for transcription, + * these offer additional guidance to the transcription service. + */ + fun transcription(transcription: AudioTranscription) = + transcription(JsonField.of(transcription)) + + /** + * Sets [Builder.transcription] to an arbitrary JSON value. + * + * You should usually call [Builder.transcription] with a well-typed [AudioTranscription] + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun transcription(transcription: JsonField) = apply { + this.transcription = transcription + } + + /** + * Configuration for turn detection, ether Server VAD or Semantic VAD. This can be set to + * `null` to turn off, in which case the client must manually trigger model response. Server + * VAD means that the model will detect the start and end of speech based on audio volume + * and respond at the end of user speech. Semantic VAD is more advanced and uses a turn + * detection model (in conjunction with VAD) to semantically estimate whether the user has + * finished speaking, then dynamically sets a timeout based on this probability. For + * example, if user audio trails off with "uhhm", the model will score a low probability of + * turn end and wait longer for the user to continue speaking. This can be useful for more + * natural conversations, but may have a higher latency. + */ + fun turnDetection(turnDetection: RealtimeAudioInputTurnDetection) = + turnDetection(JsonField.of(turnDetection)) + + /** + * Sets [Builder.turnDetection] to an arbitrary JSON value. + * + * You should usually call [Builder.turnDetection] with a well-typed + * [RealtimeAudioInputTurnDetection] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun turnDetection(turnDetection: JsonField) = apply { + this.turnDetection = turnDetection + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [RealtimeAudioConfigInput]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): RealtimeAudioConfigInput = + RealtimeAudioConfigInput( + format, + noiseReduction, + transcription, + turnDetection, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): RealtimeAudioConfigInput = apply { + if (validated) { + return@apply + } + + format().ifPresent { it.validate() } + noiseReduction().ifPresent { it.validate() } + transcription().ifPresent { it.validate() } + turnDetection().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (format.asKnown().getOrNull()?.validity() ?: 0) + + (noiseReduction.asKnown().getOrNull()?.validity() ?: 0) + + (transcription.asKnown().getOrNull()?.validity() ?: 0) + + (turnDetection.asKnown().getOrNull()?.validity() ?: 0) + + /** + * Configuration for input audio noise reduction. This can be set to `null` to turn off. Noise + * reduction filters audio added to the input audio buffer before it is sent to VAD and the + * model. Filtering the audio can improve VAD and turn detection accuracy (reducing false + * positives) and model performance by improving perception of the input audio. + */ + class NoiseReduction + private constructor( + private val type: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("type") + @ExcludeMissing + type: JsonField = JsonMissing.of() + ) : this(type, mutableMapOf()) + + /** + * Type of noise reduction. `near_field` is for close-talking microphones such as + * headphones, `far_field` is for far-field microphones such as laptop or conference room + * microphones. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun type(): Optional = type.getOptional("type") + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [NoiseReduction]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [NoiseReduction]. */ + class Builder internal constructor() { + + private var type: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(noiseReduction: NoiseReduction) = apply { + type = noiseReduction.type + additionalProperties = noiseReduction.additionalProperties.toMutableMap() + } + + /** + * Type of noise reduction. `near_field` is for close-talking microphones such as + * headphones, `far_field` is for far-field microphones such as laptop or conference + * room microphones. + */ + fun type(type: NoiseReductionType) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [NoiseReductionType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [NoiseReduction]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): NoiseReduction = NoiseReduction(type, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): NoiseReduction = apply { + if (validated) { + return@apply + } + + type().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = (type.asKnown().getOrNull()?.validity() ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is NoiseReduction && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(type, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "NoiseReduction{type=$type, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is RealtimeAudioConfigInput && + format == other.format && + noiseReduction == other.noiseReduction && + transcription == other.transcription && + turnDetection == other.turnDetection && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(format, noiseReduction, transcription, turnDetection, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "RealtimeAudioConfigInput{format=$format, noiseReduction=$noiseReduction, transcription=$transcription, turnDetection=$turnDetection, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeAudioConfigOutput.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeAudioConfigOutput.kt new file mode 100644 index 00000000..5fbc0e91 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeAudioConfigOutput.kt @@ -0,0 +1,449 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.realtime + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.Enum +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class RealtimeAudioConfigOutput +private constructor( + private val format: JsonField, + private val speed: JsonField, + private val voice: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("format") + @ExcludeMissing + format: JsonField = JsonMissing.of(), + @JsonProperty("speed") @ExcludeMissing speed: JsonField = JsonMissing.of(), + @JsonProperty("voice") @ExcludeMissing voice: JsonField = JsonMissing.of(), + ) : this(format, speed, voice, mutableMapOf()) + + /** + * The format of the output audio. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun format(): Optional = format.getOptional("format") + + /** + * The speed of the model's spoken response as a multiple of the original speed. 1.0 is the + * default speed. 0.25 is the minimum speed. 1.5 is the maximum speed. This value can only be + * changed in between model turns, not while a response is in progress. + * + * This parameter is a post-processing adjustment to the audio after it is generated, it's also + * possible to prompt the model to speak faster or slower. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun speed(): Optional = speed.getOptional("speed") + + /** + * The voice the model uses to respond. Voice cannot be changed during the session once the + * model has responded with audio at least once. Current voice options are `alloy`, `ash`, + * `ballad`, `coral`, `echo`, `sage`, `shimmer`, `verse`, `marin`, and `cedar`. We recommend + * `marin` and `cedar` for best quality. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun voice(): Optional = voice.getOptional("voice") + + /** + * Returns the raw JSON value of [format]. + * + * Unlike [format], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("format") @ExcludeMissing fun _format(): JsonField = format + + /** + * Returns the raw JSON value of [speed]. + * + * Unlike [speed], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("speed") @ExcludeMissing fun _speed(): JsonField = speed + + /** + * Returns the raw JSON value of [voice]. + * + * Unlike [voice], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("voice") @ExcludeMissing fun _voice(): JsonField = voice + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [RealtimeAudioConfigOutput]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [RealtimeAudioConfigOutput]. */ + class Builder internal constructor() { + + private var format: JsonField = JsonMissing.of() + private var speed: JsonField = JsonMissing.of() + private var voice: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(realtimeAudioConfigOutput: RealtimeAudioConfigOutput) = apply { + format = realtimeAudioConfigOutput.format + speed = realtimeAudioConfigOutput.speed + voice = realtimeAudioConfigOutput.voice + additionalProperties = realtimeAudioConfigOutput.additionalProperties.toMutableMap() + } + + /** The format of the output audio. */ + fun format(format: RealtimeAudioFormats) = format(JsonField.of(format)) + + /** + * Sets [Builder.format] to an arbitrary JSON value. + * + * You should usually call [Builder.format] with a well-typed [RealtimeAudioFormats] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun format(format: JsonField) = apply { this.format = format } + + /** Alias for calling [format] with `RealtimeAudioFormats.ofAudioPcm(audioPcm)`. */ + fun format(audioPcm: RealtimeAudioFormats.AudioPcm) = + format(RealtimeAudioFormats.ofAudioPcm(audioPcm)) + + /** Alias for calling [format] with `RealtimeAudioFormats.ofAudioPcmu(audioPcmu)`. */ + fun format(audioPcmu: RealtimeAudioFormats.AudioPcmu) = + format(RealtimeAudioFormats.ofAudioPcmu(audioPcmu)) + + /** Alias for calling [format] with `RealtimeAudioFormats.ofAudioPcma(audioPcma)`. */ + fun format(audioPcma: RealtimeAudioFormats.AudioPcma) = + format(RealtimeAudioFormats.ofAudioPcma(audioPcma)) + + /** + * The speed of the model's spoken response as a multiple of the original speed. 1.0 is the + * default speed. 0.25 is the minimum speed. 1.5 is the maximum speed. This value can only + * be changed in between model turns, not while a response is in progress. + * + * This parameter is a post-processing adjustment to the audio after it is generated, it's + * also possible to prompt the model to speak faster or slower. + */ + fun speed(speed: Double) = speed(JsonField.of(speed)) + + /** + * Sets [Builder.speed] to an arbitrary JSON value. + * + * You should usually call [Builder.speed] with a well-typed [Double] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun speed(speed: JsonField) = apply { this.speed = speed } + + /** + * The voice the model uses to respond. Voice cannot be changed during the session once the + * model has responded with audio at least once. Current voice options are `alloy`, `ash`, + * `ballad`, `coral`, `echo`, `sage`, `shimmer`, `verse`, `marin`, and `cedar`. We recommend + * `marin` and `cedar` for best quality. + */ + fun voice(voice: Voice) = voice(JsonField.of(voice)) + + /** + * Sets [Builder.voice] to an arbitrary JSON value. + * + * You should usually call [Builder.voice] with a well-typed [Voice] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun voice(voice: JsonField) = apply { this.voice = voice } + + /** + * Sets [voice] to an arbitrary [String]. + * + * You should usually call [voice] with a well-typed [Voice] constant instead. This method + * is primarily for setting the field to an undocumented or not yet supported value. + */ + fun voice(value: String) = voice(Voice.of(value)) + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [RealtimeAudioConfigOutput]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): RealtimeAudioConfigOutput = + RealtimeAudioConfigOutput(format, speed, voice, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): RealtimeAudioConfigOutput = apply { + if (validated) { + return@apply + } + + format().ifPresent { it.validate() } + speed() + voice() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (format.asKnown().getOrNull()?.validity() ?: 0) + + (if (speed.asKnown().isPresent) 1 else 0) + + (if (voice.asKnown().isPresent) 1 else 0) + + /** + * The voice the model uses to respond. Voice cannot be changed during the session once the + * model has responded with audio at least once. Current voice options are `alloy`, `ash`, + * `ballad`, `coral`, `echo`, `sage`, `shimmer`, `verse`, `marin`, and `cedar`. We recommend + * `marin` and `cedar` for best quality. + */ + class Voice @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val ALLOY = of("alloy") + + @JvmField val ASH = of("ash") + + @JvmField val BALLAD = of("ballad") + + @JvmField val CORAL = of("coral") + + @JvmField val ECHO = of("echo") + + @JvmField val SAGE = of("sage") + + @JvmField val SHIMMER = of("shimmer") + + @JvmField val VERSE = of("verse") + + @JvmField val MARIN = of("marin") + + @JvmField val CEDAR = of("cedar") + + @JvmStatic fun of(value: String) = Voice(JsonField.of(value)) + } + + /** An enum containing [Voice]'s known values. */ + enum class Known { + ALLOY, + ASH, + BALLAD, + CORAL, + ECHO, + SAGE, + SHIMMER, + VERSE, + MARIN, + CEDAR, + } + + /** + * An enum containing [Voice]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Voice] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + ALLOY, + ASH, + BALLAD, + CORAL, + ECHO, + SAGE, + SHIMMER, + VERSE, + MARIN, + CEDAR, + /** An enum member indicating that [Voice] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + ALLOY -> Value.ALLOY + ASH -> Value.ASH + BALLAD -> Value.BALLAD + CORAL -> Value.CORAL + ECHO -> Value.ECHO + SAGE -> Value.SAGE + SHIMMER -> Value.SHIMMER + VERSE -> Value.VERSE + MARIN -> Value.MARIN + CEDAR -> Value.CEDAR + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + ALLOY -> Known.ALLOY + ASH -> Known.ASH + BALLAD -> Known.BALLAD + CORAL -> Known.CORAL + ECHO -> Known.ECHO + SAGE -> Known.SAGE + SHIMMER -> Known.SHIMMER + VERSE -> Known.VERSE + MARIN -> Known.MARIN + CEDAR -> Known.CEDAR + else -> throw OpenAIInvalidDataException("Unknown Voice: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): Voice = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Voice && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is RealtimeAudioConfigOutput && + format == other.format && + speed == other.speed && + voice == other.voice && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(format, speed, voice, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "RealtimeAudioConfigOutput{format=$format, speed=$speed, voice=$voice, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeAudioFormats.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeAudioFormats.kt new file mode 100644 index 00000000..1ce219d8 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeAudioFormats.kt @@ -0,0 +1,1182 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.realtime + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.BaseDeserializer +import com.openai.core.BaseSerializer +import com.openai.core.Enum +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.getOrThrow +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** The PCM audio format. Only a 24kHz sample rate is supported. */ +@JsonDeserialize(using = RealtimeAudioFormats.Deserializer::class) +@JsonSerialize(using = RealtimeAudioFormats.Serializer::class) +class RealtimeAudioFormats +private constructor( + private val audioPcm: AudioPcm? = null, + private val audioPcmu: AudioPcmu? = null, + private val audioPcma: AudioPcma? = null, + private val _json: JsonValue? = null, +) { + + /** The PCM audio format. Only a 24kHz sample rate is supported. */ + fun audioPcm(): Optional = Optional.ofNullable(audioPcm) + + /** The G.711 μ-law format. */ + fun audioPcmu(): Optional = Optional.ofNullable(audioPcmu) + + /** The G.711 A-law format. */ + fun audioPcma(): Optional = Optional.ofNullable(audioPcma) + + fun isAudioPcm(): Boolean = audioPcm != null + + fun isAudioPcmu(): Boolean = audioPcmu != null + + fun isAudioPcma(): Boolean = audioPcma != null + + /** The PCM audio format. Only a 24kHz sample rate is supported. */ + fun asAudioPcm(): AudioPcm = audioPcm.getOrThrow("audioPcm") + + /** The G.711 μ-law format. */ + fun asAudioPcmu(): AudioPcmu = audioPcmu.getOrThrow("audioPcmu") + + /** The G.711 A-law format. */ + fun asAudioPcma(): AudioPcma = audioPcma.getOrThrow("audioPcma") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + audioPcm != null -> visitor.visitAudioPcm(audioPcm) + audioPcmu != null -> visitor.visitAudioPcmu(audioPcmu) + audioPcma != null -> visitor.visitAudioPcma(audioPcma) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): RealtimeAudioFormats = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitAudioPcm(audioPcm: AudioPcm) { + audioPcm.validate() + } + + override fun visitAudioPcmu(audioPcmu: AudioPcmu) { + audioPcmu.validate() + } + + override fun visitAudioPcma(audioPcma: AudioPcma) { + audioPcma.validate() + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitAudioPcm(audioPcm: AudioPcm) = audioPcm.validity() + + override fun visitAudioPcmu(audioPcmu: AudioPcmu) = audioPcmu.validity() + + override fun visitAudioPcma(audioPcma: AudioPcma) = audioPcma.validity() + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is RealtimeAudioFormats && + audioPcm == other.audioPcm && + audioPcmu == other.audioPcmu && + audioPcma == other.audioPcma + } + + override fun hashCode(): Int = Objects.hash(audioPcm, audioPcmu, audioPcma) + + override fun toString(): String = + when { + audioPcm != null -> "RealtimeAudioFormats{audioPcm=$audioPcm}" + audioPcmu != null -> "RealtimeAudioFormats{audioPcmu=$audioPcmu}" + audioPcma != null -> "RealtimeAudioFormats{audioPcma=$audioPcma}" + _json != null -> "RealtimeAudioFormats{_unknown=$_json}" + else -> throw IllegalStateException("Invalid RealtimeAudioFormats") + } + + companion object { + + /** The PCM audio format. Only a 24kHz sample rate is supported. */ + @JvmStatic fun ofAudioPcm(audioPcm: AudioPcm) = RealtimeAudioFormats(audioPcm = audioPcm) + + /** The G.711 μ-law format. */ + @JvmStatic + fun ofAudioPcmu(audioPcmu: AudioPcmu) = RealtimeAudioFormats(audioPcmu = audioPcmu) + + /** The G.711 A-law format. */ + @JvmStatic + fun ofAudioPcma(audioPcma: AudioPcma) = RealtimeAudioFormats(audioPcma = audioPcma) + } + + /** + * An interface that defines how to map each variant of [RealtimeAudioFormats] to a value of + * type [T]. + */ + interface Visitor { + + /** The PCM audio format. Only a 24kHz sample rate is supported. */ + fun visitAudioPcm(audioPcm: AudioPcm): T + + /** The G.711 μ-law format. */ + fun visitAudioPcmu(audioPcmu: AudioPcmu): T + + /** The G.711 A-law format. */ + fun visitAudioPcma(audioPcma: AudioPcma): T + + /** + * Maps an unknown variant of [RealtimeAudioFormats] to a value of type [T]. + * + * An instance of [RealtimeAudioFormats] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For example, if the SDK is + * on an older version than the API, then the API may respond with new variants that the SDK + * is unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown RealtimeAudioFormats: $json") + } + } + + internal class Deserializer : + BaseDeserializer(RealtimeAudioFormats::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): RealtimeAudioFormats { + val json = JsonValue.fromJsonNode(node) + val type = json.asObject().getOrNull()?.get("type")?.asString()?.getOrNull() + + when (type) { + "audio/pcm" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + RealtimeAudioFormats(audioPcm = it, _json = json) + } ?: RealtimeAudioFormats(_json = json) + } + "audio/pcmu" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + RealtimeAudioFormats(audioPcmu = it, _json = json) + } ?: RealtimeAudioFormats(_json = json) + } + "audio/pcma" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + RealtimeAudioFormats(audioPcma = it, _json = json) + } ?: RealtimeAudioFormats(_json = json) + } + } + + return RealtimeAudioFormats(_json = json) + } + } + + internal class Serializer : BaseSerializer(RealtimeAudioFormats::class) { + + override fun serialize( + value: RealtimeAudioFormats, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.audioPcm != null -> generator.writeObject(value.audioPcm) + value.audioPcmu != null -> generator.writeObject(value.audioPcmu) + value.audioPcma != null -> generator.writeObject(value.audioPcma) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid RealtimeAudioFormats") + } + } + } + + /** The PCM audio format. Only a 24kHz sample rate is supported. */ + class AudioPcm + private constructor( + private val rate: JsonField, + private val type: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("rate") @ExcludeMissing rate: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + ) : this(rate, type, mutableMapOf()) + + /** + * The sample rate of the audio. Always `24000`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun rate(): Optional = rate.getOptional("rate") + + /** + * The audio format. Always `audio/pcm`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun type(): Optional = type.getOptional("type") + + /** + * Returns the raw JSON value of [rate]. + * + * Unlike [rate], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("rate") @ExcludeMissing fun _rate(): JsonField = rate + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [AudioPcm]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AudioPcm]. */ + class Builder internal constructor() { + + private var rate: JsonField = JsonMissing.of() + private var type: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(audioPcm: AudioPcm) = apply { + rate = audioPcm.rate + type = audioPcm.type + additionalProperties = audioPcm.additionalProperties.toMutableMap() + } + + /** The sample rate of the audio. Always `24000`. */ + fun rate(rate: Rate) = rate(JsonField.of(rate)) + + /** + * Sets [Builder.rate] to an arbitrary JSON value. + * + * You should usually call [Builder.rate] with a well-typed [Rate] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun rate(rate: JsonField) = apply { this.rate = rate } + + /** The audio format. Always `audio/pcm`. */ + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonField) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [AudioPcm]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AudioPcm = AudioPcm(rate, type, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): AudioPcm = apply { + if (validated) { + return@apply + } + + rate().ifPresent { it.validate() } + type().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (rate.asKnown().getOrNull()?.validity() ?: 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + /** The sample rate of the audio. Always `24000`. */ + class Rate @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val _24000 = of(24000L) + + @JvmStatic fun of(value: Long) = Rate(JsonField.of(value)) + } + + /** An enum containing [Rate]'s known values. */ + enum class Known { + _24000 + } + + /** + * An enum containing [Rate]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Rate] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + _24000, + /** An enum member indicating that [Rate] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you + * want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + _24000 -> Value._24000 + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + _24000 -> Known._24000 + else -> throw OpenAIInvalidDataException("Unknown Rate: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asLong(): Long = + _value().asNumber().getOrNull()?.let { + if (it.toDouble() % 1 == 0.0) it.toLong() else null + } ?: throw OpenAIInvalidDataException("Value is not a Long") + + private var validated: Boolean = false + + fun validate(): Rate = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Rate && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** The audio format. Always `audio/pcm`. */ + class Type @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val AUDIO_PCM = of("audio/pcm") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + AUDIO_PCM + } + + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + AUDIO_PCM, + /** An enum member indicating that [Type] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you + * want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + AUDIO_PCM -> Value.AUDIO_PCM + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + AUDIO_PCM -> Known.AUDIO_PCM + else -> throw OpenAIInvalidDataException("Unknown Type: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + OpenAIInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Type = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Type && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AudioPcm && + rate == other.rate && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(rate, type, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AudioPcm{rate=$rate, type=$type, additionalProperties=$additionalProperties}" + } + + /** The G.711 μ-law format. */ + class AudioPcmu + private constructor( + private val type: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of() + ) : this(type, mutableMapOf()) + + /** + * The audio format. Always `audio/pcmu`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun type(): Optional = type.getOptional("type") + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [AudioPcmu]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AudioPcmu]. */ + class Builder internal constructor() { + + private var type: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(audioPcmu: AudioPcmu) = apply { + type = audioPcmu.type + additionalProperties = audioPcmu.additionalProperties.toMutableMap() + } + + /** The audio format. Always `audio/pcmu`. */ + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonField) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [AudioPcmu]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AudioPcmu = AudioPcmu(type, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): AudioPcmu = apply { + if (validated) { + return@apply + } + + type().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = (type.asKnown().getOrNull()?.validity() ?: 0) + + /** The audio format. Always `audio/pcmu`. */ + class Type @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val AUDIO_PCMU = of("audio/pcmu") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + AUDIO_PCMU + } + + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + AUDIO_PCMU, + /** An enum member indicating that [Type] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you + * want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + AUDIO_PCMU -> Value.AUDIO_PCMU + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + AUDIO_PCMU -> Known.AUDIO_PCMU + else -> throw OpenAIInvalidDataException("Unknown Type: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + OpenAIInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Type = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Type && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AudioPcmu && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(type, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AudioPcmu{type=$type, additionalProperties=$additionalProperties}" + } + + /** The G.711 A-law format. */ + class AudioPcma + private constructor( + private val type: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of() + ) : this(type, mutableMapOf()) + + /** + * The audio format. Always `audio/pcma`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun type(): Optional = type.getOptional("type") + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [AudioPcma]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AudioPcma]. */ + class Builder internal constructor() { + + private var type: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(audioPcma: AudioPcma) = apply { + type = audioPcma.type + additionalProperties = audioPcma.additionalProperties.toMutableMap() + } + + /** The audio format. Always `audio/pcma`. */ + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonField) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [AudioPcma]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AudioPcma = AudioPcma(type, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): AudioPcma = apply { + if (validated) { + return@apply + } + + type().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = (type.asKnown().getOrNull()?.validity() ?: 0) + + /** The audio format. Always `audio/pcma`. */ + class Type @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val AUDIO_PCMA = of("audio/pcma") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + AUDIO_PCMA + } + + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + AUDIO_PCMA, + /** An enum member indicating that [Type] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you + * want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + AUDIO_PCMA -> Value.AUDIO_PCMA + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + AUDIO_PCMA -> Known.AUDIO_PCMA + else -> throw OpenAIInvalidDataException("Unknown Type: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + OpenAIInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Type = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Type && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AudioPcma && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(type, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AudioPcma{type=$type, additionalProperties=$additionalProperties}" + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeAudioInputTurnDetection.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeAudioInputTurnDetection.kt new file mode 100644 index 00000000..f86a67a4 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeAudioInputTurnDetection.kt @@ -0,0 +1,793 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.realtime + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.Enum +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Configuration for turn detection, ether Server VAD or Semantic VAD. This can be set to `null` to + * turn off, in which case the client must manually trigger model response. Server VAD means that + * the model will detect the start and end of speech based on audio volume and respond at the end of + * user speech. Semantic VAD is more advanced and uses a turn detection model (in conjunction with + * VAD) to semantically estimate whether the user has finished speaking, then dynamically sets a + * timeout based on this probability. For example, if user audio trails off with "uhhm", the model + * will score a low probability of turn end and wait longer for the user to continue speaking. This + * can be useful for more natural conversations, but may have a higher latency. + */ +class RealtimeAudioInputTurnDetection +private constructor( + private val createResponse: JsonField, + private val eagerness: JsonField, + private val idleTimeoutMs: JsonField, + private val interruptResponse: JsonField, + private val prefixPaddingMs: JsonField, + private val silenceDurationMs: JsonField, + private val threshold: JsonField, + private val type: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("create_response") + @ExcludeMissing + createResponse: JsonField = JsonMissing.of(), + @JsonProperty("eagerness") + @ExcludeMissing + eagerness: JsonField = JsonMissing.of(), + @JsonProperty("idle_timeout_ms") + @ExcludeMissing + idleTimeoutMs: JsonField = JsonMissing.of(), + @JsonProperty("interrupt_response") + @ExcludeMissing + interruptResponse: JsonField = JsonMissing.of(), + @JsonProperty("prefix_padding_ms") + @ExcludeMissing + prefixPaddingMs: JsonField = JsonMissing.of(), + @JsonProperty("silence_duration_ms") + @ExcludeMissing + silenceDurationMs: JsonField = JsonMissing.of(), + @JsonProperty("threshold") @ExcludeMissing threshold: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + ) : this( + createResponse, + eagerness, + idleTimeoutMs, + interruptResponse, + prefixPaddingMs, + silenceDurationMs, + threshold, + type, + mutableMapOf(), + ) + + /** + * Whether or not to automatically generate a response when a VAD stop event occurs. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun createResponse(): Optional = createResponse.getOptional("create_response") + + /** + * Used only for `semantic_vad` mode. The eagerness of the model to respond. `low` will wait + * longer for the user to continue speaking, `high` will respond more quickly. `auto` is the + * default and is equivalent to `medium`. `low`, `medium`, and `high` have max timeouts of 8s, + * 4s, and 2s respectively. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun eagerness(): Optional = eagerness.getOptional("eagerness") + + /** + * Optional idle timeout after which turn detection will auto-timeout when no additional audio + * is received. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun idleTimeoutMs(): Optional = idleTimeoutMs.getOptional("idle_timeout_ms") + + /** + * Whether or not to automatically interrupt any ongoing response with output to the default + * conversation (i.e. `conversation` of `auto`) when a VAD start event occurs. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun interruptResponse(): Optional = interruptResponse.getOptional("interrupt_response") + + /** + * Used only for `server_vad` mode. Amount of audio to include before the VAD detected speech + * (in milliseconds). Defaults to 300ms. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun prefixPaddingMs(): Optional = prefixPaddingMs.getOptional("prefix_padding_ms") + + /** + * Used only for `server_vad` mode. Duration of silence to detect speech stop (in milliseconds). + * Defaults to 500ms. With shorter values the model will respond more quickly, but may jump in + * on short pauses from the user. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun silenceDurationMs(): Optional = silenceDurationMs.getOptional("silence_duration_ms") + + /** + * Used only for `server_vad` mode. Activation threshold for VAD (0.0 to 1.0), this defaults to + * 0.5. A higher threshold will require louder audio to activate the model, and thus might + * perform better in noisy environments. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun threshold(): Optional = threshold.getOptional("threshold") + + /** + * Type of turn detection. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun type(): Optional = type.getOptional("type") + + /** + * Returns the raw JSON value of [createResponse]. + * + * Unlike [createResponse], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("create_response") + @ExcludeMissing + fun _createResponse(): JsonField = createResponse + + /** + * Returns the raw JSON value of [eagerness]. + * + * Unlike [eagerness], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("eagerness") @ExcludeMissing fun _eagerness(): JsonField = eagerness + + /** + * Returns the raw JSON value of [idleTimeoutMs]. + * + * Unlike [idleTimeoutMs], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("idle_timeout_ms") + @ExcludeMissing + fun _idleTimeoutMs(): JsonField = idleTimeoutMs + + /** + * Returns the raw JSON value of [interruptResponse]. + * + * Unlike [interruptResponse], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("interrupt_response") + @ExcludeMissing + fun _interruptResponse(): JsonField = interruptResponse + + /** + * Returns the raw JSON value of [prefixPaddingMs]. + * + * Unlike [prefixPaddingMs], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("prefix_padding_ms") + @ExcludeMissing + fun _prefixPaddingMs(): JsonField = prefixPaddingMs + + /** + * Returns the raw JSON value of [silenceDurationMs]. + * + * Unlike [silenceDurationMs], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("silence_duration_ms") + @ExcludeMissing + fun _silenceDurationMs(): JsonField = silenceDurationMs + + /** + * Returns the raw JSON value of [threshold]. + * + * Unlike [threshold], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("threshold") @ExcludeMissing fun _threshold(): JsonField = threshold + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [RealtimeAudioInputTurnDetection]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [RealtimeAudioInputTurnDetection]. */ + class Builder internal constructor() { + + private var createResponse: JsonField = JsonMissing.of() + private var eagerness: JsonField = JsonMissing.of() + private var idleTimeoutMs: JsonField = JsonMissing.of() + private var interruptResponse: JsonField = JsonMissing.of() + private var prefixPaddingMs: JsonField = JsonMissing.of() + private var silenceDurationMs: JsonField = JsonMissing.of() + private var threshold: JsonField = JsonMissing.of() + private var type: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(realtimeAudioInputTurnDetection: RealtimeAudioInputTurnDetection) = + apply { + createResponse = realtimeAudioInputTurnDetection.createResponse + eagerness = realtimeAudioInputTurnDetection.eagerness + idleTimeoutMs = realtimeAudioInputTurnDetection.idleTimeoutMs + interruptResponse = realtimeAudioInputTurnDetection.interruptResponse + prefixPaddingMs = realtimeAudioInputTurnDetection.prefixPaddingMs + silenceDurationMs = realtimeAudioInputTurnDetection.silenceDurationMs + threshold = realtimeAudioInputTurnDetection.threshold + type = realtimeAudioInputTurnDetection.type + additionalProperties = + realtimeAudioInputTurnDetection.additionalProperties.toMutableMap() + } + + /** Whether or not to automatically generate a response when a VAD stop event occurs. */ + fun createResponse(createResponse: Boolean) = createResponse(JsonField.of(createResponse)) + + /** + * Sets [Builder.createResponse] to an arbitrary JSON value. + * + * You should usually call [Builder.createResponse] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun createResponse(createResponse: JsonField) = apply { + this.createResponse = createResponse + } + + /** + * Used only for `semantic_vad` mode. The eagerness of the model to respond. `low` will wait + * longer for the user to continue speaking, `high` will respond more quickly. `auto` is the + * default and is equivalent to `medium`. `low`, `medium`, and `high` have max timeouts of + * 8s, 4s, and 2s respectively. + */ + fun eagerness(eagerness: Eagerness) = eagerness(JsonField.of(eagerness)) + + /** + * Sets [Builder.eagerness] to an arbitrary JSON value. + * + * You should usually call [Builder.eagerness] with a well-typed [Eagerness] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun eagerness(eagerness: JsonField) = apply { this.eagerness = eagerness } + + /** + * Optional idle timeout after which turn detection will auto-timeout when no additional + * audio is received. + */ + fun idleTimeoutMs(idleTimeoutMs: Long?) = idleTimeoutMs(JsonField.ofNullable(idleTimeoutMs)) + + /** + * Alias for [Builder.idleTimeoutMs]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun idleTimeoutMs(idleTimeoutMs: Long) = idleTimeoutMs(idleTimeoutMs as Long?) + + /** Alias for calling [Builder.idleTimeoutMs] with `idleTimeoutMs.orElse(null)`. */ + fun idleTimeoutMs(idleTimeoutMs: Optional) = idleTimeoutMs(idleTimeoutMs.getOrNull()) + + /** + * Sets [Builder.idleTimeoutMs] to an arbitrary JSON value. + * + * You should usually call [Builder.idleTimeoutMs] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun idleTimeoutMs(idleTimeoutMs: JsonField) = apply { + this.idleTimeoutMs = idleTimeoutMs + } + + /** + * Whether or not to automatically interrupt any ongoing response with output to the default + * conversation (i.e. `conversation` of `auto`) when a VAD start event occurs. + */ + fun interruptResponse(interruptResponse: Boolean) = + interruptResponse(JsonField.of(interruptResponse)) + + /** + * Sets [Builder.interruptResponse] to an arbitrary JSON value. + * + * You should usually call [Builder.interruptResponse] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun interruptResponse(interruptResponse: JsonField) = apply { + this.interruptResponse = interruptResponse + } + + /** + * Used only for `server_vad` mode. Amount of audio to include before the VAD detected + * speech (in milliseconds). Defaults to 300ms. + */ + fun prefixPaddingMs(prefixPaddingMs: Long) = prefixPaddingMs(JsonField.of(prefixPaddingMs)) + + /** + * Sets [Builder.prefixPaddingMs] to an arbitrary JSON value. + * + * You should usually call [Builder.prefixPaddingMs] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun prefixPaddingMs(prefixPaddingMs: JsonField) = apply { + this.prefixPaddingMs = prefixPaddingMs + } + + /** + * Used only for `server_vad` mode. Duration of silence to detect speech stop (in + * milliseconds). Defaults to 500ms. With shorter values the model will respond more + * quickly, but may jump in on short pauses from the user. + */ + fun silenceDurationMs(silenceDurationMs: Long) = + silenceDurationMs(JsonField.of(silenceDurationMs)) + + /** + * Sets [Builder.silenceDurationMs] to an arbitrary JSON value. + * + * You should usually call [Builder.silenceDurationMs] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun silenceDurationMs(silenceDurationMs: JsonField) = apply { + this.silenceDurationMs = silenceDurationMs + } + + /** + * Used only for `server_vad` mode. Activation threshold for VAD (0.0 to 1.0), this defaults + * to 0.5. A higher threshold will require louder audio to activate the model, and thus + * might perform better in noisy environments. + */ + fun threshold(threshold: Double) = threshold(JsonField.of(threshold)) + + /** + * Sets [Builder.threshold] to an arbitrary JSON value. + * + * You should usually call [Builder.threshold] with a well-typed [Double] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun threshold(threshold: JsonField) = apply { this.threshold = threshold } + + /** Type of turn detection. */ + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [RealtimeAudioInputTurnDetection]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): RealtimeAudioInputTurnDetection = + RealtimeAudioInputTurnDetection( + createResponse, + eagerness, + idleTimeoutMs, + interruptResponse, + prefixPaddingMs, + silenceDurationMs, + threshold, + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): RealtimeAudioInputTurnDetection = apply { + if (validated) { + return@apply + } + + createResponse() + eagerness().ifPresent { it.validate() } + idleTimeoutMs() + interruptResponse() + prefixPaddingMs() + silenceDurationMs() + threshold() + type().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (createResponse.asKnown().isPresent) 1 else 0) + + (eagerness.asKnown().getOrNull()?.validity() ?: 0) + + (if (idleTimeoutMs.asKnown().isPresent) 1 else 0) + + (if (interruptResponse.asKnown().isPresent) 1 else 0) + + (if (prefixPaddingMs.asKnown().isPresent) 1 else 0) + + (if (silenceDurationMs.asKnown().isPresent) 1 else 0) + + (if (threshold.asKnown().isPresent) 1 else 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + /** + * Used only for `semantic_vad` mode. The eagerness of the model to respond. `low` will wait + * longer for the user to continue speaking, `high` will respond more quickly. `auto` is the + * default and is equivalent to `medium`. `low`, `medium`, and `high` have max timeouts of 8s, + * 4s, and 2s respectively. + */ + class Eagerness @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val LOW = of("low") + + @JvmField val MEDIUM = of("medium") + + @JvmField val HIGH = of("high") + + @JvmField val AUTO = of("auto") + + @JvmStatic fun of(value: String) = Eagerness(JsonField.of(value)) + } + + /** An enum containing [Eagerness]'s known values. */ + enum class Known { + LOW, + MEDIUM, + HIGH, + AUTO, + } + + /** + * An enum containing [Eagerness]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Eagerness] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + LOW, + MEDIUM, + HIGH, + AUTO, + /** + * An enum member indicating that [Eagerness] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + LOW -> Value.LOW + MEDIUM -> Value.MEDIUM + HIGH -> Value.HIGH + AUTO -> Value.AUTO + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + LOW -> Known.LOW + MEDIUM -> Known.MEDIUM + HIGH -> Known.HIGH + AUTO -> Known.AUTO + else -> throw OpenAIInvalidDataException("Unknown Eagerness: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): Eagerness = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Eagerness && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** Type of turn detection. */ + class Type @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val SERVER_VAD = of("server_vad") + + @JvmField val SEMANTIC_VAD = of("semantic_vad") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + SERVER_VAD, + SEMANTIC_VAD, + } + + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + SERVER_VAD, + SEMANTIC_VAD, + /** An enum member indicating that [Type] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + SERVER_VAD -> Value.SERVER_VAD + SEMANTIC_VAD -> Value.SEMANTIC_VAD + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + SERVER_VAD -> Known.SERVER_VAD + SEMANTIC_VAD -> Known.SEMANTIC_VAD + else -> throw OpenAIInvalidDataException("Unknown Type: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): Type = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Type && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is RealtimeAudioInputTurnDetection && + createResponse == other.createResponse && + eagerness == other.eagerness && + idleTimeoutMs == other.idleTimeoutMs && + interruptResponse == other.interruptResponse && + prefixPaddingMs == other.prefixPaddingMs && + silenceDurationMs == other.silenceDurationMs && + threshold == other.threshold && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + createResponse, + eagerness, + idleTimeoutMs, + interruptResponse, + prefixPaddingMs, + silenceDurationMs, + threshold, + type, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "RealtimeAudioInputTurnDetection{createResponse=$createResponse, eagerness=$eagerness, idleTimeoutMs=$idleTimeoutMs, interruptResponse=$interruptResponse, prefixPaddingMs=$prefixPaddingMs, silenceDurationMs=$silenceDurationMs, threshold=$threshold, type=$type, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeClientEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeClientEvent.kt index 9bb6a3cd..9df31774 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeClientEvent.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeClientEvent.kt @@ -84,13 +84,17 @@ private constructor( /** * Send this event to append audio bytes to the input audio buffer. The audio buffer is - * temporary storage you can write to and later commit. In Server VAD mode, the audio buffer is - * used to detect speech and the server will decide when to commit. When Server VAD is disabled, - * you must commit the audio buffer manually. + * temporary storage you can write to and later commit. A "commit" will create a new user + * message item in the conversation history from the buffer content and clear the buffer. Input + * audio transcription (if enabled) will be generated when the buffer is committed. + * + * If VAD is enabled the audio buffer is used to detect speech and the server will decide when + * to commit. When Server VAD is disabled, you must commit the audio buffer manually. Input + * audio noise reduction operates on writes to the audio buffer. * * The client may choose how much audio to place in each event up to a maximum of 15 MiB, for * example streaming smaller chunks from the client may allow the VAD to be more responsive. - * Unlike made other client events, the server will not send a confirmation response to this + * Unlike most other client events, the server will not send a confirmation response to this * event. */ fun inputAudioBufferAppend(): Optional = @@ -128,7 +132,8 @@ private constructor( /** * Send this event to cancel an in-progress response. The server will respond with a * `response.done` event with a status of `response.status=cancelled`. If there is no response - * to cancel, the server will respond with an error. + * to cancel, the server will respond with an error. It's safe to call `response.cancel` even if + * no response is in progress, an error will be returned the session will remain unaffected. */ fun responseCancel(): Optional = Optional.ofNullable(responseCancel) @@ -137,25 +142,36 @@ private constructor( * When in Server VAD mode, the server will create Responses automatically. * * A Response will include at least one Item, and may have two, in which case the second will be - * a function call. These Items will be appended to the conversation history. + * a function call. These Items will be appended to the conversation history by default. * * The server will respond with a `response.created` event, events for Items and content * created, and finally a `response.done` event to indicate the Response is complete. * - * The `response.create` event includes inference configuration like `instructions`, and - * `temperature`. These fields will override the Session's configuration for this Response only. + * The `response.create` event includes inference configuration like `instructions` and `tools`. + * If these are set, they will override the Session's configuration for this Response only. + * + * Responses can be created out-of-band of the default Conversation, meaning that they can have + * arbitrary input, and it's possible to disable writing the output to the Conversation. Only + * one Response can write to the default Conversation at a time, but otherwise multiple + * Responses can be created in parallel. The `metadata` field is a good way to disambiguate + * multiple simultaneous Responses. + * + * Clients can set `conversation` to `none` to create a Response that does not write to the + * default Conversation. Arbitrary input can be provided with the `input` field, which is an + * array accepting raw Items and references to existing Items. */ fun responseCreate(): Optional = Optional.ofNullable(responseCreate) /** - * Send this event to update the session’s default configuration. The client may send this event - * at any time to update any field, except for `voice`. However, note that once a session has - * been initialized with a particular `model`, it can’t be changed to another model using - * `session.update`. + * Send this event to update the session’s configuration. The client may send this event at any + * time to update any field except for `voice` and `model`. `voice` can be updated only if there + * have been no other audio outputs yet. * * When the server receives a `session.update`, it will respond with a `session.updated` event - * showing the full, effective configuration. Only the fields that are present are updated. To - * clear a field like `instructions`, pass an empty string. + * showing the full, effective configuration. Only the fields that are present in the + * `session.update` are updated. To clear a field like `instructions`, pass an empty string. To + * clear a field like `tools`, pass an empty array. To clear a field like `turn_detection`, pass + * `null`. */ fun sessionUpdate(): Optional = Optional.ofNullable(sessionUpdate) @@ -233,13 +249,17 @@ private constructor( /** * Send this event to append audio bytes to the input audio buffer. The audio buffer is - * temporary storage you can write to and later commit. In Server VAD mode, the audio buffer is - * used to detect speech and the server will decide when to commit. When Server VAD is disabled, - * you must commit the audio buffer manually. + * temporary storage you can write to and later commit. A "commit" will create a new user + * message item in the conversation history from the buffer content and clear the buffer. Input + * audio transcription (if enabled) will be generated when the buffer is committed. + * + * If VAD is enabled the audio buffer is used to detect speech and the server will decide when + * to commit. When Server VAD is disabled, you must commit the audio buffer manually. Input + * audio noise reduction operates on writes to the audio buffer. * * The client may choose how much audio to place in each event up to a maximum of 15 MiB, for * example streaming smaller chunks from the client may allow the VAD to be more responsive. - * Unlike made other client events, the server will not send a confirmation response to this + * Unlike most other client events, the server will not send a confirmation response to this * event. */ fun asInputAudioBufferAppend(): InputAudioBufferAppendEvent = @@ -277,7 +297,8 @@ private constructor( /** * Send this event to cancel an in-progress response. The server will respond with a * `response.done` event with a status of `response.status=cancelled`. If there is no response - * to cancel, the server will respond with an error. + * to cancel, the server will respond with an error. It's safe to call `response.cancel` even if + * no response is in progress, an error will be returned the session will remain unaffected. */ fun asResponseCancel(): ResponseCancelEvent = responseCancel.getOrThrow("responseCancel") @@ -286,25 +307,36 @@ private constructor( * When in Server VAD mode, the server will create Responses automatically. * * A Response will include at least one Item, and may have two, in which case the second will be - * a function call. These Items will be appended to the conversation history. + * a function call. These Items will be appended to the conversation history by default. * * The server will respond with a `response.created` event, events for Items and content * created, and finally a `response.done` event to indicate the Response is complete. * - * The `response.create` event includes inference configuration like `instructions`, and - * `temperature`. These fields will override the Session's configuration for this Response only. + * The `response.create` event includes inference configuration like `instructions` and `tools`. + * If these are set, they will override the Session's configuration for this Response only. + * + * Responses can be created out-of-band of the default Conversation, meaning that they can have + * arbitrary input, and it's possible to disable writing the output to the Conversation. Only + * one Response can write to the default Conversation at a time, but otherwise multiple + * Responses can be created in parallel. The `metadata` field is a good way to disambiguate + * multiple simultaneous Responses. + * + * Clients can set `conversation` to `none` to create a Response that does not write to the + * default Conversation. Arbitrary input can be provided with the `input` field, which is an + * array accepting raw Items and references to existing Items. */ fun asResponseCreate(): ResponseCreateEvent = responseCreate.getOrThrow("responseCreate") /** - * Send this event to update the session’s default configuration. The client may send this event - * at any time to update any field, except for `voice`. However, note that once a session has - * been initialized with a particular `model`, it can’t be changed to another model using - * `session.update`. + * Send this event to update the session’s configuration. The client may send this event at any + * time to update any field except for `voice` and `model`. `voice` can be updated only if there + * have been no other audio outputs yet. * * When the server receives a `session.update`, it will respond with a `session.updated` event - * showing the full, effective configuration. Only the fields that are present are updated. To - * clear a field like `instructions`, pass an empty string. + * showing the full, effective configuration. Only the fields that are present in the + * `session.update` are updated. To clear a field like `instructions`, pass an empty string. To + * clear a field like `tools`, pass an empty array. To clear a field like `turn_detection`, pass + * `null`. */ fun asSessionUpdate(): SessionUpdateEvent = sessionUpdate.getOrThrow("sessionUpdate") @@ -600,13 +632,17 @@ private constructor( /** * Send this event to append audio bytes to the input audio buffer. The audio buffer is - * temporary storage you can write to and later commit. In Server VAD mode, the audio buffer - * is used to detect speech and the server will decide when to commit. When Server VAD is - * disabled, you must commit the audio buffer manually. + * temporary storage you can write to and later commit. A "commit" will create a new user + * message item in the conversation history from the buffer content and clear the buffer. + * Input audio transcription (if enabled) will be generated when the buffer is committed. + * + * If VAD is enabled the audio buffer is used to detect speech and the server will decide + * when to commit. When Server VAD is disabled, you must commit the audio buffer manually. + * Input audio noise reduction operates on writes to the audio buffer. * * The client may choose how much audio to place in each event up to a maximum of 15 MiB, * for example streaming smaller chunks from the client may allow the VAD to be more - * responsive. Unlike made other client events, the server will not send a confirmation + * responsive. Unlike most other client events, the server will not send a confirmation * response to this event. */ @JvmStatic @@ -649,7 +685,9 @@ private constructor( /** * Send this event to cancel an in-progress response. The server will respond with a * `response.done` event with a status of `response.status=cancelled`. If there is no - * response to cancel, the server will respond with an error. + * response to cancel, the server will respond with an error. It's safe to call + * `response.cancel` even if no response is in progress, an error will be returned the + * session will remain unaffected. */ @JvmStatic fun ofResponseCancel(responseCancel: ResponseCancelEvent) = @@ -660,28 +698,40 @@ private constructor( * inference. When in Server VAD mode, the server will create Responses automatically. * * A Response will include at least one Item, and may have two, in which case the second - * will be a function call. These Items will be appended to the conversation history. + * will be a function call. These Items will be appended to the conversation history by + * default. * * The server will respond with a `response.created` event, events for Items and content * created, and finally a `response.done` event to indicate the Response is complete. * - * The `response.create` event includes inference configuration like `instructions`, and - * `temperature`. These fields will override the Session's configuration for this Response - * only. + * The `response.create` event includes inference configuration like `instructions` and + * `tools`. If these are set, they will override the Session's configuration for this + * Response only. + * + * Responses can be created out-of-band of the default Conversation, meaning that they can + * have arbitrary input, and it's possible to disable writing the output to the + * Conversation. Only one Response can write to the default Conversation at a time, but + * otherwise multiple Responses can be created in parallel. The `metadata` field is a good + * way to disambiguate multiple simultaneous Responses. + * + * Clients can set `conversation` to `none` to create a Response that does not write to the + * default Conversation. Arbitrary input can be provided with the `input` field, which is an + * array accepting raw Items and references to existing Items. */ @JvmStatic fun ofResponseCreate(responseCreate: ResponseCreateEvent) = RealtimeClientEvent(responseCreate = responseCreate) /** - * Send this event to update the session’s default configuration. The client may send this - * event at any time to update any field, except for `voice`. However, note that once a - * session has been initialized with a particular `model`, it can’t be changed to another - * model using `session.update`. + * Send this event to update the session’s configuration. The client may send this event at + * any time to update any field except for `voice` and `model`. `voice` can be updated only + * if there have been no other audio outputs yet. * * When the server receives a `session.update`, it will respond with a `session.updated` - * event showing the full, effective configuration. Only the fields that are present are - * updated. To clear a field like `instructions`, pass an empty string. + * event showing the full, effective configuration. Only the fields that are present in the + * `session.update` are updated. To clear a field like `instructions`, pass an empty string. + * To clear a field like `tools`, pass an empty array. To clear a field like + * `turn_detection`, pass `null`. */ @JvmStatic fun ofSessionUpdate(sessionUpdate: SessionUpdateEvent) = @@ -745,13 +795,17 @@ private constructor( /** * Send this event to append audio bytes to the input audio buffer. The audio buffer is - * temporary storage you can write to and later commit. In Server VAD mode, the audio buffer - * is used to detect speech and the server will decide when to commit. When Server VAD is - * disabled, you must commit the audio buffer manually. + * temporary storage you can write to and later commit. A "commit" will create a new user + * message item in the conversation history from the buffer content and clear the buffer. + * Input audio transcription (if enabled) will be generated when the buffer is committed. + * + * If VAD is enabled the audio buffer is used to detect speech and the server will decide + * when to commit. When Server VAD is disabled, you must commit the audio buffer manually. + * Input audio noise reduction operates on writes to the audio buffer. * * The client may choose how much audio to place in each event up to a maximum of 15 MiB, * for example streaming smaller chunks from the client may allow the VAD to be more - * responsive. Unlike made other client events, the server will not send a confirmation + * responsive. Unlike most other client events, the server will not send a confirmation * response to this event. */ fun visitInputAudioBufferAppend(inputAudioBufferAppend: InputAudioBufferAppendEvent): T @@ -786,7 +840,9 @@ private constructor( /** * Send this event to cancel an in-progress response. The server will respond with a * `response.done` event with a status of `response.status=cancelled`. If there is no - * response to cancel, the server will respond with an error. + * response to cancel, the server will respond with an error. It's safe to call + * `response.cancel` even if no response is in progress, an error will be returned the + * session will remain unaffected. */ fun visitResponseCancel(responseCancel: ResponseCancelEvent): T @@ -795,26 +851,38 @@ private constructor( * inference. When in Server VAD mode, the server will create Responses automatically. * * A Response will include at least one Item, and may have two, in which case the second - * will be a function call. These Items will be appended to the conversation history. + * will be a function call. These Items will be appended to the conversation history by + * default. * * The server will respond with a `response.created` event, events for Items and content * created, and finally a `response.done` event to indicate the Response is complete. * - * The `response.create` event includes inference configuration like `instructions`, and - * `temperature`. These fields will override the Session's configuration for this Response - * only. + * The `response.create` event includes inference configuration like `instructions` and + * `tools`. If these are set, they will override the Session's configuration for this + * Response only. + * + * Responses can be created out-of-band of the default Conversation, meaning that they can + * have arbitrary input, and it's possible to disable writing the output to the + * Conversation. Only one Response can write to the default Conversation at a time, but + * otherwise multiple Responses can be created in parallel. The `metadata` field is a good + * way to disambiguate multiple simultaneous Responses. + * + * Clients can set `conversation` to `none` to create a Response that does not write to the + * default Conversation. Arbitrary input can be provided with the `input` field, which is an + * array accepting raw Items and references to existing Items. */ fun visitResponseCreate(responseCreate: ResponseCreateEvent): T /** - * Send this event to update the session’s default configuration. The client may send this - * event at any time to update any field, except for `voice`. However, note that once a - * session has been initialized with a particular `model`, it can’t be changed to another - * model using `session.update`. + * Send this event to update the session’s configuration. The client may send this event at + * any time to update any field except for `voice` and `model`. `voice` can be updated only + * if there have been no other audio outputs yet. * * When the server receives a `session.update`, it will respond with a `session.updated` - * event showing the full, effective configuration. Only the fields that are present are - * updated. To clear a field like `instructions`, pass an empty string. + * event showing the full, effective configuration. Only the fields that are present in the + * `session.update` are updated. To clear a field like `instructions`, pass an empty string. + * To clear a field like `tools`, pass an empty array. To clear a field like + * `turn_detection`, pass `null`. */ fun visitSessionUpdate(sessionUpdate: SessionUpdateEvent): T diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeConversationItemAssistantMessage.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeConversationItemAssistantMessage.kt index f444c6b1..00f25ceb 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeConversationItemAssistantMessage.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeConversationItemAssistantMessage.kt @@ -79,7 +79,7 @@ private constructor( @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type /** - * The unique ID of the item. + * The unique ID of the item. This may be provided by the client or generated by the server. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -87,7 +87,8 @@ private constructor( fun id(): Optional = id.getOptional("id") /** - * Identifier for the API object being returned - always `realtime.item`. + * Identifier for the API object being returned - always `realtime.item`. Optional when creating + * a new item. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -235,7 +236,9 @@ private constructor( */ fun type(type: JsonValue) = apply { this.type = type } - /** The unique ID of the item. */ + /** + * The unique ID of the item. This may be provided by the client or generated by the server. + */ fun id(id: String) = id(JsonField.of(id)) /** @@ -246,7 +249,10 @@ private constructor( */ fun id(id: JsonField) = apply { this.id = id } - /** Identifier for the API object being returned - always `realtime.item`. */ + /** + * Identifier for the API object being returned - always `realtime.item`. Optional when + * creating a new item. + */ fun object_(object_: Object) = object_(JsonField.of(object_)) /** @@ -359,16 +365,31 @@ private constructor( class Content private constructor( + private val audio: JsonField, private val text: JsonField, + private val transcript: JsonField, private val type: JsonField, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( + @JsonProperty("audio") @ExcludeMissing audio: JsonField = JsonMissing.of(), @JsonProperty("text") @ExcludeMissing text: JsonField = JsonMissing.of(), + @JsonProperty("transcript") + @ExcludeMissing + transcript: JsonField = JsonMissing.of(), @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), - ) : this(text, type, mutableMapOf()) + ) : this(audio, text, transcript, type, mutableMapOf()) + + /** + * Base64-encoded audio bytes, these will be parsed as the format specified in the session + * output audio type configuration. This defaults to PCM 16-bit 24kHz mono if not specified. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun audio(): Optional = audio.getOptional("audio") /** * The text content. @@ -379,13 +400,30 @@ private constructor( fun text(): Optional = text.getOptional("text") /** - * The content type. Always `text` for assistant messages. + * The transcript of the audio content, this will always be present if the output type is + * `audio`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun transcript(): Optional = transcript.getOptional("transcript") + + /** + * The content type, `output_text` or `output_audio` depending on the session + * `output_modalities` configuration. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). */ fun type(): Optional = type.getOptional("type") + /** + * Returns the raw JSON value of [audio]. + * + * Unlike [audio], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("audio") @ExcludeMissing fun _audio(): JsonField = audio + /** * Returns the raw JSON value of [text]. * @@ -393,6 +431,15 @@ private constructor( */ @JsonProperty("text") @ExcludeMissing fun _text(): JsonField = text + /** + * Returns the raw JSON value of [transcript]. + * + * Unlike [transcript], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("transcript") + @ExcludeMissing + fun _transcript(): JsonField = transcript + /** * Returns the raw JSON value of [type]. * @@ -421,17 +468,37 @@ private constructor( /** A builder for [Content]. */ class Builder internal constructor() { + private var audio: JsonField = JsonMissing.of() private var text: JsonField = JsonMissing.of() + private var transcript: JsonField = JsonMissing.of() private var type: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(content: Content) = apply { + audio = content.audio text = content.text + transcript = content.transcript type = content.type additionalProperties = content.additionalProperties.toMutableMap() } + /** + * Base64-encoded audio bytes, these will be parsed as the format specified in the + * session output audio type configuration. This defaults to PCM 16-bit 24kHz mono if + * not specified. + */ + fun audio(audio: String) = audio(JsonField.of(audio)) + + /** + * Sets [Builder.audio] to an arbitrary JSON value. + * + * You should usually call [Builder.audio] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun audio(audio: JsonField) = apply { this.audio = audio } + /** The text content. */ fun text(text: String) = text(JsonField.of(text)) @@ -444,7 +511,25 @@ private constructor( */ fun text(text: JsonField) = apply { this.text = text } - /** The content type. Always `text` for assistant messages. */ + /** + * The transcript of the audio content, this will always be present if the output type + * is `audio`. + */ + fun transcript(transcript: String) = transcript(JsonField.of(transcript)) + + /** + * Sets [Builder.transcript] to an arbitrary JSON value. + * + * You should usually call [Builder.transcript] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun transcript(transcript: JsonField) = apply { this.transcript = transcript } + + /** + * The content type, `output_text` or `output_audio` depending on the session + * `output_modalities` configuration. + */ fun type(type: Type) = type(JsonField.of(type)) /** @@ -480,7 +565,8 @@ private constructor( * * Further updates to this [Builder] will not mutate the returned instance. */ - fun build(): Content = Content(text, type, additionalProperties.toMutableMap()) + fun build(): Content = + Content(audio, text, transcript, type, additionalProperties.toMutableMap()) } private var validated: Boolean = false @@ -490,7 +576,9 @@ private constructor( return@apply } + audio() text() + transcript() type().ifPresent { it.validate() } validated = true } @@ -511,9 +599,15 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (if (text.asKnown().isPresent) 1 else 0) + (type.asKnown().getOrNull()?.validity() ?: 0) + (if (audio.asKnown().isPresent) 1 else 0) + + (if (text.asKnown().isPresent) 1 else 0) + + (if (transcript.asKnown().isPresent) 1 else 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) - /** The content type. Always `text` for assistant messages. */ + /** + * The content type, `output_text` or `output_audio` depending on the session + * `output_modalities` configuration. + */ class Type @JsonCreator private constructor(private val value: JsonField) : Enum { /** @@ -528,14 +622,17 @@ private constructor( companion object { - @JvmField val TEXT = of("text") + @JvmField val OUTPUT_TEXT = of("output_text") + + @JvmField val OUTPUT_AUDIO = of("output_audio") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } /** An enum containing [Type]'s known values. */ enum class Known { - TEXT + OUTPUT_TEXT, + OUTPUT_AUDIO, } /** @@ -548,7 +645,8 @@ private constructor( * - It was constructed with an arbitrary value using the [of] method. */ enum class Value { - TEXT, + OUTPUT_TEXT, + OUTPUT_AUDIO, /** An enum member indicating that [Type] was instantiated with an unknown value. */ _UNKNOWN, } @@ -562,7 +660,8 @@ private constructor( */ fun value(): Value = when (this) { - TEXT -> Value.TEXT + OUTPUT_TEXT -> Value.OUTPUT_TEXT + OUTPUT_AUDIO -> Value.OUTPUT_AUDIO else -> Value._UNKNOWN } @@ -577,7 +676,8 @@ private constructor( */ fun known(): Known = when (this) { - TEXT -> Known.TEXT + OUTPUT_TEXT -> Known.OUTPUT_TEXT + OUTPUT_AUDIO -> Known.OUTPUT_AUDIO else -> throw OpenAIInvalidDataException("Unknown Type: $value") } @@ -641,20 +741,27 @@ private constructor( } return other is Content && + audio == other.audio && text == other.text && + transcript == other.transcript && type == other.type && additionalProperties == other.additionalProperties } - private val hashCode: Int by lazy { Objects.hash(text, type, additionalProperties) } + private val hashCode: Int by lazy { + Objects.hash(audio, text, transcript, type, additionalProperties) + } override fun hashCode(): Int = hashCode override fun toString() = - "Content{text=$text, type=$type, additionalProperties=$additionalProperties}" + "Content{audio=$audio, text=$text, transcript=$transcript, type=$type, additionalProperties=$additionalProperties}" } - /** Identifier for the API object being returned - always `realtime.item`. */ + /** + * Identifier for the API object being returned - always `realtime.item`. Optional when creating + * a new item. + */ class Object @JsonCreator private constructor(private val value: JsonField) : Enum { /** diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeConversationItemFunctionCall.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeConversationItemFunctionCall.kt index 8378fdd7..c33b3bfe 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeConversationItemFunctionCall.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeConversationItemFunctionCall.kt @@ -43,7 +43,8 @@ private constructor( ) : this(arguments, name, type, id, callId, object_, status, mutableMapOf()) /** - * The arguments of the function call. + * The arguments of the function call. This is a JSON-encoded string representing the arguments + * passed to the function, for example `{"arg1": "value1", "arg2": 42}`. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected value). @@ -72,7 +73,7 @@ private constructor( @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type /** - * The unique ID of the item. + * The unique ID of the item. This may be provided by the client or generated by the server. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -88,7 +89,8 @@ private constructor( fun callId(): Optional = callId.getOptional("call_id") /** - * Identifier for the API object being returned - always `realtime.item`. + * Identifier for the API object being returned - always `realtime.item`. Optional when creating + * a new item. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -199,7 +201,10 @@ private constructor( realtimeConversationItemFunctionCall.additionalProperties.toMutableMap() } - /** The arguments of the function call. */ + /** + * The arguments of the function call. This is a JSON-encoded string representing the + * arguments passed to the function, for example `{"arg1": "value1", "arg2": 42}`. + */ fun arguments(arguments: String) = arguments(JsonField.of(arguments)) /** @@ -236,7 +241,9 @@ private constructor( */ fun type(type: JsonValue) = apply { this.type = type } - /** The unique ID of the item. */ + /** + * The unique ID of the item. This may be provided by the client or generated by the server. + */ fun id(id: String) = id(JsonField.of(id)) /** @@ -258,7 +265,10 @@ private constructor( */ fun callId(callId: JsonField) = apply { this.callId = callId } - /** Identifier for the API object being returned - always `realtime.item`. */ + /** + * Identifier for the API object being returned - always `realtime.item`. Optional when + * creating a new item. + */ fun object_(object_: Object) = object_(JsonField.of(object_)) /** @@ -369,7 +379,10 @@ private constructor( (object_.asKnown().getOrNull()?.validity() ?: 0) + (status.asKnown().getOrNull()?.validity() ?: 0) - /** Identifier for the API object being returned - always `realtime.item`. */ + /** + * Identifier for the API object being returned - always `realtime.item`. Optional when creating + * a new item. + */ class Object @JsonCreator private constructor(private val value: JsonField) : Enum { /** diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeConversationItemFunctionCallOutput.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeConversationItemFunctionCallOutput.kt index 825b4efd..83f0dda2 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeConversationItemFunctionCallOutput.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeConversationItemFunctionCallOutput.kt @@ -49,7 +49,8 @@ private constructor( fun callId(): String = callId.getRequired("call_id") /** - * The output of the function call. + * The output of the function call, this is free text and can contain any information or simply + * be empty. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected value). @@ -70,7 +71,7 @@ private constructor( @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type /** - * The unique ID of the item. + * The unique ID of the item. This may be provided by the client or generated by the server. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -78,7 +79,8 @@ private constructor( fun id(): Optional = id.getOptional("id") /** - * Identifier for the API object being returned - always `realtime.item`. + * Identifier for the API object being returned - always `realtime.item`. Optional when creating + * a new item. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -191,7 +193,10 @@ private constructor( */ fun callId(callId: JsonField) = apply { this.callId = callId } - /** The output of the function call. */ + /** + * The output of the function call, this is free text and can contain any information or + * simply be empty. + */ fun output(output: String) = output(JsonField.of(output)) /** @@ -216,7 +221,9 @@ private constructor( */ fun type(type: JsonValue) = apply { this.type = type } - /** The unique ID of the item. */ + /** + * The unique ID of the item. This may be provided by the client or generated by the server. + */ fun id(id: String) = id(JsonField.of(id)) /** @@ -227,7 +234,10 @@ private constructor( */ fun id(id: JsonField) = apply { this.id = id } - /** Identifier for the API object being returned - always `realtime.item`. */ + /** + * Identifier for the API object being returned - always `realtime.item`. Optional when + * creating a new item. + */ fun object_(object_: Object) = object_(JsonField.of(object_)) /** @@ -335,7 +345,10 @@ private constructor( (object_.asKnown().getOrNull()?.validity() ?: 0) + (status.asKnown().getOrNull()?.validity() ?: 0) - /** Identifier for the API object being returned - always `realtime.item`. */ + /** + * Identifier for the API object being returned - always `realtime.item`. Optional when creating + * a new item. + */ class Object @JsonCreator private constructor(private val value: JsonField) : Enum { /** diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeConversationItemSystemMessage.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeConversationItemSystemMessage.kt index e5a1ba15..4c683774 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeConversationItemSystemMessage.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeConversationItemSystemMessage.kt @@ -20,7 +20,13 @@ import java.util.Objects import java.util.Optional import kotlin.jvm.optionals.getOrNull -/** A system message item in a Realtime conversation. */ +/** + * A system message in a Realtime conversation can be used to provide additional context or + * instructions to the model. This is similar but distinct from the instruction prompt provided at + * the start of a conversation, as system messages can be added at any point in the conversation. + * For major changes to the conversation's behavior, use instructions, but for smaller updates (e.g. + * "the user is now asking about a different topic"), use system messages. + */ class RealtimeConversationItemSystemMessage private constructor( private val content: JsonField>, @@ -79,7 +85,7 @@ private constructor( @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type /** - * The unique ID of the item. + * The unique ID of the item. This may be provided by the client or generated by the server. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -87,7 +93,8 @@ private constructor( fun id(): Optional = id.getOptional("id") /** - * Identifier for the API object being returned - always `realtime.item`. + * Identifier for the API object being returned - always `realtime.item`. Optional when creating + * a new item. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -235,7 +242,9 @@ private constructor( */ fun type(type: JsonValue) = apply { this.type = type } - /** The unique ID of the item. */ + /** + * The unique ID of the item. This may be provided by the client or generated by the server. + */ fun id(id: String) = id(JsonField.of(id)) /** @@ -246,7 +255,10 @@ private constructor( */ fun id(id: JsonField) = apply { this.id = id } - /** Identifier for the API object being returned - always `realtime.item`. */ + /** + * Identifier for the API object being returned - always `realtime.item`. Optional when + * creating a new item. + */ fun object_(object_: Object) = object_(JsonField.of(object_)) /** @@ -654,7 +666,10 @@ private constructor( "Content{text=$text, type=$type, additionalProperties=$additionalProperties}" } - /** Identifier for the API object being returned - always `realtime.item`. */ + /** + * Identifier for the API object being returned - always `realtime.item`. Optional when creating + * a new item. + */ class Object @JsonCreator private constructor(private val value: JsonField) : Enum { /** diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeConversationItemUserMessage.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeConversationItemUserMessage.kt index be5d09d5..838235b7 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeConversationItemUserMessage.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeConversationItemUserMessage.kt @@ -79,7 +79,7 @@ private constructor( @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type /** - * The unique ID of the item. + * The unique ID of the item. This may be provided by the client or generated by the server. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -87,7 +87,8 @@ private constructor( fun id(): Optional = id.getOptional("id") /** - * Identifier for the API object being returned - always `realtime.item`. + * Identifier for the API object being returned - always `realtime.item`. Optional when creating + * a new item. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -235,7 +236,9 @@ private constructor( */ fun type(type: JsonValue) = apply { this.type = type } - /** The unique ID of the item. */ + /** + * The unique ID of the item. This may be provided by the client or generated by the server. + */ fun id(id: String) = id(JsonField.of(id)) /** @@ -246,7 +249,10 @@ private constructor( */ fun id(id: JsonField) = apply { this.id = id } - /** Identifier for the API object being returned - always `realtime.item`. */ + /** + * Identifier for the API object being returned - always `realtime.item`. Optional when + * creating a new item. + */ fun object_(object_: Object) = object_(JsonField.of(object_)) /** @@ -360,6 +366,8 @@ private constructor( class Content private constructor( private val audio: JsonField, + private val detail: JsonField, + private val imageUrl: JsonField, private val text: JsonField, private val transcript: JsonField, private val type: JsonField, @@ -369,21 +377,44 @@ private constructor( @JsonCreator private constructor( @JsonProperty("audio") @ExcludeMissing audio: JsonField = JsonMissing.of(), + @JsonProperty("detail") @ExcludeMissing detail: JsonField = JsonMissing.of(), + @JsonProperty("image_url") + @ExcludeMissing + imageUrl: JsonField = JsonMissing.of(), @JsonProperty("text") @ExcludeMissing text: JsonField = JsonMissing.of(), @JsonProperty("transcript") @ExcludeMissing transcript: JsonField = JsonMissing.of(), @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), - ) : this(audio, text, transcript, type, mutableMapOf()) + ) : this(audio, detail, imageUrl, text, transcript, type, mutableMapOf()) /** - * Base64-encoded audio bytes (for `input_audio`). + * Base64-encoded audio bytes (for `input_audio`), these will be parsed as the format + * specified in the session input audio type configuration. This defaults to PCM 16-bit + * 24kHz mono if not specified. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). */ fun audio(): Optional = audio.getOptional("audio") + /** + * The detail level of the image (for `input_image`). `auto` will default to `high`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun detail(): Optional = detail.getOptional("detail") + + /** + * Base64-encoded image bytes (for `input_image`) as a data URI. For example + * `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...`. Supported formats are PNG and JPEG. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun imageUrl(): Optional = imageUrl.getOptional("image_url") + /** * The text content (for `input_text`). * @@ -393,7 +424,8 @@ private constructor( fun text(): Optional = text.getOptional("text") /** - * Transcript of the audio (for `input_audio`). + * Transcript of the audio (for `input_audio`). This is not sent to the model, but will be + * attached to the message item for reference. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -401,7 +433,7 @@ private constructor( fun transcript(): Optional = transcript.getOptional("transcript") /** - * The content type (`input_text` or `input_audio`). + * The content type (`input_text`, `input_audio`, or `input_image`). * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -415,6 +447,20 @@ private constructor( */ @JsonProperty("audio") @ExcludeMissing fun _audio(): JsonField = audio + /** + * Returns the raw JSON value of [detail]. + * + * Unlike [detail], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("detail") @ExcludeMissing fun _detail(): JsonField = detail + + /** + * Returns the raw JSON value of [imageUrl]. + * + * Unlike [imageUrl], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("image_url") @ExcludeMissing fun _imageUrl(): JsonField = imageUrl + /** * Returns the raw JSON value of [text]. * @@ -460,6 +506,8 @@ private constructor( class Builder internal constructor() { private var audio: JsonField = JsonMissing.of() + private var detail: JsonField = JsonMissing.of() + private var imageUrl: JsonField = JsonMissing.of() private var text: JsonField = JsonMissing.of() private var transcript: JsonField = JsonMissing.of() private var type: JsonField = JsonMissing.of() @@ -468,13 +516,19 @@ private constructor( @JvmSynthetic internal fun from(content: Content) = apply { audio = content.audio + detail = content.detail + imageUrl = content.imageUrl text = content.text transcript = content.transcript type = content.type additionalProperties = content.additionalProperties.toMutableMap() } - /** Base64-encoded audio bytes (for `input_audio`). */ + /** + * Base64-encoded audio bytes (for `input_audio`), these will be parsed as the format + * specified in the session input audio type configuration. This defaults to PCM 16-bit + * 24kHz mono if not specified. + */ fun audio(audio: String) = audio(JsonField.of(audio)) /** @@ -486,6 +540,34 @@ private constructor( */ fun audio(audio: JsonField) = apply { this.audio = audio } + /** The detail level of the image (for `input_image`). `auto` will default to `high`. */ + fun detail(detail: Detail) = detail(JsonField.of(detail)) + + /** + * Sets [Builder.detail] to an arbitrary JSON value. + * + * You should usually call [Builder.detail] with a well-typed [Detail] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun detail(detail: JsonField) = apply { this.detail = detail } + + /** + * Base64-encoded image bytes (for `input_image`) as a data URI. For example + * `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...`. Supported formats are PNG and + * JPEG. + */ + fun imageUrl(imageUrl: String) = imageUrl(JsonField.of(imageUrl)) + + /** + * Sets [Builder.imageUrl] to an arbitrary JSON value. + * + * You should usually call [Builder.imageUrl] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun imageUrl(imageUrl: JsonField) = apply { this.imageUrl = imageUrl } + /** The text content (for `input_text`). */ fun text(text: String) = text(JsonField.of(text)) @@ -498,7 +580,10 @@ private constructor( */ fun text(text: JsonField) = apply { this.text = text } - /** Transcript of the audio (for `input_audio`). */ + /** + * Transcript of the audio (for `input_audio`). This is not sent to the model, but will + * be attached to the message item for reference. + */ fun transcript(transcript: String) = transcript(JsonField.of(transcript)) /** @@ -510,7 +595,7 @@ private constructor( */ fun transcript(transcript: JsonField) = apply { this.transcript = transcript } - /** The content type (`input_text` or `input_audio`). */ + /** The content type (`input_text`, `input_audio`, or `input_image`). */ fun type(type: Type) = type(JsonField.of(type)) /** @@ -547,7 +632,15 @@ private constructor( * Further updates to this [Builder] will not mutate the returned instance. */ fun build(): Content = - Content(audio, text, transcript, type, additionalProperties.toMutableMap()) + Content( + audio, + detail, + imageUrl, + text, + transcript, + type, + additionalProperties.toMutableMap(), + ) } private var validated: Boolean = false @@ -558,6 +651,8 @@ private constructor( } audio() + detail().ifPresent { it.validate() } + imageUrl() text() transcript() type().ifPresent { it.validate() } @@ -581,11 +676,149 @@ private constructor( @JvmSynthetic internal fun validity(): Int = (if (audio.asKnown().isPresent) 1 else 0) + + (detail.asKnown().getOrNull()?.validity() ?: 0) + + (if (imageUrl.asKnown().isPresent) 1 else 0) + (if (text.asKnown().isPresent) 1 else 0) + (if (transcript.asKnown().isPresent) 1 else 0) + (type.asKnown().getOrNull()?.validity() ?: 0) - /** The content type (`input_text` or `input_audio`). */ + /** The detail level of the image (for `input_image`). `auto` will default to `high`. */ + class Detail @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val AUTO = of("auto") + + @JvmField val LOW = of("low") + + @JvmField val HIGH = of("high") + + @JvmStatic fun of(value: String) = Detail(JsonField.of(value)) + } + + /** An enum containing [Detail]'s known values. */ + enum class Known { + AUTO, + LOW, + HIGH, + } + + /** + * An enum containing [Detail]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Detail] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + AUTO, + LOW, + HIGH, + /** + * An enum member indicating that [Detail] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you + * want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + AUTO -> Value.AUTO + LOW -> Value.LOW + HIGH -> Value.HIGH + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + AUTO -> Known.AUTO + LOW -> Known.LOW + HIGH -> Known.HIGH + else -> throw OpenAIInvalidDataException("Unknown Detail: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + OpenAIInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Detail = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Detail && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** The content type (`input_text`, `input_audio`, or `input_image`). */ class Type @JsonCreator private constructor(private val value: JsonField) : Enum { /** @@ -604,6 +837,8 @@ private constructor( @JvmField val INPUT_AUDIO = of("input_audio") + @JvmField val INPUT_IMAGE = of("input_image") + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } @@ -611,6 +846,7 @@ private constructor( enum class Known { INPUT_TEXT, INPUT_AUDIO, + INPUT_IMAGE, } /** @@ -625,6 +861,7 @@ private constructor( enum class Value { INPUT_TEXT, INPUT_AUDIO, + INPUT_IMAGE, /** An enum member indicating that [Type] was instantiated with an unknown value. */ _UNKNOWN, } @@ -640,6 +877,7 @@ private constructor( when (this) { INPUT_TEXT -> Value.INPUT_TEXT INPUT_AUDIO -> Value.INPUT_AUDIO + INPUT_IMAGE -> Value.INPUT_IMAGE else -> Value._UNKNOWN } @@ -656,6 +894,7 @@ private constructor( when (this) { INPUT_TEXT -> Known.INPUT_TEXT INPUT_AUDIO -> Known.INPUT_AUDIO + INPUT_IMAGE -> Known.INPUT_IMAGE else -> throw OpenAIInvalidDataException("Unknown Type: $value") } @@ -720,6 +959,8 @@ private constructor( return other is Content && audio == other.audio && + detail == other.detail && + imageUrl == other.imageUrl && text == other.text && transcript == other.transcript && type == other.type && @@ -727,16 +968,19 @@ private constructor( } private val hashCode: Int by lazy { - Objects.hash(audio, text, transcript, type, additionalProperties) + Objects.hash(audio, detail, imageUrl, text, transcript, type, additionalProperties) } override fun hashCode(): Int = hashCode override fun toString() = - "Content{audio=$audio, text=$text, transcript=$transcript, type=$type, additionalProperties=$additionalProperties}" + "Content{audio=$audio, detail=$detail, imageUrl=$imageUrl, text=$text, transcript=$transcript, type=$type, additionalProperties=$additionalProperties}" } - /** Identifier for the API object being returned - always `realtime.item`. */ + /** + * Identifier for the API object being returned - always `realtime.item`. Optional when creating + * a new item. + */ class Object @JsonCreator private constructor(private val value: JsonField) : Enum { /** diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeResponse.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeResponse.kt index 66b0a182..f3c6ad0d 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeResponse.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeResponse.kt @@ -34,24 +34,23 @@ import kotlin.jvm.optionals.getOrNull class RealtimeResponse private constructor( private val id: JsonField, + private val audio: JsonField