diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 6a37fe2d..3b4c2d4b 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "4.0.1" + ".": "4.1.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 27f2ffc6..4e40d470 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-e205b1f2da6a1f2caa229efa9ede63f2d3d2fedeeb2dd6ed3d880bafdcb0ab88.yml -openapi_spec_hash: c8aee2469a749f6a838b40c57e4b7b06 -config_hash: 45dcba51451ba532959c020a0ddbf23c +configured_endpoints: 122 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-fadefdc7c7e30df47c09df323669b242ff90ee08e51f304175ace5274e0aab49.yml +openapi_spec_hash: 6d20f639d9ff8a097a34962da6218231 +config_hash: 902654e60f5d659f2bfcfd903e17c46d diff --git a/CHANGELOG.md b/CHANGELOG.md index b3d2db44..47456bf8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 4.1.0 (2025-10-02) + +Full Changelog: [v4.0.1...v4.1.0](https://github.com/openai/openai-java/compare/v4.0.1...v4.1.0) + +### Features + +* **api:** add support for realtime calls ([c4d224c](https://github.com/openai/openai-java/commit/c4d224cf9b37aa0535c2857f3159421898304ff6)) + ## 4.0.1 (2025-10-01) Full Changelog: [v4.0.0...v4.0.1](https://github.com/openai/openai-java/compare/v4.0.0...v4.0.1) diff --git a/README.md b/README.md index 84e22df1..ed41afcf 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ -[![Maven Central](https://img.shields.io/maven-central/v/com.openai/openai-java)](https://central.sonatype.com/artifact/com.openai/openai-java/4.0.1) -[![javadoc](https://javadoc.io/badge2/com.openai/openai-java/4.0.1/javadoc.svg)](https://javadoc.io/doc/com.openai/openai-java/4.0.1) +[![Maven Central](https://img.shields.io/maven-central/v/com.openai/openai-java)](https://central.sonatype.com/artifact/com.openai/openai-java/4.1.0) +[![javadoc](https://javadoc.io/badge2/com.openai/openai-java/4.1.0/javadoc.svg)](https://javadoc.io/doc/com.openai/openai-java/4.1.0) @@ -11,7 +11,7 @@ The OpenAI Java SDK provides convenient access to the [OpenAI REST API](https:// -The REST API documentation can be found on [platform.openai.com](https://platform.openai.com/docs). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.openai/openai-java/4.0.1). +The REST API documentation can be found on [platform.openai.com](https://platform.openai.com/docs). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.openai/openai-java/4.1.0). @@ -24,7 +24,7 @@ The REST API documentation can be found on [platform.openai.com](https://platfor ### Gradle ```kotlin -implementation("com.openai:openai-java:4.0.1") +implementation("com.openai:openai-java:4.1.0") ``` ### Maven @@ -33,7 +33,7 @@ implementation("com.openai:openai-java:4.0.1") com.openai openai-java - 4.0.1 + 4.1.0 ``` @@ -1342,7 +1342,7 @@ If you're using Spring Boot, then you can use the SDK's [Spring Boot starter](ht #### Gradle ```kotlin -implementation("com.openai:openai-java-spring-boot-starter:4.0.1") +implementation("com.openai:openai-java-spring-boot-starter:4.1.0") ``` #### Maven @@ -1351,7 +1351,7 @@ implementation("com.openai:openai-java-spring-boot-starter:4.0.1") com.openai openai-java-spring-boot-starter - 4.0.1 + 4.1.0 ``` diff --git a/build.gradle.kts b/build.gradle.kts index 3230d8a3..d0ccf1e9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ repositories { allprojects { group = "com.openai" - version = "4.0.1" // x-release-please-version + version = "4.1.0" // x-release-please-version } subprojects { diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/calls/CallAcceptParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/calls/CallAcceptParams.kt new file mode 100644 index 00000000..53fbc597 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/calls/CallAcceptParams.kt @@ -0,0 +1,227 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.realtime.calls + +import com.openai.core.JsonValue +import com.openai.core.Params +import com.openai.core.checkRequired +import com.openai.core.http.Headers +import com.openai.core.http.QueryParams +import com.openai.models.realtime.RealtimeSessionCreateRequest +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Accept an incoming SIP call and configure the realtime session that will handle it. */ +class CallAcceptParams +private constructor( + private val callId: String?, + private val realtimeSessionCreateRequest: RealtimeSessionCreateRequest, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun callId(): Optional = Optional.ofNullable(callId) + + /** Realtime session object configuration. */ + fun realtimeSessionCreateRequest(): RealtimeSessionCreateRequest = realtimeSessionCreateRequest + + fun _additionalBodyProperties(): Map = + realtimeSessionCreateRequest._additionalProperties() + + /** Additional headers to send with the request. */ + fun _additionalHeaders(): Headers = additionalHeaders + + /** Additional query param to send with the request. */ + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [CallAcceptParams]. + * + * The following fields are required: + * ```java + * .realtimeSessionCreateRequest() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [CallAcceptParams]. */ + class Builder internal constructor() { + + private var callId: String? = null + private var realtimeSessionCreateRequest: RealtimeSessionCreateRequest? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(callAcceptParams: CallAcceptParams) = apply { + callId = callAcceptParams.callId + realtimeSessionCreateRequest = callAcceptParams.realtimeSessionCreateRequest + additionalHeaders = callAcceptParams.additionalHeaders.toBuilder() + additionalQueryParams = callAcceptParams.additionalQueryParams.toBuilder() + } + + fun callId(callId: String?) = apply { this.callId = callId } + + /** Alias for calling [Builder.callId] with `callId.orElse(null)`. */ + fun callId(callId: Optional) = callId(callId.getOrNull()) + + /** Realtime session object configuration. */ + fun realtimeSessionCreateRequest( + realtimeSessionCreateRequest: RealtimeSessionCreateRequest + ) = apply { this.realtimeSessionCreateRequest = realtimeSessionCreateRequest } + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) + } + + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } + + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } + + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } + + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } + + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } + + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + /** + * Returns an immutable instance of [CallAcceptParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .realtimeSessionCreateRequest() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): CallAcceptParams = + CallAcceptParams( + callId, + checkRequired("realtimeSessionCreateRequest", realtimeSessionCreateRequest), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): RealtimeSessionCreateRequest = realtimeSessionCreateRequest + + fun _pathParam(index: Int): String = + when (index) { + 0 -> callId ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is CallAcceptParams && + callId == other.callId && + realtimeSessionCreateRequest == other.realtimeSessionCreateRequest && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(callId, realtimeSessionCreateRequest, additionalHeaders, additionalQueryParams) + + override fun toString() = + "CallAcceptParams{callId=$callId, realtimeSessionCreateRequest=$realtimeSessionCreateRequest, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/calls/CallHangupParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/calls/CallHangupParams.kt new file mode 100644 index 00000000..c62586a3 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/calls/CallHangupParams.kt @@ -0,0 +1,229 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.realtime.calls + +import com.openai.core.JsonValue +import com.openai.core.Params +import com.openai.core.http.Headers +import com.openai.core.http.QueryParams +import com.openai.core.toImmutable +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** End an active Realtime API call, whether it was initiated over SIP or WebRTC. */ +class CallHangupParams +private constructor( + private val callId: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, + private val additionalBodyProperties: Map, +) : Params { + + fun callId(): Optional = Optional.ofNullable(callId) + + /** Additional body properties to send with the request. */ + fun _additionalBodyProperties(): Map = additionalBodyProperties + + /** Additional headers to send with the request. */ + fun _additionalHeaders(): Headers = additionalHeaders + + /** Additional query param to send with the request. */ + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + @JvmStatic fun none(): CallHangupParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [CallHangupParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [CallHangupParams]. */ + class Builder internal constructor() { + + private var callId: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + private var additionalBodyProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(callHangupParams: CallHangupParams) = apply { + callId = callHangupParams.callId + additionalHeaders = callHangupParams.additionalHeaders.toBuilder() + additionalQueryParams = callHangupParams.additionalQueryParams.toBuilder() + additionalBodyProperties = callHangupParams.additionalBodyProperties.toMutableMap() + } + + fun callId(callId: String?) = apply { this.callId = callId } + + /** Alias for calling [Builder.callId] with `callId.orElse(null)`. */ + fun callId(callId: Optional) = callId(callId.getOrNull()) + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) + } + + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } + + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } + + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } + + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } + + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } + + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + this.additionalBodyProperties.clear() + putAllAdditionalBodyProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + additionalBodyProperties.put(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + this.additionalBodyProperties.putAll(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { + additionalBodyProperties.remove(key) + } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalBodyProperty) + } + + /** + * Returns an immutable instance of [CallHangupParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): CallHangupParams = + CallHangupParams( + callId, + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), + ) + } + + fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) + + fun _pathParam(index: Int): String = + when (index) { + 0 -> callId ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is CallHangupParams && + callId == other.callId && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams && + additionalBodyProperties == other.additionalBodyProperties + } + + override fun hashCode(): Int = + Objects.hash(callId, additionalHeaders, additionalQueryParams, additionalBodyProperties) + + override fun toString() = + "CallHangupParams{callId=$callId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/calls/CallReferParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/calls/CallReferParams.kt new file mode 100644 index 00000000..ccec151d --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/calls/CallReferParams.kt @@ -0,0 +1,448 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.realtime.calls + +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.Params +import com.openai.core.checkRequired +import com.openai.core.http.Headers +import com.openai.core.http.QueryParams +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Transfer an active SIP call to a new destination using the SIP REFER verb. */ +class CallReferParams +private constructor( + private val callId: String?, + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun callId(): Optional = Optional.ofNullable(callId) + + /** + * URI that should appear in the SIP Refer-To header. Supports values like `tel:+14155550123` or + * `sip:agent@example.com`. + * + * @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 targetUri(): String = body.targetUri() + + /** + * Returns the raw JSON value of [targetUri]. + * + * Unlike [targetUri], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _targetUri(): JsonField = body._targetUri() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + /** Additional headers to send with the request. */ + fun _additionalHeaders(): Headers = additionalHeaders + + /** Additional query param to send with the request. */ + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [CallReferParams]. + * + * The following fields are required: + * ```java + * .targetUri() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [CallReferParams]. */ + class Builder internal constructor() { + + private var callId: String? = null + private var body: Body.Builder = Body.builder() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(callReferParams: CallReferParams) = apply { + callId = callReferParams.callId + body = callReferParams.body.toBuilder() + additionalHeaders = callReferParams.additionalHeaders.toBuilder() + additionalQueryParams = callReferParams.additionalQueryParams.toBuilder() + } + + fun callId(callId: String?) = apply { this.callId = callId } + + /** Alias for calling [Builder.callId] with `callId.orElse(null)`. */ + fun callId(callId: Optional) = callId(callId.getOrNull()) + + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [targetUri] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** + * URI that should appear in the SIP Refer-To header. Supports values like + * `tel:+14155550123` or `sip:agent@example.com`. + */ + fun targetUri(targetUri: String) = apply { body.targetUri(targetUri) } + + /** + * Sets [Builder.targetUri] to an arbitrary JSON value. + * + * You should usually call [Builder.targetUri] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun targetUri(targetUri: JsonField) = apply { body.targetUri(targetUri) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) + } + + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } + + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } + + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } + + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } + + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } + + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + /** + * Returns an immutable instance of [CallReferParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .targetUri() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): CallReferParams = + CallReferParams( + callId, + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + fun _pathParam(index: Int): String = + when (index) { + 0 -> callId ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + /** Parameters required to transfer a SIP call to a new destination using the Realtime API. */ + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val targetUri: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("target_uri") + @ExcludeMissing + targetUri: JsonField = JsonMissing.of() + ) : this(targetUri, mutableMapOf()) + + /** + * URI that should appear in the SIP Refer-To header. Supports values like + * `tel:+14155550123` or `sip:agent@example.com`. + * + * @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 targetUri(): String = targetUri.getRequired("target_uri") + + /** + * Returns the raw JSON value of [targetUri]. + * + * Unlike [targetUri], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("target_uri") @ExcludeMissing fun _targetUri(): JsonField = targetUri + + @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 [Body]. + * + * The following fields are required: + * ```java + * .targetUri() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var targetUri: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + targetUri = body.targetUri + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** + * URI that should appear in the SIP Refer-To header. Supports values like + * `tel:+14155550123` or `sip:agent@example.com`. + */ + fun targetUri(targetUri: String) = targetUri(JsonField.of(targetUri)) + + /** + * Sets [Builder.targetUri] to an arbitrary JSON value. + * + * You should usually call [Builder.targetUri] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun targetUri(targetUri: JsonField) = apply { this.targetUri = targetUri } + + 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 [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .targetUri() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body(checkRequired("targetUri", targetUri), additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + targetUri() + 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 (targetUri.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + targetUri == other.targetUri && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(targetUri, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{targetUri=$targetUri, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is CallReferParams && + callId == other.callId && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(callId, body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "CallReferParams{callId=$callId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/calls/CallRejectParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/calls/CallRejectParams.kt new file mode 100644 index 00000000..e625d3ac --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/calls/CallRejectParams.kt @@ -0,0 +1,416 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.realtime.calls + +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.Params +import com.openai.core.http.Headers +import com.openai.core.http.QueryParams +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Decline an incoming SIP call by returning a SIP status code to the caller. */ +class CallRejectParams +private constructor( + private val callId: String?, + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun callId(): Optional = Optional.ofNullable(callId) + + /** + * SIP response code to send back to the caller. Defaults to `603` (Decline) when omitted. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun statusCode(): Optional = body.statusCode() + + /** + * Returns the raw JSON value of [statusCode]. + * + * Unlike [statusCode], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _statusCode(): JsonField = body._statusCode() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + /** Additional headers to send with the request. */ + fun _additionalHeaders(): Headers = additionalHeaders + + /** Additional query param to send with the request. */ + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + @JvmStatic fun none(): CallRejectParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [CallRejectParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [CallRejectParams]. */ + class Builder internal constructor() { + + private var callId: String? = null + private var body: Body.Builder = Body.builder() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(callRejectParams: CallRejectParams) = apply { + callId = callRejectParams.callId + body = callRejectParams.body.toBuilder() + additionalHeaders = callRejectParams.additionalHeaders.toBuilder() + additionalQueryParams = callRejectParams.additionalQueryParams.toBuilder() + } + + fun callId(callId: String?) = apply { this.callId = callId } + + /** Alias for calling [Builder.callId] with `callId.orElse(null)`. */ + fun callId(callId: Optional) = callId(callId.getOrNull()) + + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [statusCode] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** + * SIP response code to send back to the caller. Defaults to `603` (Decline) when omitted. + */ + fun statusCode(statusCode: Long) = apply { body.statusCode(statusCode) } + + /** + * Sets [Builder.statusCode] to an arbitrary JSON value. + * + * You should usually call [Builder.statusCode] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun statusCode(statusCode: JsonField) = apply { body.statusCode(statusCode) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) + } + + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } + + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } + + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } + + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } + + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } + + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + /** + * Returns an immutable instance of [CallRejectParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): CallRejectParams = + CallRejectParams( + callId, + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + fun _pathParam(index: Int): String = + when (index) { + 0 -> callId ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + /** Parameters used to decline an incoming SIP call handled by the Realtime API. */ + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val statusCode: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("status_code") + @ExcludeMissing + statusCode: JsonField = JsonMissing.of() + ) : this(statusCode, mutableMapOf()) + + /** + * SIP response code to send back to the caller. Defaults to `603` (Decline) when omitted. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun statusCode(): Optional = statusCode.getOptional("status_code") + + /** + * Returns the raw JSON value of [statusCode]. + * + * Unlike [statusCode], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status_code") @ExcludeMissing fun _statusCode(): JsonField = statusCode + + @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 [Body]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var statusCode: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + statusCode = body.statusCode + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** + * SIP response code to send back to the caller. Defaults to `603` (Decline) when + * omitted. + */ + fun statusCode(statusCode: Long) = statusCode(JsonField.of(statusCode)) + + /** + * Sets [Builder.statusCode] to an arbitrary JSON value. + * + * You should usually call [Builder.statusCode] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun statusCode(statusCode: JsonField) = apply { this.statusCode = statusCode } + + 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 [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Body = Body(statusCode, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + statusCode() + 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 (statusCode.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + statusCode == other.statusCode && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(statusCode, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{statusCode=$statusCode, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is CallRejectParams && + callId == other.callId && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(callId, body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "CallRejectParams{callId=$callId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/RealtimeServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/RealtimeServiceAsync.kt index 439aeee9..8595c99a 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/RealtimeServiceAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/RealtimeServiceAsync.kt @@ -3,6 +3,7 @@ package com.openai.services.async import com.openai.core.ClientOptions +import com.openai.services.async.realtime.CallServiceAsync import com.openai.services.async.realtime.ClientSecretServiceAsync import java.util.function.Consumer @@ -22,6 +23,8 @@ interface RealtimeServiceAsync { fun clientSecrets(): ClientSecretServiceAsync + fun calls(): CallServiceAsync + /** * A view of [RealtimeServiceAsync] that provides access to raw HTTP responses for each method. */ @@ -37,5 +40,7 @@ interface RealtimeServiceAsync { ): RealtimeServiceAsync.WithRawResponse fun clientSecrets(): ClientSecretServiceAsync.WithRawResponse + + fun calls(): CallServiceAsync.WithRawResponse } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/RealtimeServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/RealtimeServiceAsyncImpl.kt index 5ded7c7e..4b2443bf 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/RealtimeServiceAsyncImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/RealtimeServiceAsyncImpl.kt @@ -3,6 +3,8 @@ package com.openai.services.async import com.openai.core.ClientOptions +import com.openai.services.async.realtime.CallServiceAsync +import com.openai.services.async.realtime.CallServiceAsyncImpl import com.openai.services.async.realtime.ClientSecretServiceAsync import com.openai.services.async.realtime.ClientSecretServiceAsyncImpl import java.util.function.Consumer @@ -18,6 +20,8 @@ class RealtimeServiceAsyncImpl internal constructor(private val clientOptions: C ClientSecretServiceAsyncImpl(clientOptions) } + private val calls: CallServiceAsync by lazy { CallServiceAsyncImpl(clientOptions) } + override fun withRawResponse(): RealtimeServiceAsync.WithRawResponse = withRawResponse override fun withOptions(modifier: Consumer): RealtimeServiceAsync = @@ -25,6 +29,8 @@ class RealtimeServiceAsyncImpl internal constructor(private val clientOptions: C override fun clientSecrets(): ClientSecretServiceAsync = clientSecrets + override fun calls(): CallServiceAsync = calls + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : RealtimeServiceAsync.WithRawResponse { @@ -32,6 +38,10 @@ class RealtimeServiceAsyncImpl internal constructor(private val clientOptions: C ClientSecretServiceAsyncImpl.WithRawResponseImpl(clientOptions) } + private val calls: CallServiceAsync.WithRawResponse by lazy { + CallServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + override fun withOptions( modifier: Consumer ): RealtimeServiceAsync.WithRawResponse = @@ -40,5 +50,7 @@ class RealtimeServiceAsyncImpl internal constructor(private val clientOptions: C ) override fun clientSecrets(): ClientSecretServiceAsync.WithRawResponse = clientSecrets + + override fun calls(): CallServiceAsync.WithRawResponse = calls } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/realtime/CallServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/realtime/CallServiceAsync.kt new file mode 100644 index 00000000..16fe3831 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/realtime/CallServiceAsync.kt @@ -0,0 +1,265 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.services.async.realtime + +import com.openai.core.ClientOptions +import com.openai.core.RequestOptions +import com.openai.core.http.HttpResponse +import com.openai.models.realtime.calls.CallAcceptParams +import com.openai.models.realtime.calls.CallHangupParams +import com.openai.models.realtime.calls.CallReferParams +import com.openai.models.realtime.calls.CallRejectParams +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +interface CallServiceAsync { + + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + + /** + * Returns a view of this service with the given option modifications applied. + * + * The original service is not modified. + */ + fun withOptions(modifier: Consumer): CallServiceAsync + + /** Accept an incoming SIP call and configure the realtime session that will handle it. */ + fun accept(callId: String, params: CallAcceptParams): CompletableFuture = + accept(callId, params, RequestOptions.none()) + + /** @see accept */ + fun accept( + callId: String, + params: CallAcceptParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = accept(params.toBuilder().callId(callId).build(), requestOptions) + + /** @see accept */ + fun accept(params: CallAcceptParams): CompletableFuture = + accept(params, RequestOptions.none()) + + /** @see accept */ + fun accept( + params: CallAcceptParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** End an active Realtime API call, whether it was initiated over SIP or WebRTC. */ + fun hangup(callId: String): CompletableFuture = hangup(callId, CallHangupParams.none()) + + /** @see hangup */ + fun hangup( + callId: String, + params: CallHangupParams = CallHangupParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = hangup(params.toBuilder().callId(callId).build(), requestOptions) + + /** @see hangup */ + fun hangup( + callId: String, + params: CallHangupParams = CallHangupParams.none(), + ): CompletableFuture = hangup(callId, params, RequestOptions.none()) + + /** @see hangup */ + fun hangup( + params: CallHangupParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see hangup */ + fun hangup(params: CallHangupParams): CompletableFuture = + hangup(params, RequestOptions.none()) + + /** @see hangup */ + fun hangup(callId: String, requestOptions: RequestOptions): CompletableFuture = + hangup(callId, CallHangupParams.none(), requestOptions) + + /** Transfer an active SIP call to a new destination using the SIP REFER verb. */ + fun refer(callId: String, params: CallReferParams): CompletableFuture = + refer(callId, params, RequestOptions.none()) + + /** @see refer */ + fun refer( + callId: String, + params: CallReferParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = refer(params.toBuilder().callId(callId).build(), requestOptions) + + /** @see refer */ + fun refer(params: CallReferParams): CompletableFuture = + refer(params, RequestOptions.none()) + + /** @see refer */ + fun refer( + params: CallReferParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** Decline an incoming SIP call by returning a SIP status code to the caller. */ + fun reject(callId: String): CompletableFuture = reject(callId, CallRejectParams.none()) + + /** @see reject */ + fun reject( + callId: String, + params: CallRejectParams = CallRejectParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = reject(params.toBuilder().callId(callId).build(), requestOptions) + + /** @see reject */ + fun reject( + callId: String, + params: CallRejectParams = CallRejectParams.none(), + ): CompletableFuture = reject(callId, params, RequestOptions.none()) + + /** @see reject */ + fun reject( + params: CallRejectParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see reject */ + fun reject(params: CallRejectParams): CompletableFuture = + reject(params, RequestOptions.none()) + + /** @see reject */ + fun reject(callId: String, requestOptions: RequestOptions): CompletableFuture = + reject(callId, CallRejectParams.none(), requestOptions) + + /** A view of [CallServiceAsync] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a view of this service with the given option modifications applied. + * + * The original service is not modified. + */ + fun withOptions(modifier: Consumer): CallServiceAsync.WithRawResponse + + /** + * Returns a raw HTTP response for `post /realtime/calls/{call_id}/accept`, but is otherwise + * the same as [CallServiceAsync.accept]. + */ + fun accept(callId: String, params: CallAcceptParams): CompletableFuture = + accept(callId, params, RequestOptions.none()) + + /** @see accept */ + fun accept( + callId: String, + params: CallAcceptParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + accept(params.toBuilder().callId(callId).build(), requestOptions) + + /** @see accept */ + fun accept(params: CallAcceptParams): CompletableFuture = + accept(params, RequestOptions.none()) + + /** @see accept */ + fun accept( + params: CallAcceptParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** + * Returns a raw HTTP response for `post /realtime/calls/{call_id}/hangup`, but is otherwise + * the same as [CallServiceAsync.hangup]. + */ + fun hangup(callId: String): CompletableFuture = + hangup(callId, CallHangupParams.none()) + + /** @see hangup */ + fun hangup( + callId: String, + params: CallHangupParams = CallHangupParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + hangup(params.toBuilder().callId(callId).build(), requestOptions) + + /** @see hangup */ + fun hangup( + callId: String, + params: CallHangupParams = CallHangupParams.none(), + ): CompletableFuture = hangup(callId, params, RequestOptions.none()) + + /** @see hangup */ + fun hangup( + params: CallHangupParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see hangup */ + fun hangup(params: CallHangupParams): CompletableFuture = + hangup(params, RequestOptions.none()) + + /** @see hangup */ + fun hangup( + callId: String, + requestOptions: RequestOptions, + ): CompletableFuture = hangup(callId, CallHangupParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `post /realtime/calls/{call_id}/refer`, but is otherwise + * the same as [CallServiceAsync.refer]. + */ + fun refer(callId: String, params: CallReferParams): CompletableFuture = + refer(callId, params, RequestOptions.none()) + + /** @see refer */ + fun refer( + callId: String, + params: CallReferParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + refer(params.toBuilder().callId(callId).build(), requestOptions) + + /** @see refer */ + fun refer(params: CallReferParams): CompletableFuture = + refer(params, RequestOptions.none()) + + /** @see refer */ + fun refer( + params: CallReferParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** + * Returns a raw HTTP response for `post /realtime/calls/{call_id}/reject`, but is otherwise + * the same as [CallServiceAsync.reject]. + */ + fun reject(callId: String): CompletableFuture = + reject(callId, CallRejectParams.none()) + + /** @see reject */ + fun reject( + callId: String, + params: CallRejectParams = CallRejectParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + reject(params.toBuilder().callId(callId).build(), requestOptions) + + /** @see reject */ + fun reject( + callId: String, + params: CallRejectParams = CallRejectParams.none(), + ): CompletableFuture = reject(callId, params, RequestOptions.none()) + + /** @see reject */ + fun reject( + params: CallRejectParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see reject */ + fun reject(params: CallRejectParams): CompletableFuture = + reject(params, RequestOptions.none()) + + /** @see reject */ + fun reject( + callId: String, + requestOptions: RequestOptions, + ): CompletableFuture = reject(callId, CallRejectParams.none(), requestOptions) + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/realtime/CallServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/realtime/CallServiceAsyncImpl.kt new file mode 100644 index 00000000..dd222558 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/realtime/CallServiceAsyncImpl.kt @@ -0,0 +1,187 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.services.async.realtime + +import com.openai.core.ClientOptions +import com.openai.core.RequestOptions +import com.openai.core.checkRequired +import com.openai.core.handlers.emptyHandler +import com.openai.core.handlers.errorBodyHandler +import com.openai.core.handlers.errorHandler +import com.openai.core.http.HttpMethod +import com.openai.core.http.HttpRequest +import com.openai.core.http.HttpResponse +import com.openai.core.http.HttpResponse.Handler +import com.openai.core.http.json +import com.openai.core.http.parseable +import com.openai.core.prepareAsync +import com.openai.models.realtime.calls.CallAcceptParams +import com.openai.models.realtime.calls.CallHangupParams +import com.openai.models.realtime.calls.CallReferParams +import com.openai.models.realtime.calls.CallRejectParams +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer +import kotlin.jvm.optionals.getOrNull + +class CallServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + CallServiceAsync { + + private val withRawResponse: CallServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): CallServiceAsync.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): CallServiceAsync = + CallServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun accept( + params: CallAcceptParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /realtime/calls/{call_id}/accept + withRawResponse().accept(params, requestOptions).thenAccept {} + + override fun hangup( + params: CallHangupParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /realtime/calls/{call_id}/hangup + withRawResponse().hangup(params, requestOptions).thenAccept {} + + override fun refer( + params: CallReferParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /realtime/calls/{call_id}/refer + withRawResponse().refer(params, requestOptions).thenAccept {} + + override fun reject( + params: CallRejectParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /realtime/calls/{call_id}/reject + withRawResponse().reject(params, requestOptions).thenAccept {} + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + CallServiceAsync.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): CallServiceAsync.WithRawResponse = + CallServiceAsyncImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val acceptHandler: Handler = emptyHandler() + + override fun accept( + params: CallAcceptParams, + requestOptions: RequestOptions, + ): CompletableFuture { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("callId", params.callId().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("realtime", "calls", params._pathParam(0), "accept") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response.use { acceptHandler.handle(it) } + } + } + } + + private val hangupHandler: Handler = emptyHandler() + + override fun hangup( + params: CallHangupParams, + requestOptions: RequestOptions, + ): CompletableFuture { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("callId", params.callId().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("realtime", "calls", params._pathParam(0), "hangup") + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response.use { hangupHandler.handle(it) } + } + } + } + + private val referHandler: Handler = emptyHandler() + + override fun refer( + params: CallReferParams, + requestOptions: RequestOptions, + ): CompletableFuture { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("callId", params.callId().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("realtime", "calls", params._pathParam(0), "refer") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response.use { referHandler.handle(it) } + } + } + } + + private val rejectHandler: Handler = emptyHandler() + + override fun reject( + params: CallRejectParams, + requestOptions: RequestOptions, + ): CompletableFuture { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("callId", params.callId().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("realtime", "calls", params._pathParam(0), "reject") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response.use { rejectHandler.handle(it) } + } + } + } + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/RealtimeService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/RealtimeService.kt index 8a380ee7..b776aa49 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/RealtimeService.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/RealtimeService.kt @@ -3,6 +3,7 @@ package com.openai.services.blocking import com.openai.core.ClientOptions +import com.openai.services.blocking.realtime.CallService import com.openai.services.blocking.realtime.ClientSecretService import java.util.function.Consumer @@ -22,6 +23,8 @@ interface RealtimeService { fun clientSecrets(): ClientSecretService + fun calls(): CallService + /** A view of [RealtimeService] that provides access to raw HTTP responses for each method. */ interface WithRawResponse { @@ -33,5 +36,7 @@ interface RealtimeService { fun withOptions(modifier: Consumer): RealtimeService.WithRawResponse fun clientSecrets(): ClientSecretService.WithRawResponse + + fun calls(): CallService.WithRawResponse } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/RealtimeServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/RealtimeServiceImpl.kt index 4cd4236a..aa430126 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/RealtimeServiceImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/RealtimeServiceImpl.kt @@ -3,6 +3,8 @@ package com.openai.services.blocking import com.openai.core.ClientOptions +import com.openai.services.blocking.realtime.CallService +import com.openai.services.blocking.realtime.CallServiceImpl import com.openai.services.blocking.realtime.ClientSecretService import com.openai.services.blocking.realtime.ClientSecretServiceImpl import java.util.function.Consumer @@ -18,6 +20,8 @@ class RealtimeServiceImpl internal constructor(private val clientOptions: Client ClientSecretServiceImpl(clientOptions) } + private val calls: CallService by lazy { CallServiceImpl(clientOptions) } + override fun withRawResponse(): RealtimeService.WithRawResponse = withRawResponse override fun withOptions(modifier: Consumer): RealtimeService = @@ -25,6 +29,8 @@ class RealtimeServiceImpl internal constructor(private val clientOptions: Client override fun clientSecrets(): ClientSecretService = clientSecrets + override fun calls(): CallService = calls + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : RealtimeService.WithRawResponse { @@ -32,6 +38,10 @@ class RealtimeServiceImpl internal constructor(private val clientOptions: Client ClientSecretServiceImpl.WithRawResponseImpl(clientOptions) } + private val calls: CallService.WithRawResponse by lazy { + CallServiceImpl.WithRawResponseImpl(clientOptions) + } + override fun withOptions( modifier: Consumer ): RealtimeService.WithRawResponse = @@ -40,5 +50,7 @@ class RealtimeServiceImpl internal constructor(private val clientOptions: Client ) override fun clientSecrets(): ClientSecretService.WithRawResponse = clientSecrets + + override fun calls(): CallService.WithRawResponse = calls } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/realtime/CallService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/realtime/CallService.kt new file mode 100644 index 00000000..f2754cf3 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/realtime/CallService.kt @@ -0,0 +1,251 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.services.blocking.realtime + +import com.google.errorprone.annotations.MustBeClosed +import com.openai.core.ClientOptions +import com.openai.core.RequestOptions +import com.openai.core.http.HttpResponse +import com.openai.models.realtime.calls.CallAcceptParams +import com.openai.models.realtime.calls.CallHangupParams +import com.openai.models.realtime.calls.CallReferParams +import com.openai.models.realtime.calls.CallRejectParams +import java.util.function.Consumer + +interface CallService { + + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + + /** + * Returns a view of this service with the given option modifications applied. + * + * The original service is not modified. + */ + fun withOptions(modifier: Consumer): CallService + + /** Accept an incoming SIP call and configure the realtime session that will handle it. */ + fun accept(callId: String, params: CallAcceptParams) = + accept(callId, params, RequestOptions.none()) + + /** @see accept */ + fun accept( + callId: String, + params: CallAcceptParams, + requestOptions: RequestOptions = RequestOptions.none(), + ) = accept(params.toBuilder().callId(callId).build(), requestOptions) + + /** @see accept */ + fun accept(params: CallAcceptParams) = accept(params, RequestOptions.none()) + + /** @see accept */ + fun accept(params: CallAcceptParams, requestOptions: RequestOptions = RequestOptions.none()) + + /** End an active Realtime API call, whether it was initiated over SIP or WebRTC. */ + fun hangup(callId: String) = hangup(callId, CallHangupParams.none()) + + /** @see hangup */ + fun hangup( + callId: String, + params: CallHangupParams = CallHangupParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ) = hangup(params.toBuilder().callId(callId).build(), requestOptions) + + /** @see hangup */ + fun hangup(callId: String, params: CallHangupParams = CallHangupParams.none()) = + hangup(callId, params, RequestOptions.none()) + + /** @see hangup */ + fun hangup(params: CallHangupParams, requestOptions: RequestOptions = RequestOptions.none()) + + /** @see hangup */ + fun hangup(params: CallHangupParams) = hangup(params, RequestOptions.none()) + + /** @see hangup */ + fun hangup(callId: String, requestOptions: RequestOptions) = + hangup(callId, CallHangupParams.none(), requestOptions) + + /** Transfer an active SIP call to a new destination using the SIP REFER verb. */ + fun refer(callId: String, params: CallReferParams) = + refer(callId, params, RequestOptions.none()) + + /** @see refer */ + fun refer( + callId: String, + params: CallReferParams, + requestOptions: RequestOptions = RequestOptions.none(), + ) = refer(params.toBuilder().callId(callId).build(), requestOptions) + + /** @see refer */ + fun refer(params: CallReferParams) = refer(params, RequestOptions.none()) + + /** @see refer */ + fun refer(params: CallReferParams, requestOptions: RequestOptions = RequestOptions.none()) + + /** Decline an incoming SIP call by returning a SIP status code to the caller. */ + fun reject(callId: String) = reject(callId, CallRejectParams.none()) + + /** @see reject */ + fun reject( + callId: String, + params: CallRejectParams = CallRejectParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ) = reject(params.toBuilder().callId(callId).build(), requestOptions) + + /** @see reject */ + fun reject(callId: String, params: CallRejectParams = CallRejectParams.none()) = + reject(callId, params, RequestOptions.none()) + + /** @see reject */ + fun reject(params: CallRejectParams, requestOptions: RequestOptions = RequestOptions.none()) + + /** @see reject */ + fun reject(params: CallRejectParams) = reject(params, RequestOptions.none()) + + /** @see reject */ + fun reject(callId: String, requestOptions: RequestOptions) = + reject(callId, CallRejectParams.none(), requestOptions) + + /** A view of [CallService] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a view of this service with the given option modifications applied. + * + * The original service is not modified. + */ + fun withOptions(modifier: Consumer): CallService.WithRawResponse + + /** + * Returns a raw HTTP response for `post /realtime/calls/{call_id}/accept`, but is otherwise + * the same as [CallService.accept]. + */ + @MustBeClosed + fun accept(callId: String, params: CallAcceptParams): HttpResponse = + accept(callId, params, RequestOptions.none()) + + /** @see accept */ + @MustBeClosed + fun accept( + callId: String, + params: CallAcceptParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponse = accept(params.toBuilder().callId(callId).build(), requestOptions) + + /** @see accept */ + @MustBeClosed + fun accept(params: CallAcceptParams): HttpResponse = accept(params, RequestOptions.none()) + + /** @see accept */ + @MustBeClosed + fun accept( + params: CallAcceptParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponse + + /** + * Returns a raw HTTP response for `post /realtime/calls/{call_id}/hangup`, but is otherwise + * the same as [CallService.hangup]. + */ + @MustBeClosed + fun hangup(callId: String): HttpResponse = hangup(callId, CallHangupParams.none()) + + /** @see hangup */ + @MustBeClosed + fun hangup( + callId: String, + params: CallHangupParams = CallHangupParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponse = hangup(params.toBuilder().callId(callId).build(), requestOptions) + + /** @see hangup */ + @MustBeClosed + fun hangup( + callId: String, + params: CallHangupParams = CallHangupParams.none(), + ): HttpResponse = hangup(callId, params, RequestOptions.none()) + + /** @see hangup */ + @MustBeClosed + fun hangup( + params: CallHangupParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponse + + /** @see hangup */ + @MustBeClosed + fun hangup(params: CallHangupParams): HttpResponse = hangup(params, RequestOptions.none()) + + /** @see hangup */ + @MustBeClosed + fun hangup(callId: String, requestOptions: RequestOptions): HttpResponse = + hangup(callId, CallHangupParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `post /realtime/calls/{call_id}/refer`, but is otherwise + * the same as [CallService.refer]. + */ + @MustBeClosed + fun refer(callId: String, params: CallReferParams): HttpResponse = + refer(callId, params, RequestOptions.none()) + + /** @see refer */ + @MustBeClosed + fun refer( + callId: String, + params: CallReferParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponse = refer(params.toBuilder().callId(callId).build(), requestOptions) + + /** @see refer */ + @MustBeClosed + fun refer(params: CallReferParams): HttpResponse = refer(params, RequestOptions.none()) + + /** @see refer */ + @MustBeClosed + fun refer( + params: CallReferParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponse + + /** + * Returns a raw HTTP response for `post /realtime/calls/{call_id}/reject`, but is otherwise + * the same as [CallService.reject]. + */ + @MustBeClosed + fun reject(callId: String): HttpResponse = reject(callId, CallRejectParams.none()) + + /** @see reject */ + @MustBeClosed + fun reject( + callId: String, + params: CallRejectParams = CallRejectParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponse = reject(params.toBuilder().callId(callId).build(), requestOptions) + + /** @see reject */ + @MustBeClosed + fun reject( + callId: String, + params: CallRejectParams = CallRejectParams.none(), + ): HttpResponse = reject(callId, params, RequestOptions.none()) + + /** @see reject */ + @MustBeClosed + fun reject( + params: CallRejectParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponse + + /** @see reject */ + @MustBeClosed + fun reject(params: CallRejectParams): HttpResponse = reject(params, RequestOptions.none()) + + /** @see reject */ + @MustBeClosed + fun reject(callId: String, requestOptions: RequestOptions): HttpResponse = + reject(callId, CallRejectParams.none(), requestOptions) + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/realtime/CallServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/realtime/CallServiceImpl.kt new file mode 100644 index 00000000..6b2cb71d --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/realtime/CallServiceImpl.kt @@ -0,0 +1,162 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.services.blocking.realtime + +import com.openai.core.ClientOptions +import com.openai.core.RequestOptions +import com.openai.core.checkRequired +import com.openai.core.handlers.emptyHandler +import com.openai.core.handlers.errorBodyHandler +import com.openai.core.handlers.errorHandler +import com.openai.core.http.HttpMethod +import com.openai.core.http.HttpRequest +import com.openai.core.http.HttpResponse +import com.openai.core.http.HttpResponse.Handler +import com.openai.core.http.json +import com.openai.core.http.parseable +import com.openai.core.prepare +import com.openai.models.realtime.calls.CallAcceptParams +import com.openai.models.realtime.calls.CallHangupParams +import com.openai.models.realtime.calls.CallReferParams +import com.openai.models.realtime.calls.CallRejectParams +import java.util.function.Consumer +import kotlin.jvm.optionals.getOrNull + +class CallServiceImpl internal constructor(private val clientOptions: ClientOptions) : CallService { + + private val withRawResponse: CallService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): CallService.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): CallService = + CallServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun accept(params: CallAcceptParams, requestOptions: RequestOptions) { + // post /realtime/calls/{call_id}/accept + withRawResponse().accept(params, requestOptions) + } + + override fun hangup(params: CallHangupParams, requestOptions: RequestOptions) { + // post /realtime/calls/{call_id}/hangup + withRawResponse().hangup(params, requestOptions) + } + + override fun refer(params: CallReferParams, requestOptions: RequestOptions) { + // post /realtime/calls/{call_id}/refer + withRawResponse().refer(params, requestOptions) + } + + override fun reject(params: CallRejectParams, requestOptions: RequestOptions) { + // post /realtime/calls/{call_id}/reject + withRawResponse().reject(params, requestOptions) + } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + CallService.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): CallService.WithRawResponse = + CallServiceImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val acceptHandler: Handler = emptyHandler() + + override fun accept( + params: CallAcceptParams, + requestOptions: RequestOptions, + ): HttpResponse { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("callId", params.callId().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("realtime", "calls", params._pathParam(0), "accept") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response.use { acceptHandler.handle(it) } + } + } + + private val hangupHandler: Handler = emptyHandler() + + override fun hangup( + params: CallHangupParams, + requestOptions: RequestOptions, + ): HttpResponse { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("callId", params.callId().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("realtime", "calls", params._pathParam(0), "hangup") + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response.use { hangupHandler.handle(it) } + } + } + + private val referHandler: Handler = emptyHandler() + + override fun refer(params: CallReferParams, requestOptions: RequestOptions): HttpResponse { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("callId", params.callId().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("realtime", "calls", params._pathParam(0), "refer") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response.use { referHandler.handle(it) } + } + } + + private val rejectHandler: Handler = emptyHandler() + + override fun reject( + params: CallRejectParams, + requestOptions: RequestOptions, + ): HttpResponse { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("callId", params.callId().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("realtime", "calls", params._pathParam(0), "reject") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response.use { rejectHandler.handle(it) } + } + } + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/realtime/calls/CallAcceptParamsTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/realtime/calls/CallAcceptParamsTest.kt new file mode 100644 index 00000000..05a736b1 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/realtime/calls/CallAcceptParamsTest.kt @@ -0,0 +1,311 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.realtime.calls + +import com.openai.core.JsonValue +import com.openai.models.realtime.AudioTranscription +import com.openai.models.realtime.NoiseReductionType +import com.openai.models.realtime.RealtimeAudioConfig +import com.openai.models.realtime.RealtimeAudioConfigInput +import com.openai.models.realtime.RealtimeAudioConfigOutput +import com.openai.models.realtime.RealtimeAudioFormats +import com.openai.models.realtime.RealtimeAudioInputTurnDetection +import com.openai.models.realtime.RealtimeFunctionTool +import com.openai.models.realtime.RealtimeSessionCreateRequest +import com.openai.models.realtime.RealtimeTruncation +import com.openai.models.responses.ResponsePrompt +import com.openai.models.responses.ToolChoiceOptions +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class CallAcceptParamsTest { + + @Test + fun create() { + CallAcceptParams.builder() + .callId("call_id") + .realtimeSessionCreateRequest( + RealtimeSessionCreateRequest.builder() + .audio( + RealtimeAudioConfig.builder() + .input( + RealtimeAudioConfigInput.builder() + .format( + RealtimeAudioFormats.AudioPcm.builder() + .rate(RealtimeAudioFormats.AudioPcm.Rate._24000) + .type(RealtimeAudioFormats.AudioPcm.Type.AUDIO_PCM) + .build() + ) + .noiseReduction( + RealtimeAudioConfigInput.NoiseReduction.builder() + .type(NoiseReductionType.NEAR_FIELD) + .build() + ) + .transcription( + AudioTranscription.builder() + .language("language") + .model(AudioTranscription.Model.WHISPER_1) + .prompt("prompt") + .build() + ) + .turnDetection( + RealtimeAudioInputTurnDetection.ServerVad.builder() + .createResponse(true) + .idleTimeoutMs(5000L) + .interruptResponse(true) + .prefixPaddingMs(0L) + .silenceDurationMs(0L) + .threshold(0.0) + .build() + ) + .build() + ) + .output( + RealtimeAudioConfigOutput.builder() + .format( + RealtimeAudioFormats.AudioPcm.builder() + .rate(RealtimeAudioFormats.AudioPcm.Rate._24000) + .type(RealtimeAudioFormats.AudioPcm.Type.AUDIO_PCM) + .build() + ) + .speed(0.25) + .voice(RealtimeAudioConfigOutput.Voice.ALLOY) + .build() + ) + .build() + ) + .addInclude( + RealtimeSessionCreateRequest.Include.ITEM_INPUT_AUDIO_TRANSCRIPTION_LOGPROBS + ) + .instructions("instructions") + .maxOutputTokens(0L) + .model(RealtimeSessionCreateRequest.Model.GPT_REALTIME) + .addOutputModality(RealtimeSessionCreateRequest.OutputModality.TEXT) + .prompt( + ResponsePrompt.builder() + .id("id") + .variables( + ResponsePrompt.Variables.builder() + .putAdditionalProperty("foo", JsonValue.from("string")) + .build() + ) + .version("version") + .build() + ) + .toolChoice(ToolChoiceOptions.NONE) + .addTool( + RealtimeFunctionTool.builder() + .description("description") + .name("name") + .parameters(JsonValue.from(mapOf())) + .type(RealtimeFunctionTool.Type.FUNCTION) + .build() + ) + .tracingAuto() + .truncation(RealtimeTruncation.RealtimeTruncationStrategy.AUTO) + .build() + ) + .build() + } + + @Test + fun pathParams() { + val params = + CallAcceptParams.builder() + .callId("call_id") + .realtimeSessionCreateRequest(RealtimeSessionCreateRequest.builder().build()) + .build() + + assertThat(params._pathParam(0)).isEqualTo("call_id") + // out-of-bound path param + assertThat(params._pathParam(1)).isEqualTo("") + } + + @Test + fun body() { + val params = + CallAcceptParams.builder() + .callId("call_id") + .realtimeSessionCreateRequest( + RealtimeSessionCreateRequest.builder() + .audio( + RealtimeAudioConfig.builder() + .input( + RealtimeAudioConfigInput.builder() + .format( + RealtimeAudioFormats.AudioPcm.builder() + .rate(RealtimeAudioFormats.AudioPcm.Rate._24000) + .type(RealtimeAudioFormats.AudioPcm.Type.AUDIO_PCM) + .build() + ) + .noiseReduction( + RealtimeAudioConfigInput.NoiseReduction.builder() + .type(NoiseReductionType.NEAR_FIELD) + .build() + ) + .transcription( + AudioTranscription.builder() + .language("language") + .model(AudioTranscription.Model.WHISPER_1) + .prompt("prompt") + .build() + ) + .turnDetection( + RealtimeAudioInputTurnDetection.ServerVad.builder() + .createResponse(true) + .idleTimeoutMs(5000L) + .interruptResponse(true) + .prefixPaddingMs(0L) + .silenceDurationMs(0L) + .threshold(0.0) + .build() + ) + .build() + ) + .output( + RealtimeAudioConfigOutput.builder() + .format( + RealtimeAudioFormats.AudioPcm.builder() + .rate(RealtimeAudioFormats.AudioPcm.Rate._24000) + .type(RealtimeAudioFormats.AudioPcm.Type.AUDIO_PCM) + .build() + ) + .speed(0.25) + .voice(RealtimeAudioConfigOutput.Voice.ALLOY) + .build() + ) + .build() + ) + .addInclude( + RealtimeSessionCreateRequest.Include + .ITEM_INPUT_AUDIO_TRANSCRIPTION_LOGPROBS + ) + .instructions("instructions") + .maxOutputTokens(0L) + .model(RealtimeSessionCreateRequest.Model.GPT_REALTIME) + .addOutputModality(RealtimeSessionCreateRequest.OutputModality.TEXT) + .prompt( + ResponsePrompt.builder() + .id("id") + .variables( + ResponsePrompt.Variables.builder() + .putAdditionalProperty("foo", JsonValue.from("string")) + .build() + ) + .version("version") + .build() + ) + .toolChoice(ToolChoiceOptions.NONE) + .addTool( + RealtimeFunctionTool.builder() + .description("description") + .name("name") + .parameters(JsonValue.from(mapOf())) + .type(RealtimeFunctionTool.Type.FUNCTION) + .build() + ) + .tracingAuto() + .truncation(RealtimeTruncation.RealtimeTruncationStrategy.AUTO) + .build() + ) + .build() + + val body = params._body() + + assertThat(body) + .isEqualTo( + RealtimeSessionCreateRequest.builder() + .audio( + RealtimeAudioConfig.builder() + .input( + RealtimeAudioConfigInput.builder() + .format( + RealtimeAudioFormats.AudioPcm.builder() + .rate(RealtimeAudioFormats.AudioPcm.Rate._24000) + .type(RealtimeAudioFormats.AudioPcm.Type.AUDIO_PCM) + .build() + ) + .noiseReduction( + RealtimeAudioConfigInput.NoiseReduction.builder() + .type(NoiseReductionType.NEAR_FIELD) + .build() + ) + .transcription( + AudioTranscription.builder() + .language("language") + .model(AudioTranscription.Model.WHISPER_1) + .prompt("prompt") + .build() + ) + .turnDetection( + RealtimeAudioInputTurnDetection.ServerVad.builder() + .createResponse(true) + .idleTimeoutMs(5000L) + .interruptResponse(true) + .prefixPaddingMs(0L) + .silenceDurationMs(0L) + .threshold(0.0) + .build() + ) + .build() + ) + .output( + RealtimeAudioConfigOutput.builder() + .format( + RealtimeAudioFormats.AudioPcm.builder() + .rate(RealtimeAudioFormats.AudioPcm.Rate._24000) + .type(RealtimeAudioFormats.AudioPcm.Type.AUDIO_PCM) + .build() + ) + .speed(0.25) + .voice(RealtimeAudioConfigOutput.Voice.ALLOY) + .build() + ) + .build() + ) + .addInclude( + RealtimeSessionCreateRequest.Include.ITEM_INPUT_AUDIO_TRANSCRIPTION_LOGPROBS + ) + .instructions("instructions") + .maxOutputTokens(0L) + .model(RealtimeSessionCreateRequest.Model.GPT_REALTIME) + .addOutputModality(RealtimeSessionCreateRequest.OutputModality.TEXT) + .prompt( + ResponsePrompt.builder() + .id("id") + .variables( + ResponsePrompt.Variables.builder() + .putAdditionalProperty("foo", JsonValue.from("string")) + .build() + ) + .version("version") + .build() + ) + .toolChoice(ToolChoiceOptions.NONE) + .addTool( + RealtimeFunctionTool.builder() + .description("description") + .name("name") + .parameters(JsonValue.from(mapOf())) + .type(RealtimeFunctionTool.Type.FUNCTION) + .build() + ) + .tracingAuto() + .truncation(RealtimeTruncation.RealtimeTruncationStrategy.AUTO) + .build() + ) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = + CallAcceptParams.builder() + .callId("call_id") + .realtimeSessionCreateRequest(RealtimeSessionCreateRequest.builder().build()) + .build() + + val body = params._body() + + assertThat(body).isEqualTo(RealtimeSessionCreateRequest.builder().build()) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/realtime/calls/CallHangupParamsTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/realtime/calls/CallHangupParamsTest.kt new file mode 100644 index 00000000..aa5c4349 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/realtime/calls/CallHangupParamsTest.kt @@ -0,0 +1,23 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.realtime.calls + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class CallHangupParamsTest { + + @Test + fun create() { + CallHangupParams.builder().callId("call_id").build() + } + + @Test + fun pathParams() { + val params = CallHangupParams.builder().callId("call_id").build() + + assertThat(params._pathParam(0)).isEqualTo("call_id") + // out-of-bound path param + assertThat(params._pathParam(1)).isEqualTo("") + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/realtime/calls/CallReferParamsTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/realtime/calls/CallReferParamsTest.kt new file mode 100644 index 00000000..567e3c7d --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/realtime/calls/CallReferParamsTest.kt @@ -0,0 +1,34 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.realtime.calls + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class CallReferParamsTest { + + @Test + fun create() { + CallReferParams.builder().callId("call_id").targetUri("tel:+14155550123").build() + } + + @Test + fun pathParams() { + val params = + CallReferParams.builder().callId("call_id").targetUri("tel:+14155550123").build() + + assertThat(params._pathParam(0)).isEqualTo("call_id") + // out-of-bound path param + assertThat(params._pathParam(1)).isEqualTo("") + } + + @Test + fun body() { + val params = + CallReferParams.builder().callId("call_id").targetUri("tel:+14155550123").build() + + val body = params._body() + + assertThat(body.targetUri()).isEqualTo("tel:+14155550123") + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/realtime/calls/CallRejectParamsTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/realtime/calls/CallRejectParamsTest.kt new file mode 100644 index 00000000..c569662a --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/realtime/calls/CallRejectParamsTest.kt @@ -0,0 +1,39 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.realtime.calls + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class CallRejectParamsTest { + + @Test + fun create() { + CallRejectParams.builder().callId("call_id").statusCode(486L).build() + } + + @Test + fun pathParams() { + val params = CallRejectParams.builder().callId("call_id").build() + + assertThat(params._pathParam(0)).isEqualTo("call_id") + // out-of-bound path param + assertThat(params._pathParam(1)).isEqualTo("") + } + + @Test + fun body() { + val params = CallRejectParams.builder().callId("call_id").statusCode(486L).build() + + val body = params._body() + + assertThat(body.statusCode()).contains(486L) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = CallRejectParams.builder().callId("call_id").build() + + val body = params._body() + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/realtime/CallServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/realtime/CallServiceAsyncTest.kt new file mode 100644 index 00000000..0a8c555e --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/realtime/CallServiceAsyncTest.kt @@ -0,0 +1,181 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.services.async.realtime + +import com.openai.TestServerExtension +import com.openai.client.okhttp.OpenAIOkHttpClientAsync +import com.openai.core.JsonValue +import com.openai.models.realtime.AudioTranscription +import com.openai.models.realtime.NoiseReductionType +import com.openai.models.realtime.RealtimeAudioConfig +import com.openai.models.realtime.RealtimeAudioConfigInput +import com.openai.models.realtime.RealtimeAudioConfigOutput +import com.openai.models.realtime.RealtimeAudioFormats +import com.openai.models.realtime.RealtimeAudioInputTurnDetection +import com.openai.models.realtime.RealtimeFunctionTool +import com.openai.models.realtime.RealtimeSessionCreateRequest +import com.openai.models.realtime.RealtimeTruncation +import com.openai.models.realtime.calls.CallAcceptParams +import com.openai.models.realtime.calls.CallReferParams +import com.openai.models.realtime.calls.CallRejectParams +import com.openai.models.responses.ResponsePrompt +import com.openai.models.responses.ToolChoiceOptions +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class CallServiceAsyncTest { + + @Test + fun accept() { + val client = + OpenAIOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val callServiceAsync = client.realtime().calls() + + val future = + callServiceAsync.accept( + CallAcceptParams.builder() + .callId("call_id") + .realtimeSessionCreateRequest( + RealtimeSessionCreateRequest.builder() + .audio( + RealtimeAudioConfig.builder() + .input( + RealtimeAudioConfigInput.builder() + .format( + RealtimeAudioFormats.AudioPcm.builder() + .rate(RealtimeAudioFormats.AudioPcm.Rate._24000) + .type( + RealtimeAudioFormats.AudioPcm.Type.AUDIO_PCM + ) + .build() + ) + .noiseReduction( + RealtimeAudioConfigInput.NoiseReduction.builder() + .type(NoiseReductionType.NEAR_FIELD) + .build() + ) + .transcription( + AudioTranscription.builder() + .language("language") + .model(AudioTranscription.Model.WHISPER_1) + .prompt("prompt") + .build() + ) + .turnDetection( + RealtimeAudioInputTurnDetection.ServerVad.builder() + .createResponse(true) + .idleTimeoutMs(5000L) + .interruptResponse(true) + .prefixPaddingMs(0L) + .silenceDurationMs(0L) + .threshold(0.0) + .build() + ) + .build() + ) + .output( + RealtimeAudioConfigOutput.builder() + .format( + RealtimeAudioFormats.AudioPcm.builder() + .rate(RealtimeAudioFormats.AudioPcm.Rate._24000) + .type( + RealtimeAudioFormats.AudioPcm.Type.AUDIO_PCM + ) + .build() + ) + .speed(0.25) + .voice(RealtimeAudioConfigOutput.Voice.ALLOY) + .build() + ) + .build() + ) + .addInclude( + RealtimeSessionCreateRequest.Include + .ITEM_INPUT_AUDIO_TRANSCRIPTION_LOGPROBS + ) + .instructions("instructions") + .maxOutputTokens(0L) + .model(RealtimeSessionCreateRequest.Model.GPT_REALTIME) + .addOutputModality(RealtimeSessionCreateRequest.OutputModality.TEXT) + .prompt( + ResponsePrompt.builder() + .id("id") + .variables( + ResponsePrompt.Variables.builder() + .putAdditionalProperty("foo", JsonValue.from("string")) + .build() + ) + .version("version") + .build() + ) + .toolChoice(ToolChoiceOptions.NONE) + .addTool( + RealtimeFunctionTool.builder() + .description("description") + .name("name") + .parameters(JsonValue.from(mapOf())) + .type(RealtimeFunctionTool.Type.FUNCTION) + .build() + ) + .tracingAuto() + .truncation(RealtimeTruncation.RealtimeTruncationStrategy.AUTO) + .build() + ) + .build() + ) + + val response = future.get() + } + + @Test + fun hangup() { + val client = + OpenAIOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val callServiceAsync = client.realtime().calls() + + val future = callServiceAsync.hangup("call_id") + + val response = future.get() + } + + @Test + fun refer() { + val client = + OpenAIOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val callServiceAsync = client.realtime().calls() + + val future = + callServiceAsync.refer( + CallReferParams.builder().callId("call_id").targetUri("tel:+14155550123").build() + ) + + val response = future.get() + } + + @Test + fun reject() { + val client = + OpenAIOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val callServiceAsync = client.realtime().calls() + + val future = + callServiceAsync.reject( + CallRejectParams.builder().callId("call_id").statusCode(486L).build() + ) + + val response = future.get() + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/realtime/CallServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/realtime/CallServiceTest.kt new file mode 100644 index 00000000..42a11755 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/realtime/CallServiceTest.kt @@ -0,0 +1,164 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.services.blocking.realtime + +import com.openai.TestServerExtension +import com.openai.client.okhttp.OpenAIOkHttpClient +import com.openai.core.JsonValue +import com.openai.models.realtime.AudioTranscription +import com.openai.models.realtime.NoiseReductionType +import com.openai.models.realtime.RealtimeAudioConfig +import com.openai.models.realtime.RealtimeAudioConfigInput +import com.openai.models.realtime.RealtimeAudioConfigOutput +import com.openai.models.realtime.RealtimeAudioFormats +import com.openai.models.realtime.RealtimeAudioInputTurnDetection +import com.openai.models.realtime.RealtimeFunctionTool +import com.openai.models.realtime.RealtimeSessionCreateRequest +import com.openai.models.realtime.RealtimeTruncation +import com.openai.models.realtime.calls.CallAcceptParams +import com.openai.models.realtime.calls.CallReferParams +import com.openai.models.realtime.calls.CallRejectParams +import com.openai.models.responses.ResponsePrompt +import com.openai.models.responses.ToolChoiceOptions +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class CallServiceTest { + + @Test + fun accept() { + val client = + OpenAIOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val callService = client.realtime().calls() + + callService.accept( + CallAcceptParams.builder() + .callId("call_id") + .realtimeSessionCreateRequest( + RealtimeSessionCreateRequest.builder() + .audio( + RealtimeAudioConfig.builder() + .input( + RealtimeAudioConfigInput.builder() + .format( + RealtimeAudioFormats.AudioPcm.builder() + .rate(RealtimeAudioFormats.AudioPcm.Rate._24000) + .type(RealtimeAudioFormats.AudioPcm.Type.AUDIO_PCM) + .build() + ) + .noiseReduction( + RealtimeAudioConfigInput.NoiseReduction.builder() + .type(NoiseReductionType.NEAR_FIELD) + .build() + ) + .transcription( + AudioTranscription.builder() + .language("language") + .model(AudioTranscription.Model.WHISPER_1) + .prompt("prompt") + .build() + ) + .turnDetection( + RealtimeAudioInputTurnDetection.ServerVad.builder() + .createResponse(true) + .idleTimeoutMs(5000L) + .interruptResponse(true) + .prefixPaddingMs(0L) + .silenceDurationMs(0L) + .threshold(0.0) + .build() + ) + .build() + ) + .output( + RealtimeAudioConfigOutput.builder() + .format( + RealtimeAudioFormats.AudioPcm.builder() + .rate(RealtimeAudioFormats.AudioPcm.Rate._24000) + .type(RealtimeAudioFormats.AudioPcm.Type.AUDIO_PCM) + .build() + ) + .speed(0.25) + .voice(RealtimeAudioConfigOutput.Voice.ALLOY) + .build() + ) + .build() + ) + .addInclude( + RealtimeSessionCreateRequest.Include + .ITEM_INPUT_AUDIO_TRANSCRIPTION_LOGPROBS + ) + .instructions("instructions") + .maxOutputTokens(0L) + .model(RealtimeSessionCreateRequest.Model.GPT_REALTIME) + .addOutputModality(RealtimeSessionCreateRequest.OutputModality.TEXT) + .prompt( + ResponsePrompt.builder() + .id("id") + .variables( + ResponsePrompt.Variables.builder() + .putAdditionalProperty("foo", JsonValue.from("string")) + .build() + ) + .version("version") + .build() + ) + .toolChoice(ToolChoiceOptions.NONE) + .addTool( + RealtimeFunctionTool.builder() + .description("description") + .name("name") + .parameters(JsonValue.from(mapOf())) + .type(RealtimeFunctionTool.Type.FUNCTION) + .build() + ) + .tracingAuto() + .truncation(RealtimeTruncation.RealtimeTruncationStrategy.AUTO) + .build() + ) + .build() + ) + } + + @Test + fun hangup() { + val client = + OpenAIOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val callService = client.realtime().calls() + + callService.hangup("call_id") + } + + @Test + fun refer() { + val client = + OpenAIOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val callService = client.realtime().calls() + + callService.refer( + CallReferParams.builder().callId("call_id").targetUri("tel:+14155550123").build() + ) + } + + @Test + fun reject() { + val client = + OpenAIOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val callService = client.realtime().calls() + + callService.reject(CallRejectParams.builder().callId("call_id").statusCode(486L).build()) + } +}