From 10cd1c49b63b63aa7d3a357ab5b0e982628cd933 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 10 Sep 2025 13:35:57 +0000 Subject: [PATCH 1/2] chore(api): fix realtime GA types --- .stats.yml | 6 +- .../RealtimeAudioInputTurnDetection.kt | 4 +- .../models/realtime/RealtimeClientEvent.kt | 46 +- .../{Models.kt => RealtimeFunctionTool.kt} | 36 +- .../realtime/RealtimeResponseCreateParams.kt | 42 +- .../models/realtime/RealtimeServerEvent.kt | 104 -- .../openai/models/realtime/RealtimeSession.kt | 28 +- .../realtime/RealtimeSessionCreateRequest.kt | 3 +- .../realtime/RealtimeToolsConfigUnion.kt | 18 +- .../realtime/TranscriptionSessionCreated.kt | 270 ----- .../TranscriptionSessionUpdatedEvent.kt | 1076 ++++++++++++++++- .../ClientSecretCreateResponse.kt | 211 ++-- .../RealtimeSessionCreateResponse.kt | 328 ++--- ...ealtimeTranscriptionSessionClientSecret.kt | 223 ---- ...ltimeTranscriptionSessionCreateResponse.kt | 1003 +++++++++++---- ...scriptionSessionInputAudioTranscription.kt | 402 ------ .../com/openai/models/realtime/ModelsTest.kt | 45 - .../realtime/RealtimeClientEventTest.kt | 137 +-- .../realtime/RealtimeFunctionToolTest.kt | 49 + .../RealtimeResponseCreateParamsTest.kt | 14 +- .../realtime/RealtimeServerEventTest.kt | 388 +----- .../RealtimeSessionCreateRequestTest.kt | 12 +- .../models/realtime/RealtimeSessionTest.kt | 12 +- .../realtime/RealtimeToolsConfigUnionTest.kt | 8 +- .../realtime/ResponseCreateEventTest.kt | 12 +- .../realtime/SessionCreatedEventTest.kt | 12 +- .../models/realtime/SessionUpdateEventTest.kt | 12 +- .../realtime/SessionUpdatedEventTest.kt | 12 +- .../TranscriptionSessionCreatedTest.kt | 132 -- .../TranscriptionSessionUpdatedEventTest.kt | 48 +- .../ClientSecretCreateParamsTest.kt | 14 +- .../ClientSecretCreateResponseTest.kt | 55 +- .../RealtimeSessionCreateResponseTest.kt | 36 +- ...imeTranscriptionSessionClientSecretTest.kt | 36 - ...eTranscriptionSessionCreateResponseTest.kt | 188 ++- ...ptionSessionInputAudioTranscriptionTest.kt | 47 - .../realtime/ClientSecretServiceAsyncTest.kt | 6 +- .../realtime/ClientSecretServiceTest.kt | 6 +- 38 files changed, 2420 insertions(+), 2661 deletions(-) rename openai-java-core/src/main/kotlin/com/openai/models/realtime/{Models.kt => RealtimeFunctionTool.kt} (92%) delete mode 100644 openai-java-core/src/main/kotlin/com/openai/models/realtime/TranscriptionSessionCreated.kt delete mode 100644 openai-java-core/src/main/kotlin/com/openai/models/realtime/clientsecrets/RealtimeTranscriptionSessionClientSecret.kt delete mode 100644 openai-java-core/src/main/kotlin/com/openai/models/realtime/clientsecrets/RealtimeTranscriptionSessionInputAudioTranscription.kt delete 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/RealtimeFunctionToolTest.kt delete mode 100644 openai-java-core/src/test/kotlin/com/openai/models/realtime/TranscriptionSessionCreatedTest.kt delete mode 100644 openai-java-core/src/test/kotlin/com/openai/models/realtime/clientsecrets/RealtimeTranscriptionSessionClientSecretTest.kt delete mode 100644 openai-java-core/src/test/kotlin/com/openai/models/realtime/clientsecrets/RealtimeTranscriptionSessionInputAudioTranscriptionTest.kt diff --git a/.stats.yml b/.stats.yml index 36a3c7f5..2aa16be8 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-7807ec6037efcee1af7decbfd3974a42b761fb6c6a71b4050fe43484d7fcbac4.yml -openapi_spec_hash: da6851e3891ad2659a50ed6a736fd32a -config_hash: 74d955cdc2377213f5268ea309090f6c +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-16cb18bed32bae8c5840fb39a1bf664026cc40463ad0c487dcb0df1bd3d72db0.yml +openapi_spec_hash: 4cb51b22f98dee1a90bc7add82d1d132 +config_hash: 930dac3aa861344867e4ac84f037b5df 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 index f86a67a4..63985f43 100644 --- 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 @@ -95,7 +95,7 @@ private constructor( /** * Optional idle timeout after which turn detection will auto-timeout when no additional audio - * is received. + * is received and emits a `timeout_triggered` event. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -298,7 +298,7 @@ private constructor( /** * Optional idle timeout after which turn detection will auto-timeout when no additional - * audio is received. + * audio is received and emits a `timeout_triggered` event. */ fun idleTimeoutMs(idleTimeoutMs: Long?) = idleTimeoutMs(JsonField.ofNullable(idleTimeoutMs)) 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 9df31774..5a0300e3 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 @@ -34,7 +34,6 @@ private constructor( private val responseCancel: ResponseCancelEvent? = null, private val responseCreate: ResponseCreateEvent? = null, private val sessionUpdate: SessionUpdateEvent? = null, - private val transcriptionSessionUpdate: TranscriptionSessionUpdate? = null, private val _json: JsonValue? = null, ) { @@ -175,10 +174,6 @@ private constructor( */ fun sessionUpdate(): Optional = Optional.ofNullable(sessionUpdate) - /** Send this event to update a transcription session. */ - fun transcriptionSessionUpdate(): Optional = - Optional.ofNullable(transcriptionSessionUpdate) - fun isConversationItemCreate(): Boolean = conversationItemCreate != null fun isConversationItemDelete(): Boolean = conversationItemDelete != null @@ -201,8 +196,6 @@ private constructor( fun isSessionUpdate(): Boolean = sessionUpdate != null - fun isTranscriptionSessionUpdate(): Boolean = transcriptionSessionUpdate != null - /** * Add a new Item to the Conversation's context, including messages, function calls, and * function call responses. This event can be used both to populate a "history" of the @@ -340,10 +333,6 @@ private constructor( */ fun asSessionUpdate(): SessionUpdateEvent = sessionUpdate.getOrThrow("sessionUpdate") - /** Send this event to update a transcription session. */ - fun asTranscriptionSessionUpdate(): TranscriptionSessionUpdate = - transcriptionSessionUpdate.getOrThrow("transcriptionSessionUpdate") - fun _json(): Optional = Optional.ofNullable(_json) fun accept(visitor: Visitor): T = @@ -367,8 +356,6 @@ private constructor( responseCancel != null -> visitor.visitResponseCancel(responseCancel) responseCreate != null -> visitor.visitResponseCreate(responseCreate) sessionUpdate != null -> visitor.visitSessionUpdate(sessionUpdate) - transcriptionSessionUpdate != null -> - visitor.visitTranscriptionSessionUpdate(transcriptionSessionUpdate) else -> visitor.unknown(_json) } @@ -440,12 +427,6 @@ private constructor( override fun visitSessionUpdate(sessionUpdate: SessionUpdateEvent) { sessionUpdate.validate() } - - override fun visitTranscriptionSessionUpdate( - transcriptionSessionUpdate: TranscriptionSessionUpdate - ) { - transcriptionSessionUpdate.validate() - } } ) validated = true @@ -509,10 +490,6 @@ private constructor( override fun visitSessionUpdate(sessionUpdate: SessionUpdateEvent) = sessionUpdate.validity() - override fun visitTranscriptionSessionUpdate( - transcriptionSessionUpdate: TranscriptionSessionUpdate - ) = transcriptionSessionUpdate.validity() - override fun unknown(json: JsonValue?) = 0 } ) @@ -533,8 +510,7 @@ private constructor( inputAudioBufferCommit == other.inputAudioBufferCommit && responseCancel == other.responseCancel && responseCreate == other.responseCreate && - sessionUpdate == other.sessionUpdate && - transcriptionSessionUpdate == other.transcriptionSessionUpdate + sessionUpdate == other.sessionUpdate } override fun hashCode(): Int = @@ -550,7 +526,6 @@ private constructor( responseCancel, responseCreate, sessionUpdate, - transcriptionSessionUpdate, ) override fun toString(): String = @@ -574,8 +549,6 @@ private constructor( responseCancel != null -> "RealtimeClientEvent{responseCancel=$responseCancel}" responseCreate != null -> "RealtimeClientEvent{responseCreate=$responseCreate}" sessionUpdate != null -> "RealtimeClientEvent{sessionUpdate=$sessionUpdate}" - transcriptionSessionUpdate != null -> - "RealtimeClientEvent{transcriptionSessionUpdate=$transcriptionSessionUpdate}" _json != null -> "RealtimeClientEvent{_unknown=$_json}" else -> throw IllegalStateException("Invalid RealtimeClientEvent") } @@ -736,11 +709,6 @@ private constructor( @JvmStatic fun ofSessionUpdate(sessionUpdate: SessionUpdateEvent) = RealtimeClientEvent(sessionUpdate = sessionUpdate) - - /** Send this event to update a transcription session. */ - @JvmStatic - fun ofTranscriptionSessionUpdate(transcriptionSessionUpdate: TranscriptionSessionUpdate) = - RealtimeClientEvent(transcriptionSessionUpdate = transcriptionSessionUpdate) } /** @@ -886,11 +854,6 @@ private constructor( */ fun visitSessionUpdate(sessionUpdate: SessionUpdateEvent): T - /** Send this event to update a transcription session. */ - fun visitTranscriptionSessionUpdate( - transcriptionSessionUpdate: TranscriptionSessionUpdate - ): T - /** * Maps an unknown variant of [RealtimeClientEvent] to a value of type [T]. * @@ -969,11 +932,6 @@ private constructor( RealtimeClientEvent(sessionUpdate = it, _json = json) } ?: RealtimeClientEvent(_json = json) } - "transcription_session.update" -> { - return tryDeserialize(node, jacksonTypeRef())?.let { - RealtimeClientEvent(transcriptionSessionUpdate = it, _json = json) - } ?: RealtimeClientEvent(_json = json) - } } return RealtimeClientEvent(_json = json) @@ -1007,8 +965,6 @@ private constructor( value.responseCancel != null -> generator.writeObject(value.responseCancel) value.responseCreate != null -> generator.writeObject(value.responseCreate) value.sessionUpdate != null -> generator.writeObject(value.sessionUpdate) - value.transcriptionSessionUpdate != null -> - generator.writeObject(value.transcriptionSessionUpdate) value._json != null -> generator.writeObject(value._json) else -> throw IllegalStateException("Invalid RealtimeClientEvent") } 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/RealtimeFunctionTool.kt similarity index 92% rename from openai-java-core/src/main/kotlin/com/openai/models/realtime/Models.kt rename to openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeFunctionTool.kt index fe1f7695..f6320255 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/Models.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeFunctionTool.kt @@ -17,7 +17,7 @@ import java.util.Objects import java.util.Optional import kotlin.jvm.optionals.getOrNull -class Models +class RealtimeFunctionTool private constructor( private val description: JsonField, private val name: JsonField, @@ -99,11 +99,11 @@ private constructor( companion object { - /** Returns a mutable builder for constructing an instance of [Models]. */ + /** Returns a mutable builder for constructing an instance of [RealtimeFunctionTool]. */ @JvmStatic fun builder() = Builder() } - /** A builder for [Models]. */ + /** A builder for [RealtimeFunctionTool]. */ class Builder internal constructor() { private var description: JsonField = JsonMissing.of() @@ -113,12 +113,12 @@ private constructor( 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() + internal fun from(realtimeFunctionTool: RealtimeFunctionTool) = apply { + description = realtimeFunctionTool.description + name = realtimeFunctionTool.name + parameters = realtimeFunctionTool.parameters + type = realtimeFunctionTool.type + additionalProperties = realtimeFunctionTool.additionalProperties.toMutableMap() } /** @@ -181,17 +181,23 @@ private constructor( } /** - * Returns an immutable instance of [Models]. + * Returns an immutable instance of [RealtimeFunctionTool]. * * Further updates to this [Builder] will not mutate the returned instance. */ - fun build(): Models = - Models(description, name, parameters, type, additionalProperties.toMutableMap()) + fun build(): RealtimeFunctionTool = + RealtimeFunctionTool( + description, + name, + parameters, + type, + additionalProperties.toMutableMap(), + ) } private var validated: Boolean = false - fun validate(): Models = apply { + fun validate(): RealtimeFunctionTool = apply { if (validated) { return@apply } @@ -346,7 +352,7 @@ private constructor( return true } - return other is Models && + return other is RealtimeFunctionTool && description == other.description && name == other.name && parameters == other.parameters && @@ -361,5 +367,5 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "Models{description=$description, name=$name, parameters=$parameters, type=$type, additionalProperties=$additionalProperties}" + "RealtimeFunctionTool{description=$description, name=$name, parameters=$parameters, type=$type, additionalProperties=$additionalProperties}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeResponseCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeResponseCreateParams.kt index 3af381ad..7ab70379 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeResponseCreateParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeResponseCreateParams.kt @@ -677,8 +677,9 @@ private constructor( (tools ?: JsonField.of(mutableListOf())).also { checkKnown("tools", it).add(tool) } } - /** Alias for calling [addTool] with `Tool.ofModels(models)`. */ - fun addTool(models: Models) = addTool(Tool.ofModels(models)) + /** Alias for calling [addTool] with `Tool.ofRealtimeFunction(realtimeFunction)`. */ + fun addTool(realtimeFunction: RealtimeFunctionTool) = + addTool(Tool.ofRealtimeFunction(realtimeFunction)) /** * Alias for calling [addTool] with @@ -1589,12 +1590,13 @@ private constructor( @JsonSerialize(using = Tool.Serializer::class) class Tool private constructor( - private val models: Models? = null, + private val realtimeFunction: RealtimeFunctionTool? = null, private val realtimeResponseCreateMcp: RealtimeResponseCreateMcpTool? = null, private val _json: JsonValue? = null, ) { - fun models(): Optional = Optional.ofNullable(models) + fun realtimeFunction(): Optional = + Optional.ofNullable(realtimeFunction) /** * Give the model access to additional tools via remote Model Context Protocol (MCP) @@ -1604,11 +1606,12 @@ private constructor( fun realtimeResponseCreateMcp(): Optional = Optional.ofNullable(realtimeResponseCreateMcp) - fun isModels(): Boolean = models != null + fun isRealtimeFunction(): Boolean = realtimeFunction != null fun isRealtimeResponseCreateMcp(): Boolean = realtimeResponseCreateMcp != null - fun asModels(): Models = models.getOrThrow("models") + fun asRealtimeFunction(): RealtimeFunctionTool = + realtimeFunction.getOrThrow("realtimeFunction") /** * Give the model access to additional tools via remote Model Context Protocol (MCP) @@ -1622,7 +1625,7 @@ private constructor( fun accept(visitor: Visitor): T = when { - models != null -> visitor.visitModels(models) + realtimeFunction != null -> visitor.visitRealtimeFunction(realtimeFunction) realtimeResponseCreateMcp != null -> visitor.visitRealtimeResponseCreateMcp(realtimeResponseCreateMcp) else -> visitor.unknown(_json) @@ -1637,8 +1640,8 @@ private constructor( accept( object : Visitor { - override fun visitModels(models: Models) { - models.validate() + override fun visitRealtimeFunction(realtimeFunction: RealtimeFunctionTool) { + realtimeFunction.validate() } override fun visitRealtimeResponseCreateMcp( @@ -1669,7 +1672,8 @@ private constructor( internal fun validity(): Int = accept( object : Visitor { - override fun visitModels(models: Models) = models.validity() + override fun visitRealtimeFunction(realtimeFunction: RealtimeFunctionTool) = + realtimeFunction.validity() override fun visitRealtimeResponseCreateMcp( realtimeResponseCreateMcp: RealtimeResponseCreateMcpTool @@ -1685,15 +1689,15 @@ private constructor( } return other is Tool && - models == other.models && + realtimeFunction == other.realtimeFunction && realtimeResponseCreateMcp == other.realtimeResponseCreateMcp } - override fun hashCode(): Int = Objects.hash(models, realtimeResponseCreateMcp) + override fun hashCode(): Int = Objects.hash(realtimeFunction, realtimeResponseCreateMcp) override fun toString(): String = when { - models != null -> "Tool{models=$models}" + realtimeFunction != null -> "Tool{realtimeFunction=$realtimeFunction}" realtimeResponseCreateMcp != null -> "Tool{realtimeResponseCreateMcp=$realtimeResponseCreateMcp}" _json != null -> "Tool{_unknown=$_json}" @@ -1702,7 +1706,9 @@ private constructor( companion object { - @JvmStatic fun ofModels(models: Models) = Tool(models = models) + @JvmStatic + fun ofRealtimeFunction(realtimeFunction: RealtimeFunctionTool) = + Tool(realtimeFunction = realtimeFunction) /** * Give the model access to additional tools via remote Model Context Protocol (MCP) @@ -1718,7 +1724,7 @@ private constructor( /** An interface that defines how to map each variant of [Tool] to a value of type [T]. */ interface Visitor { - fun visitModels(models: Models): T + fun visitRealtimeFunction(realtimeFunction: RealtimeFunctionTool): T /** * Give the model access to additional tools via remote Model Context Protocol (MCP) @@ -1750,8 +1756,8 @@ private constructor( val bestMatches = sequenceOf( - tryDeserialize(node, jacksonTypeRef())?.let { - Tool(models = it, _json = json) + tryDeserialize(node, jacksonTypeRef())?.let { + Tool(realtimeFunction = it, _json = json) }, tryDeserialize(node, jacksonTypeRef()) ?.let { Tool(realtimeResponseCreateMcp = it, _json = json) }, @@ -1780,7 +1786,7 @@ private constructor( provider: SerializerProvider, ) { when { - value.models != null -> generator.writeObject(value.models) + value.realtimeFunction != null -> generator.writeObject(value.realtimeFunction) value.realtimeResponseCreateMcp != null -> generator.writeObject(value.realtimeResponseCreateMcp) value._json != null -> generator.writeObject(value._json) diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeServerEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeServerEvent.kt index 353b3d9b..0cad1e4d 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeServerEvent.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeServerEvent.kt @@ -68,8 +68,6 @@ private constructor( private val responseOutputTextDone: ResponseTextDoneEvent? = null, private val sessionCreated: SessionCreatedEvent? = null, private val sessionUpdated: SessionUpdatedEvent? = null, - private val transcriptionSessionUpdated: TranscriptionSessionUpdatedEvent? = null, - private val transcriptionSessionCreated: TranscriptionSessionCreated? = null, private val outputAudioBufferStarted: OutputAudioBufferStarted? = null, private val outputAudioBufferStopped: OutputAudioBufferStopped? = null, private val outputAudioBufferCleared: OutputAudioBufferCleared? = null, @@ -319,17 +317,6 @@ private constructor( */ fun sessionUpdated(): Optional = Optional.ofNullable(sessionUpdated) - /** - * Returned when a transcription session is updated with a `transcription_session.update` event, - * unless there is an error. - */ - fun transcriptionSessionUpdated(): Optional = - Optional.ofNullable(transcriptionSessionUpdated) - - /** Returned when a transcription session is created. */ - fun transcriptionSessionCreated(): Optional = - Optional.ofNullable(transcriptionSessionCreated) - /** * **WebRTC Only:** Emitted when the server begins streaming audio to the client. This event is * emitted after an audio content part has been added (`response.content_part.added`) to the @@ -487,10 +474,6 @@ private constructor( fun isSessionUpdated(): Boolean = sessionUpdated != null - fun isTranscriptionSessionUpdated(): Boolean = transcriptionSessionUpdated != null - - fun isTranscriptionSessionCreated(): Boolean = transcriptionSessionCreated != null - fun isOutputAudioBufferStarted(): Boolean = outputAudioBufferStarted != null fun isOutputAudioBufferStopped(): Boolean = outputAudioBufferStopped != null @@ -757,17 +740,6 @@ private constructor( */ fun asSessionUpdated(): SessionUpdatedEvent = sessionUpdated.getOrThrow("sessionUpdated") - /** - * Returned when a transcription session is updated with a `transcription_session.update` event, - * unless there is an error. - */ - fun asTranscriptionSessionUpdated(): TranscriptionSessionUpdatedEvent = - transcriptionSessionUpdated.getOrThrow("transcriptionSessionUpdated") - - /** Returned when a transcription session is created. */ - fun asTranscriptionSessionCreated(): TranscriptionSessionCreated = - transcriptionSessionCreated.getOrThrow("transcriptionSessionCreated") - /** * **WebRTC Only:** Emitted when the server begins streaming audio to the client. This event is * emitted after an audio content part has been added (`response.content_part.added`) to the @@ -928,10 +900,6 @@ private constructor( visitor.visitResponseOutputTextDone(responseOutputTextDone) sessionCreated != null -> visitor.visitSessionCreated(sessionCreated) sessionUpdated != null -> visitor.visitSessionUpdated(sessionUpdated) - transcriptionSessionUpdated != null -> - visitor.visitTranscriptionSessionUpdated(transcriptionSessionUpdated) - transcriptionSessionCreated != null -> - visitor.visitTranscriptionSessionCreated(transcriptionSessionCreated) outputAudioBufferStarted != null -> visitor.visitOutputAudioBufferStarted(outputAudioBufferStarted) outputAudioBufferStopped != null -> @@ -1145,18 +1113,6 @@ private constructor( sessionUpdated.validate() } - override fun visitTranscriptionSessionUpdated( - transcriptionSessionUpdated: TranscriptionSessionUpdatedEvent - ) { - transcriptionSessionUpdated.validate() - } - - override fun visitTranscriptionSessionCreated( - transcriptionSessionCreated: TranscriptionSessionCreated - ) { - transcriptionSessionCreated.validate() - } - override fun visitOutputAudioBufferStarted( outputAudioBufferStarted: OutputAudioBufferStarted ) { @@ -1381,14 +1337,6 @@ private constructor( override fun visitSessionUpdated(sessionUpdated: SessionUpdatedEvent) = sessionUpdated.validity() - override fun visitTranscriptionSessionUpdated( - transcriptionSessionUpdated: TranscriptionSessionUpdatedEvent - ) = transcriptionSessionUpdated.validity() - - override fun visitTranscriptionSessionCreated( - transcriptionSessionCreated: TranscriptionSessionCreated - ) = transcriptionSessionCreated.validity() - override fun visitOutputAudioBufferStarted( outputAudioBufferStarted: OutputAudioBufferStarted ) = outputAudioBufferStarted.validity() @@ -1491,8 +1439,6 @@ private constructor( responseOutputTextDone == other.responseOutputTextDone && sessionCreated == other.sessionCreated && sessionUpdated == other.sessionUpdated && - transcriptionSessionUpdated == other.transcriptionSessionUpdated && - transcriptionSessionCreated == other.transcriptionSessionCreated && outputAudioBufferStarted == other.outputAudioBufferStarted && outputAudioBufferStopped == other.outputAudioBufferStopped && outputAudioBufferCleared == other.outputAudioBufferCleared && @@ -1543,8 +1489,6 @@ private constructor( responseOutputTextDone, sessionCreated, sessionUpdated, - transcriptionSessionUpdated, - transcriptionSessionCreated, outputAudioBufferStarted, outputAudioBufferStopped, outputAudioBufferCleared, @@ -1618,10 +1562,6 @@ private constructor( "RealtimeServerEvent{responseOutputTextDone=$responseOutputTextDone}" sessionCreated != null -> "RealtimeServerEvent{sessionCreated=$sessionCreated}" sessionUpdated != null -> "RealtimeServerEvent{sessionUpdated=$sessionUpdated}" - transcriptionSessionUpdated != null -> - "RealtimeServerEvent{transcriptionSessionUpdated=$transcriptionSessionUpdated}" - transcriptionSessionCreated != null -> - "RealtimeServerEvent{transcriptionSessionCreated=$transcriptionSessionCreated}" outputAudioBufferStarted != null -> "RealtimeServerEvent{outputAudioBufferStarted=$outputAudioBufferStarted}" outputAudioBufferStopped != null -> @@ -1956,21 +1896,6 @@ private constructor( fun ofSessionUpdated(sessionUpdated: SessionUpdatedEvent) = RealtimeServerEvent(sessionUpdated = sessionUpdated) - /** - * Returned when a transcription session is updated with a `transcription_session.update` - * event, unless there is an error. - */ - @JvmStatic - fun ofTranscriptionSessionUpdated( - transcriptionSessionUpdated: TranscriptionSessionUpdatedEvent - ) = RealtimeServerEvent(transcriptionSessionUpdated = transcriptionSessionUpdated) - - /** Returned when a transcription session is created. */ - @JvmStatic - fun ofTranscriptionSessionCreated( - transcriptionSessionCreated: TranscriptionSessionCreated - ) = RealtimeServerEvent(transcriptionSessionCreated = transcriptionSessionCreated) - /** * **WebRTC Only:** Emitted when the server begins streaming audio to the client. This event * is emitted after an audio content part has been added (`response.content_part.added`) to @@ -2327,19 +2252,6 @@ private constructor( */ fun visitSessionUpdated(sessionUpdated: SessionUpdatedEvent): T - /** - * Returned when a transcription session is updated with a `transcription_session.update` - * event, unless there is an error. - */ - fun visitTranscriptionSessionUpdated( - transcriptionSessionUpdated: TranscriptionSessionUpdatedEvent - ): T - - /** Returned when a transcription session is created. */ - fun visitTranscriptionSessionCreated( - transcriptionSessionCreated: TranscriptionSessionCreated - ): T - /** * **WebRTC Only:** Emitted when the server begins streaming audio to the client. This event * is emitted after an audio content part has been added (`response.content_part.added`) to @@ -2652,18 +2564,6 @@ private constructor( RealtimeServerEvent(sessionUpdated = it, _json = json) } ?: RealtimeServerEvent(_json = json) } - "transcription_session.updated" -> { - return tryDeserialize(node, jacksonTypeRef()) - ?.let { - RealtimeServerEvent(transcriptionSessionUpdated = it, _json = json) - } ?: RealtimeServerEvent(_json = json) - } - "transcription_session.created" -> { - return tryDeserialize(node, jacksonTypeRef()) - ?.let { - RealtimeServerEvent(transcriptionSessionCreated = it, _json = json) - } ?: RealtimeServerEvent(_json = json) - } "output_audio_buffer.started" -> { return tryDeserialize(node, jacksonTypeRef())?.let { RealtimeServerEvent(outputAudioBufferStarted = it, _json = json) @@ -2817,10 +2717,6 @@ private constructor( generator.writeObject(value.responseOutputTextDone) value.sessionCreated != null -> generator.writeObject(value.sessionCreated) value.sessionUpdated != null -> generator.writeObject(value.sessionUpdated) - value.transcriptionSessionUpdated != null -> - generator.writeObject(value.transcriptionSessionUpdated) - value.transcriptionSessionCreated != null -> - generator.writeObject(value.transcriptionSessionCreated) value.outputAudioBufferStarted != null -> generator.writeObject(value.outputAudioBufferStarted) value.outputAudioBufferStopped != null -> diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeSession.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeSession.kt index 83d01e4b..cf15084c 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeSession.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeSession.kt @@ -50,7 +50,7 @@ private constructor( private val speed: JsonField, private val temperature: JsonField, private val toolChoice: JsonField, - private val tools: JsonField>, + private val tools: JsonField>, private val tracing: JsonField, private val turnDetection: JsonField, private val voice: JsonField, @@ -97,7 +97,9 @@ private constructor( @JsonProperty("tool_choice") @ExcludeMissing toolChoice: JsonField = JsonMissing.of(), - @JsonProperty("tools") @ExcludeMissing tools: JsonField> = JsonMissing.of(), + @JsonProperty("tools") + @ExcludeMissing + tools: JsonField> = JsonMissing.of(), @JsonProperty("tracing") @ExcludeMissing tracing: JsonField = JsonMissing.of(), @JsonProperty("turn_detection") @ExcludeMissing @@ -293,7 +295,7 @@ private constructor( * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). */ - fun tools(): Optional> = tools.getOptional("tools") + fun tools(): Optional> = tools.getOptional("tools") /** * Configuration options for tracing. Set to null to disable tracing. Once tracing is enabled @@ -469,7 +471,9 @@ private constructor( * * Unlike [tools], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("tools") @ExcludeMissing fun _tools(): JsonField> = tools + @JsonProperty("tools") + @ExcludeMissing + fun _tools(): JsonField> = tools /** * Returns the raw JSON value of [tracing]. @@ -531,7 +535,7 @@ private constructor( private var speed: JsonField = JsonMissing.of() private var temperature: JsonField = JsonMissing.of() private var toolChoice: JsonField = JsonMissing.of() - private var tools: JsonField>? = null + private var tools: JsonField>? = null private var tracing: JsonField = JsonMissing.of() private var turnDetection: JsonField = JsonMissing.of() private var voice: JsonField = JsonMissing.of() @@ -874,25 +878,25 @@ private constructor( fun toolChoice(toolChoice: JsonField) = apply { this.toolChoice = toolChoice } /** Tools (functions) available to the model. */ - fun tools(tools: List) = tools(JsonField.of(tools)) + fun tools(tools: List) = tools(JsonField.of(tools)) /** * Sets [Builder.tools] to an arbitrary JSON value. * - * You should usually call [Builder.tools] with a well-typed `List` value instead. - * This method is primarily for setting the field to an undocumented or not yet supported - * value. + * You should usually call [Builder.tools] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. */ - fun tools(tools: JsonField>) = apply { + fun tools(tools: JsonField>) = apply { this.tools = tools.map { it.toMutableList() } } /** - * Adds a single [Models] to [tools]. + * Adds a single [RealtimeFunctionTool] to [tools]. * * @throws IllegalStateException if the field was previously set to a non-list. */ - fun addTool(tool: Models) = apply { + fun addTool(tool: RealtimeFunctionTool) = apply { tools = (tools ?: JsonField.of(mutableListOf())).also { checkKnown("tools", it).add(tool) } } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeSessionCreateRequest.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeSessionCreateRequest.kt index e8141700..95cd4e5e 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeSessionCreateRequest.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeSessionCreateRequest.kt @@ -614,7 +614,8 @@ private constructor( } /** Alias for calling [addTool] with `RealtimeToolsConfigUnion.ofFunction(function)`. */ - fun addTool(function: Models) = addTool(RealtimeToolsConfigUnion.ofFunction(function)) + fun addTool(function: RealtimeFunctionTool) = + addTool(RealtimeToolsConfigUnion.ofFunction(function)) /** Alias for calling [addTool] with `RealtimeToolsConfigUnion.ofMcp(mcp)`. */ fun addTool(mcp: RealtimeToolsConfigUnion.Mcp) = diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeToolsConfigUnion.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeToolsConfigUnion.kt index be30df73..bbee3c61 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeToolsConfigUnion.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeToolsConfigUnion.kt @@ -39,12 +39,12 @@ import kotlin.jvm.optionals.getOrNull @JsonSerialize(using = RealtimeToolsConfigUnion.Serializer::class) class RealtimeToolsConfigUnion private constructor( - private val function: Models? = null, + private val function: RealtimeFunctionTool? = null, private val mcp: Mcp? = null, private val _json: JsonValue? = null, ) { - fun function(): Optional = Optional.ofNullable(function) + fun function(): Optional = Optional.ofNullable(function) /** * Give the model access to additional tools via remote Model Context Protocol (MCP) servers. @@ -56,7 +56,7 @@ private constructor( fun isMcp(): Boolean = mcp != null - fun asFunction(): Models = function.getOrThrow("function") + fun asFunction(): RealtimeFunctionTool = function.getOrThrow("function") /** * Give the model access to additional tools via remote Model Context Protocol (MCP) servers. @@ -82,7 +82,7 @@ private constructor( accept( object : Visitor { - override fun visitFunction(function: Models) { + override fun visitFunction(function: RealtimeFunctionTool) { function.validate() } @@ -111,7 +111,7 @@ private constructor( internal fun validity(): Int = accept( object : Visitor { - override fun visitFunction(function: Models) = function.validity() + override fun visitFunction(function: RealtimeFunctionTool) = function.validity() override fun visitMcp(mcp: Mcp) = mcp.validity() @@ -139,7 +139,9 @@ private constructor( companion object { - @JvmStatic fun ofFunction(function: Models) = RealtimeToolsConfigUnion(function = function) + @JvmStatic + fun ofFunction(function: RealtimeFunctionTool) = + RealtimeToolsConfigUnion(function = function) /** * Give the model access to additional tools via remote Model Context Protocol (MCP) @@ -155,7 +157,7 @@ private constructor( */ interface Visitor { - fun visitFunction(function: Models): T + fun visitFunction(function: RealtimeFunctionTool): T /** * Give the model access to additional tools via remote Model Context Protocol (MCP) @@ -188,7 +190,7 @@ private constructor( when (type) { "function" -> { - return tryDeserialize(node, jacksonTypeRef())?.let { + return tryDeserialize(node, jacksonTypeRef())?.let { RealtimeToolsConfigUnion(function = it, _json = json) } ?: RealtimeToolsConfigUnion(_json = json) } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/TranscriptionSessionCreated.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/TranscriptionSessionCreated.kt deleted file mode 100644 index c6792b4f..00000000 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/TranscriptionSessionCreated.kt +++ /dev/null @@ -1,270 +0,0 @@ -// 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.core.checkRequired -import com.openai.errors.OpenAIInvalidDataException -import com.openai.models.realtime.clientsecrets.RealtimeTranscriptionSessionCreateResponse -import java.util.Collections -import java.util.Objects -import kotlin.jvm.optionals.getOrNull - -/** Returned when a transcription session is created. */ -class TranscriptionSessionCreated -private constructor( - private val eventId: JsonField, - private val session: JsonField, - private val type: JsonValue, - private val additionalProperties: MutableMap, -) { - - @JsonCreator - private constructor( - @JsonProperty("event_id") @ExcludeMissing eventId: JsonField = JsonMissing.of(), - @JsonProperty("session") - @ExcludeMissing - session: JsonField = JsonMissing.of(), - @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), - ) : this(eventId, session, type, mutableMapOf()) - - /** - * The unique ID of the server event. - * - * @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). - */ - fun eventId(): String = eventId.getRequired("event_id") - - /** - * A new Realtime transcription session configuration. - * - * When a session is created on the server via REST API, the session object also contains an - * ephemeral key. Default TTL for keys is 10 minutes. This property is not present when a - * session is updated via the WebSocket API. - * - * @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). - */ - fun session(): RealtimeTranscriptionSessionCreateResponse = session.getRequired("session") - - /** - * The event type, must be `transcription_session.created`. - * - * Expected to always return the following: - * ```java - * JsonValue.from("transcription_session.created") - * ``` - * - * However, this method can be useful for debugging and logging (e.g. if the server responded - * with an unexpected value). - */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type - - /** - * Returns the raw JSON value of [eventId]. - * - * Unlike [eventId], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("event_id") @ExcludeMissing fun _eventId(): JsonField = eventId - - /** - * Returns the raw JSON value of [session]. - * - * Unlike [session], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("session") - @ExcludeMissing - fun _session(): JsonField = session - - @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 [TranscriptionSessionCreated]. - * - * The following fields are required: - * ```java - * .eventId() - * .session() - * ``` - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [TranscriptionSessionCreated]. */ - class Builder internal constructor() { - - private var eventId: JsonField? = null - private var session: JsonField? = null - private var type: JsonValue = JsonValue.from("transcription_session.created") - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(transcriptionSessionCreated: TranscriptionSessionCreated) = apply { - eventId = transcriptionSessionCreated.eventId - session = transcriptionSessionCreated.session - type = transcriptionSessionCreated.type - additionalProperties = transcriptionSessionCreated.additionalProperties.toMutableMap() - } - - /** The unique ID of the server event. */ - fun eventId(eventId: String) = eventId(JsonField.of(eventId)) - - /** - * Sets [Builder.eventId] to an arbitrary JSON value. - * - * You should usually call [Builder.eventId] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun eventId(eventId: JsonField) = apply { this.eventId = eventId } - - /** - * A new Realtime transcription session configuration. - * - * When a session is created on the server via REST API, the session object also contains an - * ephemeral key. Default TTL for keys is 10 minutes. This property is not present when a - * session is updated via the WebSocket API. - */ - fun session(session: RealtimeTranscriptionSessionCreateResponse) = - session(JsonField.of(session)) - - /** - * Sets [Builder.session] to an arbitrary JSON value. - * - * You should usually call [Builder.session] with a well-typed - * [RealtimeTranscriptionSessionCreateResponse] value instead. This method is primarily for - * setting the field to an undocumented or not yet supported value. - */ - fun session(session: JsonField) = apply { - this.session = session - } - - /** - * Sets the field to an arbitrary JSON value. - * - * It is usually unnecessary to call this method because the field defaults to the - * following: - * ```java - * JsonValue.from("transcription_session.created") - * ``` - * - * This method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun type(type: JsonValue) = 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 [TranscriptionSessionCreated]. - * - * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .eventId() - * .session() - * ``` - * - * @throws IllegalStateException if any required field is unset. - */ - fun build(): TranscriptionSessionCreated = - TranscriptionSessionCreated( - checkRequired("eventId", eventId), - checkRequired("session", session), - type, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): TranscriptionSessionCreated = apply { - if (validated) { - return@apply - } - - eventId() - session().validate() - _type().let { - if (it != JsonValue.from("transcription_session.created")) { - throw OpenAIInvalidDataException("'type' is invalid, received $it") - } - } - 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 (eventId.asKnown().isPresent) 1 else 0) + - (session.asKnown().getOrNull()?.validity() ?: 0) + - type.let { if (it == JsonValue.from("transcription_session.created")) 1 else 0 } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is TranscriptionSessionCreated && - eventId == other.eventId && - session == other.session && - type == other.type && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { Objects.hash(eventId, session, type, additionalProperties) } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "TranscriptionSessionCreated{eventId=$eventId, session=$session, type=$type, additionalProperties=$additionalProperties}" -} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/TranscriptionSessionUpdatedEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/TranscriptionSessionUpdatedEvent.kt index 655b6e84..3a91c74a 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/TranscriptionSessionUpdatedEvent.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/TranscriptionSessionUpdatedEvent.kt @@ -6,15 +6,18 @@ 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.core.checkKnown import com.openai.core.checkRequired +import com.openai.core.toImmutable import com.openai.errors.OpenAIInvalidDataException -import com.openai.models.realtime.clientsecrets.RealtimeTranscriptionSessionCreateResponse import java.util.Collections import java.util.Objects +import java.util.Optional import kotlin.jvm.optionals.getOrNull /** @@ -24,7 +27,7 @@ import kotlin.jvm.optionals.getOrNull class TranscriptionSessionUpdatedEvent private constructor( private val eventId: JsonField, - private val session: JsonField, + private val session: JsonField, private val type: JsonValue, private val additionalProperties: MutableMap, ) { @@ -32,9 +35,7 @@ private constructor( @JsonCreator private constructor( @JsonProperty("event_id") @ExcludeMissing eventId: JsonField = JsonMissing.of(), - @JsonProperty("session") - @ExcludeMissing - session: JsonField = JsonMissing.of(), + @JsonProperty("session") @ExcludeMissing session: JsonField = JsonMissing.of(), @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), ) : this(eventId, session, type, mutableMapOf()) @@ -56,7 +57,7 @@ private constructor( * @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). */ - fun session(): RealtimeTranscriptionSessionCreateResponse = session.getRequired("session") + fun session(): Session = session.getRequired("session") /** * The event type, must be `transcription_session.updated`. @@ -83,9 +84,7 @@ private constructor( * * Unlike [session], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("session") - @ExcludeMissing - fun _session(): JsonField = session + @JsonProperty("session") @ExcludeMissing fun _session(): JsonField = session @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { @@ -118,7 +117,7 @@ private constructor( class Builder internal constructor() { private var eventId: JsonField? = null - private var session: JsonField? = null + private var session: JsonField? = null private var type: JsonValue = JsonValue.from("transcription_session.updated") private var additionalProperties: MutableMap = mutableMapOf() @@ -150,19 +149,15 @@ private constructor( * ephemeral key. Default TTL for keys is 10 minutes. This property is not present when a * session is updated via the WebSocket API. */ - fun session(session: RealtimeTranscriptionSessionCreateResponse) = - session(JsonField.of(session)) + fun session(session: Session) = session(JsonField.of(session)) /** * Sets [Builder.session] to an arbitrary JSON value. * - * You should usually call [Builder.session] with a well-typed - * [RealtimeTranscriptionSessionCreateResponse] value instead. This method is primarily for - * setting the field to an undocumented or not yet supported value. + * You should usually call [Builder.session] with a well-typed [Session] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. */ - fun session(session: JsonField) = apply { - this.session = session - } + fun session(session: JsonField) = apply { this.session = session } /** * Sets the field to an arbitrary JSON value. @@ -255,6 +250,1051 @@ private constructor( (session.asKnown().getOrNull()?.validity() ?: 0) + type.let { if (it == JsonValue.from("transcription_session.updated")) 1 else 0 } + /** + * A new Realtime transcription session configuration. + * + * When a session is created on the server via REST API, the session object also contains an + * ephemeral key. Default TTL for keys is 10 minutes. This property is not present when a + * session is updated via the WebSocket API. + */ + class Session + private constructor( + private val clientSecret: JsonField, + private val inputAudioFormat: JsonField, + private val inputAudioTranscription: JsonField, + private val modalities: JsonField>, + private val turnDetection: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("client_secret") + @ExcludeMissing + clientSecret: JsonField = JsonMissing.of(), + @JsonProperty("input_audio_format") + @ExcludeMissing + inputAudioFormat: JsonField = JsonMissing.of(), + @JsonProperty("input_audio_transcription") + @ExcludeMissing + inputAudioTranscription: JsonField = JsonMissing.of(), + @JsonProperty("modalities") + @ExcludeMissing + modalities: JsonField> = JsonMissing.of(), + @JsonProperty("turn_detection") + @ExcludeMissing + turnDetection: JsonField = JsonMissing.of(), + ) : this( + clientSecret, + inputAudioFormat, + inputAudioTranscription, + modalities, + turnDetection, + mutableMapOf(), + ) + + /** + * Ephemeral key returned by the API. Only present when the session is created on the server + * via REST API. + * + * @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). + */ + fun clientSecret(): ClientSecret = clientSecret.getRequired("client_secret") + + /** + * The format of input audio. Options are `pcm16`, `g711_ulaw`, or `g711_alaw`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun inputAudioFormat(): Optional = + inputAudioFormat.getOptional("input_audio_format") + + /** + * Configuration of the transcription model. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun inputAudioTranscription(): Optional = + inputAudioTranscription.getOptional("input_audio_transcription") + + /** + * The set of modalities the model can respond with. To disable audio, set this to ["text"]. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun modalities(): Optional> = modalities.getOptional("modalities") + + /** + * Configuration for turn detection. Can be set to `null` to turn off. 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. + * + * @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 [clientSecret]. + * + * Unlike [clientSecret], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("client_secret") + @ExcludeMissing + fun _clientSecret(): JsonField = clientSecret + + /** + * Returns the raw JSON value of [inputAudioFormat]. + * + * Unlike [inputAudioFormat], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("input_audio_format") + @ExcludeMissing + fun _inputAudioFormat(): JsonField = inputAudioFormat + + /** + * Returns the raw JSON value of [inputAudioTranscription]. + * + * Unlike [inputAudioTranscription], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("input_audio_transcription") + @ExcludeMissing + fun _inputAudioTranscription(): JsonField = inputAudioTranscription + + /** + * Returns the raw JSON value of [modalities]. + * + * Unlike [modalities], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("modalities") + @ExcludeMissing + fun _modalities(): JsonField> = modalities + + /** + * 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 [Session]. + * + * The following fields are required: + * ```java + * .clientSecret() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Session]. */ + class Builder internal constructor() { + + private var clientSecret: JsonField? = null + private var inputAudioFormat: JsonField = JsonMissing.of() + private var inputAudioTranscription: JsonField = JsonMissing.of() + private var modalities: JsonField>? = null + private var turnDetection: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(session: Session) = apply { + clientSecret = session.clientSecret + inputAudioFormat = session.inputAudioFormat + inputAudioTranscription = session.inputAudioTranscription + modalities = session.modalities.map { it.toMutableList() } + turnDetection = session.turnDetection + additionalProperties = session.additionalProperties.toMutableMap() + } + + /** + * Ephemeral key returned by the API. Only present when the session is created on the + * server via REST API. + */ + fun clientSecret(clientSecret: ClientSecret) = clientSecret(JsonField.of(clientSecret)) + + /** + * Sets [Builder.clientSecret] to an arbitrary JSON value. + * + * You should usually call [Builder.clientSecret] with a well-typed [ClientSecret] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun clientSecret(clientSecret: JsonField) = apply { + this.clientSecret = clientSecret + } + + /** The format of input audio. Options are `pcm16`, `g711_ulaw`, or `g711_alaw`. */ + fun inputAudioFormat(inputAudioFormat: String) = + inputAudioFormat(JsonField.of(inputAudioFormat)) + + /** + * Sets [Builder.inputAudioFormat] to an arbitrary JSON value. + * + * You should usually call [Builder.inputAudioFormat] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun inputAudioFormat(inputAudioFormat: JsonField) = apply { + this.inputAudioFormat = inputAudioFormat + } + + /** Configuration of the transcription model. */ + fun inputAudioTranscription(inputAudioTranscription: AudioTranscription) = + inputAudioTranscription(JsonField.of(inputAudioTranscription)) + + /** + * Sets [Builder.inputAudioTranscription] to an arbitrary JSON value. + * + * You should usually call [Builder.inputAudioTranscription] with a well-typed + * [AudioTranscription] value instead. This method is primarily for setting the field to + * an undocumented or not yet supported value. + */ + fun inputAudioTranscription(inputAudioTranscription: JsonField) = + apply { + this.inputAudioTranscription = inputAudioTranscription + } + + /** + * The set of modalities the model can respond with. To disable audio, set this to + * ["text"]. + */ + fun modalities(modalities: List) = modalities(JsonField.of(modalities)) + + /** + * Sets [Builder.modalities] to an arbitrary JSON value. + * + * You should usually call [Builder.modalities] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun modalities(modalities: JsonField>) = apply { + this.modalities = modalities.map { it.toMutableList() } + } + + /** + * Adds a single [Modality] to [modalities]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addModality(modality: Modality) = apply { + modalities = + (modalities ?: JsonField.of(mutableListOf())).also { + checkKnown("modalities", it).add(modality) + } + } + + /** + * Configuration for turn detection. Can be set to `null` to turn off. 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. + */ + 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 [Session]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .clientSecret() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Session = + Session( + checkRequired("clientSecret", clientSecret), + inputAudioFormat, + inputAudioTranscription, + (modalities ?: JsonMissing.of()).map { it.toImmutable() }, + turnDetection, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Session = apply { + if (validated) { + return@apply + } + + clientSecret().validate() + inputAudioFormat() + inputAudioTranscription().ifPresent { it.validate() } + modalities().ifPresent { it.forEach { 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 = + (clientSecret.asKnown().getOrNull()?.validity() ?: 0) + + (if (inputAudioFormat.asKnown().isPresent) 1 else 0) + + (inputAudioTranscription.asKnown().getOrNull()?.validity() ?: 0) + + (modalities.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (turnDetection.asKnown().getOrNull()?.validity() ?: 0) + + /** + * Ephemeral key returned by the API. Only present when the session is created on the server + * via REST API. + */ + class ClientSecret + private constructor( + private val expiresAt: JsonField, + private val value: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("expires_at") + @ExcludeMissing + expiresAt: JsonField = JsonMissing.of(), + @JsonProperty("value") @ExcludeMissing value: JsonField = JsonMissing.of(), + ) : this(expiresAt, value, mutableMapOf()) + + /** + * Timestamp for when the token expires. Currently, all tokens expire after one minute. + * + * @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). + */ + fun expiresAt(): Long = expiresAt.getRequired("expires_at") + + /** + * Ephemeral key usable in client environments to authenticate connections to the + * Realtime API. Use this in client-side environments rather than a standard API token, + * which should only be used server-side. + * + * @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). + */ + fun value(): String = value.getRequired("value") + + /** + * Returns the raw JSON value of [expiresAt]. + * + * Unlike [expiresAt], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("expires_at") + @ExcludeMissing + fun _expiresAt(): JsonField = expiresAt + + /** + * Returns the raw JSON value of [value]. + * + * Unlike [value], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value + + @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 [ClientSecret]. + * + * The following fields are required: + * ```java + * .expiresAt() + * .value() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ClientSecret]. */ + class Builder internal constructor() { + + private var expiresAt: JsonField? = null + private var value: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(clientSecret: ClientSecret) = apply { + expiresAt = clientSecret.expiresAt + value = clientSecret.value + additionalProperties = clientSecret.additionalProperties.toMutableMap() + } + + /** + * Timestamp for when the token expires. Currently, all tokens expire after one + * minute. + */ + fun expiresAt(expiresAt: Long) = expiresAt(JsonField.of(expiresAt)) + + /** + * Sets [Builder.expiresAt] to an arbitrary JSON value. + * + * You should usually call [Builder.expiresAt] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun expiresAt(expiresAt: JsonField) = apply { this.expiresAt = expiresAt } + + /** + * Ephemeral key usable in client environments to authenticate connections to the + * Realtime API. Use this in client-side environments rather than a standard API + * token, which should only be used server-side. + */ + fun value(value: String) = value(JsonField.of(value)) + + /** + * Sets [Builder.value] to an arbitrary JSON value. + * + * You should usually call [Builder.value] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun value(value: JsonField) = apply { this.value = 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 [ClientSecret]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .expiresAt() + * .value() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ClientSecret = + ClientSecret( + checkRequired("expiresAt", expiresAt), + checkRequired("value", value), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): ClientSecret = apply { + if (validated) { + return@apply + } + + expiresAt() + value() + 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 (expiresAt.asKnown().isPresent) 1 else 0) + + (if (value.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ClientSecret && + expiresAt == other.expiresAt && + value == other.value && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(expiresAt, value, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ClientSecret{expiresAt=$expiresAt, value=$value, additionalProperties=$additionalProperties}" + } + + class Modality @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 TEXT = of("text") + + @JvmField val AUDIO = of("audio") + + @JvmStatic fun of(value: String) = Modality(JsonField.of(value)) + } + + /** An enum containing [Modality]'s known values. */ + enum class Known { + TEXT, + AUDIO, + } + + /** + * An enum containing [Modality]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Modality] 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 { + TEXT, + AUDIO, + /** + * An enum member indicating that [Modality] 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) { + TEXT -> Value.TEXT + AUDIO -> Value.AUDIO + 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) { + TEXT -> Known.TEXT + AUDIO -> Known.AUDIO + else -> throw OpenAIInvalidDataException("Unknown Modality: $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(): Modality = 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 Modality && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** + * Configuration for turn detection. Can be set to `null` to turn off. 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. + */ + class TurnDetection + private constructor( + private val prefixPaddingMs: JsonField, + private val silenceDurationMs: JsonField, + private val threshold: JsonField, + private val type: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @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(prefixPaddingMs, silenceDurationMs, threshold, type, mutableMapOf()) + + /** + * 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") + + /** + * 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") + + /** + * 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, only `server_vad` is currently supported. + * + * @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 [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 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 { + prefixPaddingMs = turnDetection.prefixPaddingMs + silenceDurationMs = turnDetection.silenceDurationMs + threshold = turnDetection.threshold + type = turnDetection.type + additionalProperties = turnDetection.additionalProperties.toMutableMap() + } + + /** + * 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 + } + + /** + * 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 + } + + /** + * 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, only `server_vad` is currently supported. */ + fun type(type: String) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [String] 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( + prefixPaddingMs, + silenceDurationMs, + threshold, + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): TurnDetection = apply { + if (validated) { + return@apply + } + + prefixPaddingMs() + silenceDurationMs() + threshold() + type() + 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 (prefixPaddingMs.asKnown().isPresent) 1 else 0) + + (if (silenceDurationMs.asKnown().isPresent) 1 else 0) + + (if (threshold.asKnown().isPresent) 1 else 0) + + (if (type.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is TurnDetection && + prefixPaddingMs == other.prefixPaddingMs && + silenceDurationMs == other.silenceDurationMs && + threshold == other.threshold && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + prefixPaddingMs, + silenceDurationMs, + threshold, + type, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "TurnDetection{prefixPaddingMs=$prefixPaddingMs, silenceDurationMs=$silenceDurationMs, threshold=$threshold, type=$type, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Session && + clientSecret == other.clientSecret && + inputAudioFormat == other.inputAudioFormat && + inputAudioTranscription == other.inputAudioTranscription && + modalities == other.modalities && + turnDetection == other.turnDetection && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + clientSecret, + inputAudioFormat, + inputAudioTranscription, + modalities, + turnDetection, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Session{clientSecret=$clientSecret, inputAudioFormat=$inputAudioFormat, inputAudioTranscription=$inputAudioTranscription, modalities=$modalities, turnDetection=$turnDetection, 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/clientsecrets/ClientSecretCreateResponse.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/clientsecrets/ClientSecretCreateResponse.kt index c5126b6c..1a5cc00c 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/clientsecrets/ClientSecretCreateResponse.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/clientsecrets/ClientSecretCreateResponse.kt @@ -19,7 +19,6 @@ import com.openai.core.ExcludeMissing import com.openai.core.JsonField import com.openai.core.JsonMissing import com.openai.core.JsonValue -import com.openai.core.allMaxBy import com.openai.core.checkRequired import com.openai.core.getOrThrow import com.openai.errors.OpenAIInvalidDataException @@ -154,25 +153,23 @@ private constructor( */ fun session(session: JsonField) = apply { this.session = session } - /** - * Alias for calling [session] with - * `Session.ofRealtimeSessionCreateResponse(realtimeSessionCreateResponse)`. - */ - fun session(realtimeSessionCreateResponse: RealtimeSessionCreateResponse) = - session(Session.ofRealtimeSessionCreateResponse(realtimeSessionCreateResponse)) + /** Alias for calling [session] with `Session.ofRealtime(realtime)`. */ + fun session(realtime: RealtimeSessionCreateResponse) = session(Session.ofRealtime(realtime)) /** - * Alias for calling [session] with - * `Session.ofRealtimeTranscriptionSessionCreateResponse(realtimeTranscriptionSessionCreateResponse)`. + * Alias for calling [session] with the following: + * ```java + * RealtimeSessionCreateResponse.builder() + * .clientSecret(clientSecret) + * .build() + * ``` */ - fun session( - realtimeTranscriptionSessionCreateResponse: RealtimeTranscriptionSessionCreateResponse - ) = - session( - Session.ofRealtimeTranscriptionSessionCreateResponse( - realtimeTranscriptionSessionCreateResponse - ) - ) + fun realtimeSession(clientSecret: RealtimeSessionClientSecret) = + session(RealtimeSessionCreateResponse.builder().clientSecret(clientSecret).build()) + + /** Alias for calling [session] with `Session.ofTranscription(transcription)`. */ + fun session(transcription: RealtimeTranscriptionSessionCreateResponse) = + session(Session.ofTranscription(transcription)) /** The generated client secret value. */ fun value(value: String) = value(JsonField.of(value)) @@ -264,10 +261,8 @@ private constructor( @JsonSerialize(using = Session.Serializer::class) class Session private constructor( - private val realtimeSessionCreateResponse: RealtimeSessionCreateResponse? = null, - private val realtimeTranscriptionSessionCreateResponse: - RealtimeTranscriptionSessionCreateResponse? = - null, + private val realtime: RealtimeSessionCreateResponse? = null, + private val transcription: RealtimeTranscriptionSessionCreateResponse? = null, private val _json: JsonValue? = null, ) { @@ -275,55 +270,32 @@ private constructor( * A new Realtime session configuration, with an ephemeral key. Default TTL for keys is one * minute. */ - fun realtimeSessionCreateResponse(): Optional = - Optional.ofNullable(realtimeSessionCreateResponse) + fun realtime(): Optional = Optional.ofNullable(realtime) - /** - * A new Realtime transcription session configuration. - * - * When a session is created on the server via REST API, the session object also contains an - * ephemeral key. Default TTL for keys is 10 minutes. This property is not present when a - * session is updated via the WebSocket API. - */ - fun realtimeTranscriptionSessionCreateResponse(): - Optional = - Optional.ofNullable(realtimeTranscriptionSessionCreateResponse) + /** A Realtime transcription session configuration object. */ + fun transcription(): Optional = + Optional.ofNullable(transcription) - fun isRealtimeSessionCreateResponse(): Boolean = realtimeSessionCreateResponse != null + fun isRealtime(): Boolean = realtime != null - fun isRealtimeTranscriptionSessionCreateResponse(): Boolean = - realtimeTranscriptionSessionCreateResponse != null + fun isTranscription(): Boolean = transcription != null /** * A new Realtime session configuration, with an ephemeral key. Default TTL for keys is one * minute. */ - fun asRealtimeSessionCreateResponse(): RealtimeSessionCreateResponse = - realtimeSessionCreateResponse.getOrThrow("realtimeSessionCreateResponse") + fun asRealtime(): RealtimeSessionCreateResponse = realtime.getOrThrow("realtime") - /** - * A new Realtime transcription session configuration. - * - * When a session is created on the server via REST API, the session object also contains an - * ephemeral key. Default TTL for keys is 10 minutes. This property is not present when a - * session is updated via the WebSocket API. - */ - fun asRealtimeTranscriptionSessionCreateResponse(): - RealtimeTranscriptionSessionCreateResponse = - realtimeTranscriptionSessionCreateResponse.getOrThrow( - "realtimeTranscriptionSessionCreateResponse" - ) + /** A Realtime transcription session configuration object. */ + fun asTranscription(): RealtimeTranscriptionSessionCreateResponse = + transcription.getOrThrow("transcription") fun _json(): Optional = Optional.ofNullable(_json) fun accept(visitor: Visitor): T = when { - realtimeSessionCreateResponse != null -> - visitor.visitRealtimeSessionCreateResponse(realtimeSessionCreateResponse) - realtimeTranscriptionSessionCreateResponse != null -> - visitor.visitRealtimeTranscriptionSessionCreateResponse( - realtimeTranscriptionSessionCreateResponse - ) + realtime != null -> visitor.visitRealtime(realtime) + transcription != null -> visitor.visitTranscription(transcription) else -> visitor.unknown(_json) } @@ -336,17 +308,14 @@ private constructor( accept( object : Visitor { - override fun visitRealtimeSessionCreateResponse( - realtimeSessionCreateResponse: RealtimeSessionCreateResponse - ) { - realtimeSessionCreateResponse.validate() + override fun visitRealtime(realtime: RealtimeSessionCreateResponse) { + realtime.validate() } - override fun visitRealtimeTranscriptionSessionCreateResponse( - realtimeTranscriptionSessionCreateResponse: - RealtimeTranscriptionSessionCreateResponse + override fun visitTranscription( + transcription: RealtimeTranscriptionSessionCreateResponse ) { - realtimeTranscriptionSessionCreateResponse.validate() + transcription.validate() } } ) @@ -371,14 +340,12 @@ private constructor( internal fun validity(): Int = accept( object : Visitor { - override fun visitRealtimeSessionCreateResponse( - realtimeSessionCreateResponse: RealtimeSessionCreateResponse - ) = realtimeSessionCreateResponse.validity() + override fun visitRealtime(realtime: RealtimeSessionCreateResponse) = + realtime.validity() - override fun visitRealtimeTranscriptionSessionCreateResponse( - realtimeTranscriptionSessionCreateResponse: - RealtimeTranscriptionSessionCreateResponse - ) = realtimeTranscriptionSessionCreateResponse.validity() + override fun visitTranscription( + transcription: RealtimeTranscriptionSessionCreateResponse + ) = transcription.validity() override fun unknown(json: JsonValue?) = 0 } @@ -390,20 +357,16 @@ private constructor( } return other is Session && - realtimeSessionCreateResponse == other.realtimeSessionCreateResponse && - realtimeTranscriptionSessionCreateResponse == - other.realtimeTranscriptionSessionCreateResponse + realtime == other.realtime && + transcription == other.transcription } - override fun hashCode(): Int = - Objects.hash(realtimeSessionCreateResponse, realtimeTranscriptionSessionCreateResponse) + override fun hashCode(): Int = Objects.hash(realtime, transcription) override fun toString(): String = when { - realtimeSessionCreateResponse != null -> - "Session{realtimeSessionCreateResponse=$realtimeSessionCreateResponse}" - realtimeTranscriptionSessionCreateResponse != null -> - "Session{realtimeTranscriptionSessionCreateResponse=$realtimeTranscriptionSessionCreateResponse}" + realtime != null -> "Session{realtime=$realtime}" + transcription != null -> "Session{transcription=$transcription}" _json != null -> "Session{_unknown=$_json}" else -> throw IllegalStateException("Invalid Session") } @@ -415,26 +378,12 @@ private constructor( * one minute. */ @JvmStatic - fun ofRealtimeSessionCreateResponse( - realtimeSessionCreateResponse: RealtimeSessionCreateResponse - ) = Session(realtimeSessionCreateResponse = realtimeSessionCreateResponse) + fun ofRealtime(realtime: RealtimeSessionCreateResponse) = Session(realtime = realtime) - /** - * A new Realtime transcription session configuration. - * - * When a session is created on the server via REST API, the session object also - * contains an ephemeral key. Default TTL for keys is 10 minutes. This property is not - * present when a session is updated via the WebSocket API. - */ + /** A Realtime transcription session configuration object. */ @JvmStatic - fun ofRealtimeTranscriptionSessionCreateResponse( - realtimeTranscriptionSessionCreateResponse: - RealtimeTranscriptionSessionCreateResponse - ) = - Session( - realtimeTranscriptionSessionCreateResponse = - realtimeTranscriptionSessionCreateResponse - ) + fun ofTranscription(transcription: RealtimeTranscriptionSessionCreateResponse) = + Session(transcription = transcription) } /** @@ -446,21 +395,10 @@ private constructor( * A new Realtime session configuration, with an ephemeral key. Default TTL for keys is * one minute. */ - fun visitRealtimeSessionCreateResponse( - realtimeSessionCreateResponse: RealtimeSessionCreateResponse - ): T + fun visitRealtime(realtime: RealtimeSessionCreateResponse): T - /** - * A new Realtime transcription session configuration. - * - * When a session is created on the server via REST API, the session object also - * contains an ephemeral key. Default TTL for keys is 10 minutes. This property is not - * present when a session is updated via the WebSocket API. - */ - fun visitRealtimeTranscriptionSessionCreateResponse( - realtimeTranscriptionSessionCreateResponse: - RealtimeTranscriptionSessionCreateResponse - ): T + /** A Realtime transcription session configuration object. */ + fun visitTranscription(transcription: RealtimeTranscriptionSessionCreateResponse): T /** * Maps an unknown variant of [Session] to a value of type [T]. @@ -481,35 +419,24 @@ private constructor( override fun ObjectCodec.deserialize(node: JsonNode): Session { val json = JsonValue.fromJsonNode(node) + val type = json.asObject().getOrNull()?.get("type")?.asString()?.getOrNull() - val bestMatches = - sequenceOf( - tryDeserialize(node, jacksonTypeRef()) - ?.let { Session(realtimeSessionCreateResponse = it, _json = json) }, - tryDeserialize( - node, - jacksonTypeRef(), - ) - ?.let { - Session( - realtimeTranscriptionSessionCreateResponse = it, - _json = json, - ) - }, - ) - .filterNotNull() - .allMaxBy { it.validity() } - .toList() - return when (bestMatches.size) { - // This can happen if what we're deserializing is completely incompatible with - // all the possible variants (e.g. deserializing from boolean). - 0 -> Session(_json = json) - 1 -> bestMatches.single() - // If there's more than one match with the highest validity, then use the first - // completely valid match, or simply the first match if none are completely - // valid. - else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + when (type) { + "realtime" -> { + return tryDeserialize(node, jacksonTypeRef()) + ?.let { Session(realtime = it, _json = json) } ?: Session(_json = json) + } + "transcription" -> { + return tryDeserialize( + node, + jacksonTypeRef(), + ) + ?.let { Session(transcription = it, _json = json) } + ?: Session(_json = json) + } } + + return Session(_json = json) } } @@ -521,10 +448,8 @@ private constructor( provider: SerializerProvider, ) { when { - value.realtimeSessionCreateResponse != null -> - generator.writeObject(value.realtimeSessionCreateResponse) - value.realtimeTranscriptionSessionCreateResponse != null -> - generator.writeObject(value.realtimeTranscriptionSessionCreateResponse) + value.realtime != null -> generator.writeObject(value.realtime) + value.transcription != null -> generator.writeObject(value.transcription) value._json != null -> generator.writeObject(value._json) else -> throw IllegalStateException("Invalid Session") } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/clientsecrets/RealtimeSessionCreateResponse.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/clientsecrets/RealtimeSessionCreateResponse.kt index c11961e0..721d6e94 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/clientsecrets/RealtimeSessionCreateResponse.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/clientsecrets/RealtimeSessionCreateResponse.kt @@ -27,9 +27,9 @@ import com.openai.core.getOrThrow import com.openai.core.toImmutable import com.openai.errors.OpenAIInvalidDataException import com.openai.models.realtime.AudioTranscription -import com.openai.models.realtime.Models import com.openai.models.realtime.NoiseReductionType import com.openai.models.realtime.RealtimeAudioFormats +import com.openai.models.realtime.RealtimeFunctionTool import com.openai.models.realtime.RealtimeTruncation import com.openai.models.realtime.RealtimeTruncationRetentionRatio import com.openai.models.responses.ResponsePrompt @@ -46,8 +46,9 @@ import kotlin.jvm.optionals.getOrNull */ class RealtimeSessionCreateResponse private constructor( - private val audio: JsonField