From dd24c500f029db5c1d38e9659eafb3bcd4d6fe99 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 15 Jul 2025 21:33:41 +0000 Subject: [PATCH 1/7] chore(api): update realtime specs --- .stats.yml | 4 +- .../beta/realtime/ConversationItemContent.kt | 16 +- .../realtime/ConversationItemWithReference.kt | 450 +++++++++++++++++- .../ConversationItemWithReferenceTest.kt | 12 +- .../beta/realtime/RealtimeClientEventTest.kt | 11 +- .../beta/realtime/ResponseCreateEventTest.kt | 12 +- 6 files changed, 468 insertions(+), 37 deletions(-) diff --git a/.stats.yml b/.stats.yml index 0685619d..b16a66cf 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 88 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-79dcb0ae501ac17004f50aecb112a798290ab3727fbe7c7d1b34299e38ed4f8e.yml -openapi_spec_hash: c8d54bd1ae3d704f6b6f72ffd2f876d8 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-c7dacca97e28bceff218684bb429481a70aa47aadad983ed9178bfda75ff4cd2.yml +openapi_spec_hash: 28eb1bb901ca10d2e37db4606d2bcfa7 config_hash: 167ad0ca036d0f023c78e6496b4311e8 diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/realtime/ConversationItemContent.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/realtime/ConversationItemContent.kt index 573cbea6..c74fdc98 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/realtime/ConversationItemContent.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/realtime/ConversationItemContent.kt @@ -64,7 +64,7 @@ private constructor( fun text(): Optional = text.getOptional("text") /** - * The transcript of the audio, used for `input_audio` content type. + * The transcript of the audio, used for `input_audio` and `audio` content types. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -72,7 +72,7 @@ private constructor( fun transcript(): Optional = transcript.getOptional("transcript") /** - * The content type (`input_text`, `input_audio`, `item_reference`, `text`). + * The content type (`input_text`, `input_audio`, `item_reference`, `text`, `audio`). * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -188,7 +188,7 @@ private constructor( */ fun text(text: JsonField) = apply { this.text = text } - /** The transcript of the audio, used for `input_audio` content type. */ + /** The transcript of the audio, used for `input_audio` and `audio` content types. */ fun transcript(transcript: String) = transcript(JsonField.of(transcript)) /** @@ -200,7 +200,7 @@ private constructor( */ fun transcript(transcript: JsonField) = apply { this.transcript = transcript } - /** The content type (`input_text`, `input_audio`, `item_reference`, `text`). */ + /** The content type (`input_text`, `input_audio`, `item_reference`, `text`, `audio`). */ fun type(type: Type) = type(JsonField.of(type)) /** @@ -282,7 +282,7 @@ private constructor( (if (transcript.asKnown().isPresent) 1 else 0) + (type.asKnown().getOrNull()?.validity() ?: 0) - /** The content type (`input_text`, `input_audio`, `item_reference`, `text`). */ + /** The content type (`input_text`, `input_audio`, `item_reference`, `text`, `audio`). */ class Type @JsonCreator private constructor(private val value: JsonField) : Enum { /** @@ -305,6 +305,8 @@ private constructor( @JvmField val TEXT = of("text") + @JvmField val AUDIO = of("audio") + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } @@ -314,6 +316,7 @@ private constructor( INPUT_AUDIO, ITEM_REFERENCE, TEXT, + AUDIO, } /** @@ -330,6 +333,7 @@ private constructor( INPUT_AUDIO, ITEM_REFERENCE, TEXT, + AUDIO, /** An enum member indicating that [Type] was instantiated with an unknown value. */ _UNKNOWN, } @@ -347,6 +351,7 @@ private constructor( INPUT_AUDIO -> Value.INPUT_AUDIO ITEM_REFERENCE -> Value.ITEM_REFERENCE TEXT -> Value.TEXT + AUDIO -> Value.AUDIO else -> Value._UNKNOWN } @@ -365,6 +370,7 @@ private constructor( INPUT_AUDIO -> Known.INPUT_AUDIO ITEM_REFERENCE -> Known.ITEM_REFERENCE TEXT -> Known.TEXT + AUDIO -> Known.AUDIO else -> throw OpenAIInvalidDataException("Unknown Type: $value") } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/realtime/ConversationItemWithReference.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/realtime/ConversationItemWithReference.kt index 892068a0..057095b5 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/realtime/ConversationItemWithReference.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/realtime/ConversationItemWithReference.kt @@ -25,7 +25,7 @@ private constructor( private val id: JsonField, private val arguments: JsonField, private val callId: JsonField, - private val content: JsonField>, + private val content: JsonField>, private val name: JsonField, private val object_: JsonField, private val output: JsonField, @@ -42,7 +42,7 @@ private constructor( @JsonProperty("call_id") @ExcludeMissing callId: JsonField = JsonMissing.of(), @JsonProperty("content") @ExcludeMissing - content: JsonField> = JsonMissing.of(), + content: JsonField> = JsonMissing.of(), @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), @JsonProperty("object") @ExcludeMissing object_: JsonField = JsonMissing.of(), @JsonProperty("output") @ExcludeMissing output: JsonField = JsonMissing.of(), @@ -103,7 +103,7 @@ private constructor( * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). */ - fun content(): Optional> = content.getOptional("content") + fun content(): Optional> = content.getOptional("content") /** * The name of the function being called (for `function_call` items). @@ -182,9 +182,7 @@ private constructor( * * Unlike [content], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("content") - @ExcludeMissing - fun _content(): JsonField> = content + @JsonProperty("content") @ExcludeMissing fun _content(): JsonField> = content /** * Returns the raw JSON value of [name]. @@ -255,7 +253,7 @@ private constructor( private var id: JsonField = JsonMissing.of() private var arguments: JsonField = JsonMissing.of() private var callId: JsonField = JsonMissing.of() - private var content: JsonField>? = null + private var content: JsonField>? = null private var name: JsonField = JsonMissing.of() private var object_: JsonField = JsonMissing.of() private var output: JsonField = JsonMissing.of() @@ -330,25 +328,25 @@ private constructor( * - Message items of role `user` support `input_text` and `input_audio` content * - Message items of role `assistant` support `text` content. */ - fun content(content: List) = content(JsonField.of(content)) + fun content(content: List) = content(JsonField.of(content)) /** * Sets [Builder.content] to an arbitrary JSON value. * - * You should usually call [Builder.content] with a well-typed - * `List` value instead. This method is primarily for setting the - * field to an undocumented or not yet supported value. + * You should usually call [Builder.content] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - fun content(content: JsonField>) = apply { + fun content(content: JsonField>) = apply { this.content = content.map { it.toMutableList() } } /** - * Adds a single [ConversationItemContent] to [Builder.content]. + * Adds a single [Content] to [Builder.content]. * * @throws IllegalStateException if the field was previously set to a non-list. */ - fun addContent(content: ConversationItemContent) = apply { + fun addContent(content: Content) = apply { this.content = (this.content ?: JsonField.of(mutableListOf())).also { checkKnown("content", it).add(content) @@ -517,6 +515,430 @@ private constructor( (status.asKnown().getOrNull()?.validity() ?: 0) + (type.asKnown().getOrNull()?.validity() ?: 0) + class Content + private constructor( + private val id: JsonField, + private val audio: JsonField, + private val text: JsonField, + private val transcript: JsonField, + private val type: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("audio") @ExcludeMissing audio: JsonField = JsonMissing.of(), + @JsonProperty("text") @ExcludeMissing text: JsonField = JsonMissing.of(), + @JsonProperty("transcript") + @ExcludeMissing + transcript: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + ) : this(id, audio, text, transcript, type, mutableMapOf()) + + /** + * ID of a previous conversation item to reference (for `item_reference` content types in + * `response.create` events). These can reference both client and server created items. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun id(): Optional = id.getOptional("id") + + /** + * Base64-encoded audio bytes, used for `input_audio` content type. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun audio(): Optional = audio.getOptional("audio") + + /** + * The text content, used for `input_text` and `text` content types. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun text(): Optional = text.getOptional("text") + + /** + * The transcript of the audio, used for `input_audio` content type. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun transcript(): Optional = transcript.getOptional("transcript") + + /** + * The content type (`input_text`, `input_audio`, `item_reference`, `text`). + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun type(): Optional = type.getOptional("type") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * Returns the raw JSON value of [audio]. + * + * Unlike [audio], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("audio") @ExcludeMissing fun _audio(): JsonField = audio + + /** + * Returns the raw JSON value of [text]. + * + * Unlike [text], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("text") @ExcludeMissing fun _text(): JsonField = text + + /** + * Returns the raw JSON value of [transcript]. + * + * Unlike [transcript], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("transcript") + @ExcludeMissing + fun _transcript(): JsonField = transcript + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Content]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Content]. */ + class Builder internal constructor() { + + private var id: JsonField = JsonMissing.of() + private var audio: JsonField = JsonMissing.of() + private var text: JsonField = JsonMissing.of() + private var transcript: JsonField = JsonMissing.of() + private var type: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(content: Content) = apply { + id = content.id + audio = content.audio + text = content.text + transcript = content.transcript + type = content.type + additionalProperties = content.additionalProperties.toMutableMap() + } + + /** + * ID of a previous conversation item to reference (for `item_reference` content types + * in `response.create` events). These can reference both client and server created + * items. + */ + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun id(id: JsonField) = apply { this.id = id } + + /** Base64-encoded audio bytes, used for `input_audio` content type. */ + fun audio(audio: String) = audio(JsonField.of(audio)) + + /** + * Sets [Builder.audio] to an arbitrary JSON value. + * + * You should usually call [Builder.audio] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun audio(audio: JsonField) = apply { this.audio = audio } + + /** The text content, used for `input_text` and `text` content types. */ + fun text(text: String) = text(JsonField.of(text)) + + /** + * Sets [Builder.text] to an arbitrary JSON value. + * + * You should usually call [Builder.text] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun text(text: JsonField) = apply { this.text = text } + + /** The transcript of the audio, used for `input_audio` content type. */ + fun transcript(transcript: String) = transcript(JsonField.of(transcript)) + + /** + * Sets [Builder.transcript] to an arbitrary JSON value. + * + * You should usually call [Builder.transcript] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun transcript(transcript: JsonField) = apply { this.transcript = transcript } + + /** The content type (`input_text`, `input_audio`, `item_reference`, `text`). */ + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonField) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Content]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Content = + Content(id, audio, text, transcript, type, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Content = apply { + if (validated) { + return@apply + } + + id() + audio() + text() + transcript() + type().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (id.asKnown().isPresent) 1 else 0) + + (if (audio.asKnown().isPresent) 1 else 0) + + (if (text.asKnown().isPresent) 1 else 0) + + (if (transcript.asKnown().isPresent) 1 else 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + /** The content type (`input_text`, `input_audio`, `item_reference`, `text`). */ + class Type @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val INPUT_TEXT = of("input_text") + + @JvmField val INPUT_AUDIO = of("input_audio") + + @JvmField val ITEM_REFERENCE = of("item_reference") + + @JvmField val TEXT = of("text") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + INPUT_TEXT, + INPUT_AUDIO, + ITEM_REFERENCE, + TEXT, + } + + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + INPUT_TEXT, + INPUT_AUDIO, + ITEM_REFERENCE, + TEXT, + /** An enum member indicating that [Type] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you + * want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + INPUT_TEXT -> Value.INPUT_TEXT + INPUT_AUDIO -> Value.INPUT_AUDIO + ITEM_REFERENCE -> Value.ITEM_REFERENCE + TEXT -> Value.TEXT + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + INPUT_TEXT -> Known.INPUT_TEXT + INPUT_AUDIO -> Known.INPUT_AUDIO + ITEM_REFERENCE -> Known.ITEM_REFERENCE + TEXT -> Known.TEXT + else -> throw OpenAIInvalidDataException("Unknown Type: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + OpenAIInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Type = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Content && id == other.id && audio == other.audio && text == other.text && transcript == other.transcript && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, audio, text, transcript, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Content{id=$id, audio=$audio, text=$text, transcript=$transcript, type=$type, additionalProperties=$additionalProperties}" + } + /** Identifier for the API object being returned - always `realtime.item`. */ class Object @JsonCreator private constructor(private val value: JsonField) : Enum { diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/realtime/ConversationItemWithReferenceTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/realtime/ConversationItemWithReferenceTest.kt index 43660e71..9d531b92 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/realtime/ConversationItemWithReferenceTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/realtime/ConversationItemWithReferenceTest.kt @@ -18,12 +18,12 @@ internal class ConversationItemWithReferenceTest { .arguments("arguments") .callId("call_id") .addContent( - ConversationItemContent.builder() + ConversationItemWithReference.Content.builder() .id("id") .audio("audio") .text("text") .transcript("transcript") - .type(ConversationItemContent.Type.INPUT_TEXT) + .type(ConversationItemWithReference.Content.Type.INPUT_TEXT) .build() ) .name("name") @@ -39,12 +39,12 @@ internal class ConversationItemWithReferenceTest { assertThat(conversationItemWithReference.callId()).contains("call_id") assertThat(conversationItemWithReference.content().getOrNull()) .containsExactly( - ConversationItemContent.builder() + ConversationItemWithReference.Content.builder() .id("id") .audio("audio") .text("text") .transcript("transcript") - .type(ConversationItemContent.Type.INPUT_TEXT) + .type(ConversationItemWithReference.Content.Type.INPUT_TEXT) .build() ) assertThat(conversationItemWithReference.name()).contains("name") @@ -68,12 +68,12 @@ internal class ConversationItemWithReferenceTest { .arguments("arguments") .callId("call_id") .addContent( - ConversationItemContent.builder() + ConversationItemWithReference.Content.builder() .id("id") .audio("audio") .text("text") .transcript("transcript") - .type(ConversationItemContent.Type.INPUT_TEXT) + .type(ConversationItemWithReference.Content.Type.INPUT_TEXT) .build() ) .name("name") diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/realtime/RealtimeClientEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/realtime/RealtimeClientEventTest.kt index d4fa171c..484287d4 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/realtime/RealtimeClientEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/realtime/RealtimeClientEventTest.kt @@ -441,12 +441,12 @@ internal class RealtimeClientEventTest { .arguments("arguments") .callId("call_id") .addContent( - ConversationItemContent.builder() + ConversationItemWithReference.Content.builder() .id("id") .audio("audio") .text("text") .transcript("transcript") - .type(ConversationItemContent.Type.INPUT_TEXT) + .type(ConversationItemWithReference.Content.Type.INPUT_TEXT) .build() ) .name("name") @@ -513,12 +513,15 @@ internal class RealtimeClientEventTest { .arguments("arguments") .callId("call_id") .addContent( - ConversationItemContent.builder() + ConversationItemWithReference.Content.builder() .id("id") .audio("audio") .text("text") .transcript("transcript") - .type(ConversationItemContent.Type.INPUT_TEXT) + .type( + ConversationItemWithReference.Content.Type + .INPUT_TEXT + ) .build() ) .name("name") diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/realtime/ResponseCreateEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/realtime/ResponseCreateEventTest.kt index 2d3f427d..15999401 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/realtime/ResponseCreateEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/realtime/ResponseCreateEventTest.kt @@ -24,12 +24,12 @@ internal class ResponseCreateEventTest { .arguments("arguments") .callId("call_id") .addContent( - ConversationItemContent.builder() + ConversationItemWithReference.Content.builder() .id("id") .audio("audio") .text("text") .transcript("transcript") - .type(ConversationItemContent.Type.INPUT_TEXT) + .type(ConversationItemWithReference.Content.Type.INPUT_TEXT) .build() ) .name("name") @@ -75,12 +75,12 @@ internal class ResponseCreateEventTest { .arguments("arguments") .callId("call_id") .addContent( - ConversationItemContent.builder() + ConversationItemWithReference.Content.builder() .id("id") .audio("audio") .text("text") .transcript("transcript") - .type(ConversationItemContent.Type.INPUT_TEXT) + .type(ConversationItemWithReference.Content.Type.INPUT_TEXT) .build() ) .name("name") @@ -130,12 +130,12 @@ internal class ResponseCreateEventTest { .arguments("arguments") .callId("call_id") .addContent( - ConversationItemContent.builder() + ConversationItemWithReference.Content.builder() .id("id") .audio("audio") .text("text") .transcript("transcript") - .type(ConversationItemContent.Type.INPUT_TEXT) + .type(ConversationItemWithReference.Content.Type.INPUT_TEXT) .build() ) .name("name") From e5112cdb3d411357886c334b15cc3de62e2fc9c3 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 15 Jul 2025 21:45:12 +0000 Subject: [PATCH 2/7] chore(ci): bump `actions/setup-java` to v4 --- .github/workflows/create-releases.yml | 2 +- .github/workflows/publish-sonatype.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/create-releases.yml b/.github/workflows/create-releases.yml index 0e947b41..83be2a39 100644 --- a/.github/workflows/create-releases.yml +++ b/.github/workflows/create-releases.yml @@ -24,7 +24,7 @@ jobs: - name: Set up Java if: ${{ steps.release.outputs.releases_created }} - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: temurin java-version: | diff --git a/.github/workflows/publish-sonatype.yml b/.github/workflows/publish-sonatype.yml index 8adb4c93..0765f04d 100644 --- a/.github/workflows/publish-sonatype.yml +++ b/.github/workflows/publish-sonatype.yml @@ -13,7 +13,7 @@ jobs: - uses: actions/checkout@v4 - name: Set up Java - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: temurin java-version: | From d3dd5be0c6797f7f7fb7935df27b7ad67177f6ea Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 16 Jul 2025 16:27:47 +0000 Subject: [PATCH 3/7] feat(api): manual updates --- .stats.yml | 6 +- .../StructuredChatCompletionCreateParams.kt | 22 - .../models/images/ImageEditCompletedEvent.kt | 1499 +++++++++++++++++ .../openai/models/images/ImageEditParams.kt | 336 +++- .../images/ImageEditPartialImageEvent.kt | 1001 +++++++++++ .../models/images/ImageEditStreamEvent.kt | 201 +++ .../models/images/ImageGenCompletedEvent.kt | 1499 +++++++++++++++++ .../images/ImageGenPartialImageEvent.kt | 1001 +++++++++++ .../models/images/ImageGenStreamEvent.kt | 213 +++ .../models/images/ImageGenerateParams.kt | 111 +- .../models/responses/ResponseOutputRefusal.kt | 4 +- .../com/openai/models/responses/Tool.kt | 195 ++- .../services/async/ImageServiceAsync.kt | 65 + .../services/async/ImageServiceAsyncImpl.kt | 114 ++ .../openai/services/blocking/ImageService.kt | 67 + .../services/blocking/ImageServiceImpl.kt | 104 +- .../images/ImageEditCompletedEventTest.kt | 96 ++ .../models/images/ImageEditParamsTest.kt | 6 + .../images/ImageEditPartialImageEventTest.kt | 60 + .../models/images/ImageEditStreamEventTest.kt | 146 ++ .../images/ImageGenCompletedEventTest.kt | 95 ++ .../images/ImageGenPartialImageEventTest.kt | 60 + .../models/images/ImageGenStreamEventTest.kt | 147 ++ .../models/images/ImageGenerateParamsTest.kt | 3 + .../com/openai/models/responses/ToolTest.kt | 2 + .../services/async/ImageServiceAsyncTest.kt | 74 + .../services/blocking/ImageServiceTest.kt | 74 + .../openai/example/ImageStreamingExample.java | 74 + 28 files changed, 7235 insertions(+), 40 deletions(-) create mode 100644 openai-java-core/src/main/kotlin/com/openai/models/images/ImageEditCompletedEvent.kt create mode 100644 openai-java-core/src/main/kotlin/com/openai/models/images/ImageEditPartialImageEvent.kt create mode 100644 openai-java-core/src/main/kotlin/com/openai/models/images/ImageEditStreamEvent.kt create mode 100644 openai-java-core/src/main/kotlin/com/openai/models/images/ImageGenCompletedEvent.kt create mode 100644 openai-java-core/src/main/kotlin/com/openai/models/images/ImageGenPartialImageEvent.kt create mode 100644 openai-java-core/src/main/kotlin/com/openai/models/images/ImageGenStreamEvent.kt create mode 100644 openai-java-core/src/test/kotlin/com/openai/models/images/ImageEditCompletedEventTest.kt create mode 100644 openai-java-core/src/test/kotlin/com/openai/models/images/ImageEditPartialImageEventTest.kt create mode 100644 openai-java-core/src/test/kotlin/com/openai/models/images/ImageEditStreamEventTest.kt create mode 100644 openai-java-core/src/test/kotlin/com/openai/models/images/ImageGenCompletedEventTest.kt create mode 100644 openai-java-core/src/test/kotlin/com/openai/models/images/ImageGenPartialImageEventTest.kt create mode 100644 openai-java-core/src/test/kotlin/com/openai/models/images/ImageGenStreamEventTest.kt create mode 100644 openai-java-example/src/main/java/com/openai/example/ImageStreamingExample.java diff --git a/.stats.yml b/.stats.yml index b16a66cf..e9e1048c 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 88 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-c7dacca97e28bceff218684bb429481a70aa47aadad983ed9178bfda75ff4cd2.yml -openapi_spec_hash: 28eb1bb901ca10d2e37db4606d2bcfa7 -config_hash: 167ad0ca036d0f023c78e6496b4311e8 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-670ea0d2cc44f52a87dd3cadea45632953283e0636ba30788fdbdb22a232ccac.yml +openapi_spec_hash: d8b7d38911fead545adf3e4297956410 +config_hash: 5525bda35e48ea6387c6175c4d1651fa diff --git a/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/StructuredChatCompletionCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/StructuredChatCompletionCreateParams.kt index 20eec834..8c67696f 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/StructuredChatCompletionCreateParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/StructuredChatCompletionCreateParams.kt @@ -139,28 +139,6 @@ internal constructor( paramsBuilder.addMessage(assistant) } - /** @see ChatCompletionCreateParams.Builder.addAssistantMessage */ - fun addAssistantMessage(content: ChatCompletionAssistantMessageParam.Content?) = apply { - paramsBuilder.addAssistantMessage(content) - } - - /** @see ChatCompletionCreateParams.Builder.addAssistantMessage */ - fun addAssistantMessage(content: Optional) = - apply { - paramsBuilder.addAssistantMessage(content) - } - - /** @see ChatCompletionCreateParams.Builder.addAssistantMessage */ - fun addAssistantMessage(text: String) = apply { paramsBuilder.addAssistantMessage(text) } - - /** @see ChatCompletionCreateParams.Builder.addAssistantMessageOfArrayOfContentParts */ - fun addAssistantMessageOfArrayOfContentParts( - arrayOfContentParts: - List< - ChatCompletionAssistantMessageParam.Content.ChatCompletionRequestAssistantMessageContentPart - > - ) = apply { paramsBuilder.addAssistantMessageOfArrayOfContentParts(arrayOfContentParts) } - /** @see ChatCompletionCreateParams.Builder.addMessage */ fun addMessage(tool: ChatCompletionToolMessageParam) = apply { paramsBuilder.addMessage(tool) diff --git a/openai-java-core/src/main/kotlin/com/openai/models/images/ImageEditCompletedEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/images/ImageEditCompletedEvent.kt new file mode 100644 index 00000000..65ba3a9c --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/images/ImageEditCompletedEvent.kt @@ -0,0 +1,1499 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.images + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.Enum +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.checkRequired +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import kotlin.jvm.optionals.getOrNull + +/** Emitted when image editing has completed and the final image is available. */ +class ImageEditCompletedEvent +private constructor( + private val b64Json: JsonField, + private val background: JsonField, + private val createdAt: JsonField, + private val outputFormat: JsonField, + private val quality: JsonField, + private val size: JsonField, + private val type: JsonValue, + private val usage: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("b64_json") @ExcludeMissing b64Json: JsonField = JsonMissing.of(), + @JsonProperty("background") + @ExcludeMissing + background: JsonField = JsonMissing.of(), + @JsonProperty("created_at") @ExcludeMissing createdAt: JsonField = JsonMissing.of(), + @JsonProperty("output_format") + @ExcludeMissing + outputFormat: JsonField = JsonMissing.of(), + @JsonProperty("quality") @ExcludeMissing quality: JsonField = JsonMissing.of(), + @JsonProperty("size") @ExcludeMissing size: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + @JsonProperty("usage") @ExcludeMissing usage: JsonField = JsonMissing.of(), + ) : this( + b64Json, + background, + createdAt, + outputFormat, + quality, + size, + type, + usage, + mutableMapOf(), + ) + + /** + * Base64-encoded final edited image data, suitable for rendering as an image. + * + * @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 b64Json(): String = b64Json.getRequired("b64_json") + + /** + * The background setting for the edited image. + * + * @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 background(): Background = background.getRequired("background") + + /** + * The Unix timestamp when the event was created. + * + * @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 createdAt(): Long = createdAt.getRequired("created_at") + + /** + * The output format for the edited image. + * + * @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 outputFormat(): OutputFormat = outputFormat.getRequired("output_format") + + /** + * The quality setting for the edited image. + * + * @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 quality(): Quality = quality.getRequired("quality") + + /** + * The size of the edited image. + * + * @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 size(): Size = size.getRequired("size") + + /** + * The type of the event. Always `image_edit.completed`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("image_edit.completed") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server responded + * with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * For `gpt-image-1` only, the token usage information for the image generation. + * + * @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 usage(): Usage = usage.getRequired("usage") + + /** + * Returns the raw JSON value of [b64Json]. + * + * Unlike [b64Json], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("b64_json") @ExcludeMissing fun _b64Json(): JsonField = b64Json + + /** + * Returns the raw JSON value of [background]. + * + * Unlike [background], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("background") + @ExcludeMissing + fun _background(): JsonField = background + + /** + * Returns the raw JSON value of [createdAt]. + * + * Unlike [createdAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created_at") @ExcludeMissing fun _createdAt(): JsonField = createdAt + + /** + * Returns the raw JSON value of [outputFormat]. + * + * Unlike [outputFormat], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("output_format") + @ExcludeMissing + fun _outputFormat(): JsonField = outputFormat + + /** + * Returns the raw JSON value of [quality]. + * + * Unlike [quality], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("quality") @ExcludeMissing fun _quality(): JsonField = quality + + /** + * Returns the raw JSON value of [size]. + * + * Unlike [size], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("size") @ExcludeMissing fun _size(): JsonField = size + + /** + * Returns the raw JSON value of [usage]. + * + * Unlike [usage], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("usage") @ExcludeMissing fun _usage(): JsonField = usage + + @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 [ImageEditCompletedEvent]. + * + * The following fields are required: + * ```java + * .b64Json() + * .background() + * .createdAt() + * .outputFormat() + * .quality() + * .size() + * .usage() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ImageEditCompletedEvent]. */ + class Builder internal constructor() { + + private var b64Json: JsonField? = null + private var background: JsonField? = null + private var createdAt: JsonField? = null + private var outputFormat: JsonField? = null + private var quality: JsonField? = null + private var size: JsonField? = null + private var type: JsonValue = JsonValue.from("image_edit.completed") + private var usage: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(imageEditCompletedEvent: ImageEditCompletedEvent) = apply { + b64Json = imageEditCompletedEvent.b64Json + background = imageEditCompletedEvent.background + createdAt = imageEditCompletedEvent.createdAt + outputFormat = imageEditCompletedEvent.outputFormat + quality = imageEditCompletedEvent.quality + size = imageEditCompletedEvent.size + type = imageEditCompletedEvent.type + usage = imageEditCompletedEvent.usage + additionalProperties = imageEditCompletedEvent.additionalProperties.toMutableMap() + } + + /** Base64-encoded final edited image data, suitable for rendering as an image. */ + fun b64Json(b64Json: String) = b64Json(JsonField.of(b64Json)) + + /** + * Sets [Builder.b64Json] to an arbitrary JSON value. + * + * You should usually call [Builder.b64Json] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun b64Json(b64Json: JsonField) = apply { this.b64Json = b64Json } + + /** The background setting for the edited image. */ + fun background(background: Background) = background(JsonField.of(background)) + + /** + * Sets [Builder.background] to an arbitrary JSON value. + * + * You should usually call [Builder.background] with a well-typed [Background] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun background(background: JsonField) = apply { this.background = background } + + /** The Unix timestamp when the event was created. */ + fun createdAt(createdAt: Long) = createdAt(JsonField.of(createdAt)) + + /** + * Sets [Builder.createdAt] to an arbitrary JSON value. + * + * You should usually call [Builder.createdAt] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun createdAt(createdAt: JsonField) = apply { this.createdAt = createdAt } + + /** The output format for the edited image. */ + fun outputFormat(outputFormat: OutputFormat) = outputFormat(JsonField.of(outputFormat)) + + /** + * Sets [Builder.outputFormat] to an arbitrary JSON value. + * + * You should usually call [Builder.outputFormat] with a well-typed [OutputFormat] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun outputFormat(outputFormat: JsonField) = apply { + this.outputFormat = outputFormat + } + + /** The quality setting for the edited image. */ + fun quality(quality: Quality) = quality(JsonField.of(quality)) + + /** + * Sets [Builder.quality] to an arbitrary JSON value. + * + * You should usually call [Builder.quality] with a well-typed [Quality] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun quality(quality: JsonField) = apply { this.quality = quality } + + /** The size of the edited image. */ + fun size(size: Size) = size(JsonField.of(size)) + + /** + * Sets [Builder.size] to an arbitrary JSON value. + * + * You should usually call [Builder.size] with a well-typed [Size] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun size(size: JsonField) = apply { this.size = size } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("image_edit.completed") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + /** For `gpt-image-1` only, the token usage information for the image generation. */ + fun usage(usage: Usage) = usage(JsonField.of(usage)) + + /** + * Sets [Builder.usage] to an arbitrary JSON value. + * + * You should usually call [Builder.usage] with a well-typed [Usage] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun usage(usage: JsonField) = apply { this.usage = usage } + + 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 [ImageEditCompletedEvent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .b64Json() + * .background() + * .createdAt() + * .outputFormat() + * .quality() + * .size() + * .usage() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ImageEditCompletedEvent = + ImageEditCompletedEvent( + checkRequired("b64Json", b64Json), + checkRequired("background", background), + checkRequired("createdAt", createdAt), + checkRequired("outputFormat", outputFormat), + checkRequired("quality", quality), + checkRequired("size", size), + type, + checkRequired("usage", usage), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): ImageEditCompletedEvent = apply { + if (validated) { + return@apply + } + + b64Json() + background().validate() + createdAt() + outputFormat().validate() + quality().validate() + size().validate() + _type().let { + if (it != JsonValue.from("image_edit.completed")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + usage().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (b64Json.asKnown().isPresent) 1 else 0) + + (background.asKnown().getOrNull()?.validity() ?: 0) + + (if (createdAt.asKnown().isPresent) 1 else 0) + + (outputFormat.asKnown().getOrNull()?.validity() ?: 0) + + (quality.asKnown().getOrNull()?.validity() ?: 0) + + (size.asKnown().getOrNull()?.validity() ?: 0) + + type.let { if (it == JsonValue.from("image_edit.completed")) 1 else 0 } + + (usage.asKnown().getOrNull()?.validity() ?: 0) + + /** The background setting for the edited image. */ + class Background @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val TRANSPARENT = of("transparent") + + @JvmField val OPAQUE = of("opaque") + + @JvmField val AUTO = of("auto") + + @JvmStatic fun of(value: String) = Background(JsonField.of(value)) + } + + /** An enum containing [Background]'s known values. */ + enum class Known { + TRANSPARENT, + OPAQUE, + AUTO, + } + + /** + * An enum containing [Background]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Background] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + TRANSPARENT, + OPAQUE, + AUTO, + /** + * An enum member indicating that [Background] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + TRANSPARENT -> Value.TRANSPARENT + OPAQUE -> Value.OPAQUE + AUTO -> Value.AUTO + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + TRANSPARENT -> Known.TRANSPARENT + OPAQUE -> Known.OPAQUE + AUTO -> Known.AUTO + else -> throw OpenAIInvalidDataException("Unknown Background: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): Background = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Background && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** The output format for the edited image. */ + class OutputFormat @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val PNG = of("png") + + @JvmField val WEBP = of("webp") + + @JvmField val JPEG = of("jpeg") + + @JvmStatic fun of(value: String) = OutputFormat(JsonField.of(value)) + } + + /** An enum containing [OutputFormat]'s known values. */ + enum class Known { + PNG, + WEBP, + JPEG, + } + + /** + * An enum containing [OutputFormat]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [OutputFormat] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + PNG, + WEBP, + JPEG, + /** + * An enum member indicating that [OutputFormat] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + PNG -> Value.PNG + WEBP -> Value.WEBP + JPEG -> Value.JPEG + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + PNG -> Known.PNG + WEBP -> Known.WEBP + JPEG -> Known.JPEG + else -> throw OpenAIInvalidDataException("Unknown OutputFormat: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): OutputFormat = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is OutputFormat && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** The quality setting for the edited image. */ + class Quality @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val LOW = of("low") + + @JvmField val MEDIUM = of("medium") + + @JvmField val HIGH = of("high") + + @JvmField val AUTO = of("auto") + + @JvmStatic fun of(value: String) = Quality(JsonField.of(value)) + } + + /** An enum containing [Quality]'s known values. */ + enum class Known { + LOW, + MEDIUM, + HIGH, + AUTO, + } + + /** + * An enum containing [Quality]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Quality] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + LOW, + MEDIUM, + HIGH, + AUTO, + /** An enum member indicating that [Quality] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + LOW -> Value.LOW + MEDIUM -> Value.MEDIUM + HIGH -> Value.HIGH + AUTO -> Value.AUTO + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + LOW -> Known.LOW + MEDIUM -> Known.MEDIUM + HIGH -> Known.HIGH + AUTO -> Known.AUTO + else -> throw OpenAIInvalidDataException("Unknown Quality: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): Quality = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Quality && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** The size of the edited image. */ + class Size @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val _1024X1024 = of("1024x1024") + + @JvmField val _1024X1536 = of("1024x1536") + + @JvmField val _1536X1024 = of("1536x1024") + + @JvmField val AUTO = of("auto") + + @JvmStatic fun of(value: String) = Size(JsonField.of(value)) + } + + /** An enum containing [Size]'s known values. */ + enum class Known { + _1024X1024, + _1024X1536, + _1536X1024, + AUTO, + } + + /** + * An enum containing [Size]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Size] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + _1024X1024, + _1024X1536, + _1536X1024, + AUTO, + /** An enum member indicating that [Size] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + _1024X1024 -> Value._1024X1024 + _1024X1536 -> Value._1024X1536 + _1536X1024 -> Value._1536X1024 + AUTO -> Value.AUTO + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + _1024X1024 -> Known._1024X1024 + _1024X1536 -> Known._1024X1536 + _1536X1024 -> Known._1536X1024 + AUTO -> Known.AUTO + else -> throw OpenAIInvalidDataException("Unknown Size: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): Size = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Size && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** For `gpt-image-1` only, the token usage information for the image generation. */ + class Usage + private constructor( + private val inputTokens: JsonField, + private val inputTokensDetails: JsonField, + private val outputTokens: JsonField, + private val totalTokens: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("input_tokens") + @ExcludeMissing + inputTokens: JsonField = JsonMissing.of(), + @JsonProperty("input_tokens_details") + @ExcludeMissing + inputTokensDetails: JsonField = JsonMissing.of(), + @JsonProperty("output_tokens") + @ExcludeMissing + outputTokens: JsonField = JsonMissing.of(), + @JsonProperty("total_tokens") + @ExcludeMissing + totalTokens: JsonField = JsonMissing.of(), + ) : this(inputTokens, inputTokensDetails, outputTokens, totalTokens, mutableMapOf()) + + /** + * The number of tokens (images and text) in the input prompt. + * + * @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 inputTokens(): Long = inputTokens.getRequired("input_tokens") + + /** + * The input tokens detailed information for the image generation. + * + * @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 inputTokensDetails(): InputTokensDetails = + inputTokensDetails.getRequired("input_tokens_details") + + /** + * The number of image tokens in the output image. + * + * @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 outputTokens(): Long = outputTokens.getRequired("output_tokens") + + /** + * The total number of tokens (images and text) used for the image generation. + * + * @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 totalTokens(): Long = totalTokens.getRequired("total_tokens") + + /** + * Returns the raw JSON value of [inputTokens]. + * + * Unlike [inputTokens], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("input_tokens") + @ExcludeMissing + fun _inputTokens(): JsonField = inputTokens + + /** + * Returns the raw JSON value of [inputTokensDetails]. + * + * Unlike [inputTokensDetails], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("input_tokens_details") + @ExcludeMissing + fun _inputTokensDetails(): JsonField = inputTokensDetails + + /** + * Returns the raw JSON value of [outputTokens]. + * + * Unlike [outputTokens], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("output_tokens") + @ExcludeMissing + fun _outputTokens(): JsonField = outputTokens + + /** + * Returns the raw JSON value of [totalTokens]. + * + * Unlike [totalTokens], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("total_tokens") + @ExcludeMissing + fun _totalTokens(): JsonField = totalTokens + + @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 [Usage]. + * + * The following fields are required: + * ```java + * .inputTokens() + * .inputTokensDetails() + * .outputTokens() + * .totalTokens() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Usage]. */ + class Builder internal constructor() { + + private var inputTokens: JsonField? = null + private var inputTokensDetails: JsonField? = null + private var outputTokens: JsonField? = null + private var totalTokens: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(usage: Usage) = apply { + inputTokens = usage.inputTokens + inputTokensDetails = usage.inputTokensDetails + outputTokens = usage.outputTokens + totalTokens = usage.totalTokens + additionalProperties = usage.additionalProperties.toMutableMap() + } + + /** The number of tokens (images and text) in the input prompt. */ + fun inputTokens(inputTokens: Long) = inputTokens(JsonField.of(inputTokens)) + + /** + * Sets [Builder.inputTokens] to an arbitrary JSON value. + * + * You should usually call [Builder.inputTokens] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun inputTokens(inputTokens: JsonField) = apply { this.inputTokens = inputTokens } + + /** The input tokens detailed information for the image generation. */ + fun inputTokensDetails(inputTokensDetails: InputTokensDetails) = + inputTokensDetails(JsonField.of(inputTokensDetails)) + + /** + * Sets [Builder.inputTokensDetails] to an arbitrary JSON value. + * + * You should usually call [Builder.inputTokensDetails] with a well-typed + * [InputTokensDetails] value instead. This method is primarily for setting the field to + * an undocumented or not yet supported value. + */ + fun inputTokensDetails(inputTokensDetails: JsonField) = apply { + this.inputTokensDetails = inputTokensDetails + } + + /** The number of image tokens in the output image. */ + fun outputTokens(outputTokens: Long) = outputTokens(JsonField.of(outputTokens)) + + /** + * Sets [Builder.outputTokens] to an arbitrary JSON value. + * + * You should usually call [Builder.outputTokens] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun outputTokens(outputTokens: JsonField) = apply { + this.outputTokens = outputTokens + } + + /** The total number of tokens (images and text) used for the image generation. */ + fun totalTokens(totalTokens: Long) = totalTokens(JsonField.of(totalTokens)) + + /** + * Sets [Builder.totalTokens] to an arbitrary JSON value. + * + * You should usually call [Builder.totalTokens] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun totalTokens(totalTokens: JsonField) = apply { this.totalTokens = totalTokens } + + 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 [Usage]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .inputTokens() + * .inputTokensDetails() + * .outputTokens() + * .totalTokens() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Usage = + Usage( + checkRequired("inputTokens", inputTokens), + checkRequired("inputTokensDetails", inputTokensDetails), + checkRequired("outputTokens", outputTokens), + checkRequired("totalTokens", totalTokens), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Usage = apply { + if (validated) { + return@apply + } + + inputTokens() + inputTokensDetails().validate() + outputTokens() + totalTokens() + 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 (inputTokens.asKnown().isPresent) 1 else 0) + + (inputTokensDetails.asKnown().getOrNull()?.validity() ?: 0) + + (if (outputTokens.asKnown().isPresent) 1 else 0) + + (if (totalTokens.asKnown().isPresent) 1 else 0) + + /** The input tokens detailed information for the image generation. */ + class InputTokensDetails + private constructor( + private val imageTokens: JsonField, + private val textTokens: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("image_tokens") + @ExcludeMissing + imageTokens: JsonField = JsonMissing.of(), + @JsonProperty("text_tokens") + @ExcludeMissing + textTokens: JsonField = JsonMissing.of(), + ) : this(imageTokens, textTokens, mutableMapOf()) + + /** + * The number of image tokens in the input prompt. + * + * @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 imageTokens(): Long = imageTokens.getRequired("image_tokens") + + /** + * The number of text tokens in the input prompt. + * + * @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 textTokens(): Long = textTokens.getRequired("text_tokens") + + /** + * Returns the raw JSON value of [imageTokens]. + * + * Unlike [imageTokens], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("image_tokens") + @ExcludeMissing + fun _imageTokens(): JsonField = imageTokens + + /** + * Returns the raw JSON value of [textTokens]. + * + * Unlike [textTokens], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("text_tokens") + @ExcludeMissing + fun _textTokens(): JsonField = textTokens + + @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 [InputTokensDetails]. + * + * The following fields are required: + * ```java + * .imageTokens() + * .textTokens() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InputTokensDetails]. */ + class Builder internal constructor() { + + private var imageTokens: JsonField? = null + private var textTokens: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(inputTokensDetails: InputTokensDetails) = apply { + imageTokens = inputTokensDetails.imageTokens + textTokens = inputTokensDetails.textTokens + additionalProperties = inputTokensDetails.additionalProperties.toMutableMap() + } + + /** The number of image tokens in the input prompt. */ + fun imageTokens(imageTokens: Long) = imageTokens(JsonField.of(imageTokens)) + + /** + * Sets [Builder.imageTokens] to an arbitrary JSON value. + * + * You should usually call [Builder.imageTokens] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun imageTokens(imageTokens: JsonField) = apply { + this.imageTokens = imageTokens + } + + /** The number of text tokens in the input prompt. */ + fun textTokens(textTokens: Long) = textTokens(JsonField.of(textTokens)) + + /** + * Sets [Builder.textTokens] to an arbitrary JSON value. + * + * You should usually call [Builder.textTokens] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun textTokens(textTokens: JsonField) = apply { this.textTokens = textTokens } + + 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 [InputTokensDetails]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .imageTokens() + * .textTokens() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): InputTokensDetails = + InputTokensDetails( + checkRequired("imageTokens", imageTokens), + checkRequired("textTokens", textTokens), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): InputTokensDetails = apply { + if (validated) { + return@apply + } + + imageTokens() + textTokens() + 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 (imageTokens.asKnown().isPresent) 1 else 0) + + (if (textTokens.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is InputTokensDetails && imageTokens == other.imageTokens && textTokens == other.textTokens && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(imageTokens, textTokens, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "InputTokensDetails{imageTokens=$imageTokens, textTokens=$textTokens, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Usage && inputTokens == other.inputTokens && inputTokensDetails == other.inputTokensDetails && outputTokens == other.outputTokens && totalTokens == other.totalTokens && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(inputTokens, inputTokensDetails, outputTokens, totalTokens, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Usage{inputTokens=$inputTokens, inputTokensDetails=$inputTokensDetails, outputTokens=$outputTokens, totalTokens=$totalTokens, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ImageEditCompletedEvent && b64Json == other.b64Json && background == other.background && createdAt == other.createdAt && outputFormat == other.outputFormat && quality == other.quality && size == other.size && type == other.type && usage == other.usage && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(b64Json, background, createdAt, outputFormat, quality, size, type, usage, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ImageEditCompletedEvent{b64Json=$b64Json, background=$background, createdAt=$createdAt, outputFormat=$outputFormat, quality=$quality, size=$size, type=$type, usage=$usage, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/images/ImageEditParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/images/ImageEditParams.kt index 5e1650b5..6872d5ee 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/images/ImageEditParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/images/ImageEditParams.kt @@ -82,6 +82,16 @@ private constructor( */ fun background(): Optional = body.background() + /** + * Control how much effort the model will exert to match the style and features, especially + * facial features, of input images. This parameter is only supported for `gpt-image-1`. + * Supports `high` and `low`. Defaults to `low`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun inputFidelity(): Optional = body.inputFidelity() + /** * An additional image whose fully transparent areas (e.g. where alpha is zero) indicate where * `image` should be edited. If there are multiple images provided, the mask will be applied on @@ -128,6 +138,16 @@ private constructor( */ fun outputFormat(): Optional = body.outputFormat() + /** + * The number of partial images to generate. This parameter is used for streaming responses that + * return partial images. Value must be between 0 and 3. When set to 0, the response will be a + * single image sent in one streaming event. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun partialImages(): Optional = body.partialImages() + /** * The quality of the image that will be generated. `high`, `medium` and `low` are only * supported for `gpt-image-1`. `dall-e-2` only supports `standard` quality. Defaults to `auto`. @@ -188,6 +208,14 @@ private constructor( */ fun _background(): MultipartField = body._background() + /** + * Returns the raw multipart value of [inputFidelity]. + * + * Unlike [inputFidelity], this method doesn't throw if the multipart field has an unexpected + * type. + */ + fun _inputFidelity(): MultipartField = body._inputFidelity() + /** * Returns the raw multipart value of [mask]. * @@ -225,6 +253,14 @@ private constructor( */ fun _outputFormat(): MultipartField = body._outputFormat() + /** + * Returns the raw multipart value of [partialImages]. + * + * Unlike [partialImages], this method doesn't throw if the multipart field has an unexpected + * type. + */ + fun _partialImages(): MultipartField = body._partialImages() + /** * Returns the raw multipart value of [quality]. * @@ -296,8 +332,8 @@ private constructor( * - [image] * - [prompt] * - [background] + * - [inputFidelity] * - [mask] - * - [model] * - etc. */ fun body(body: Body) = apply { this.body = body.toBuilder() } @@ -390,6 +426,30 @@ private constructor( body.background(background) } + /** + * Control how much effort the model will exert to match the style and features, especially + * facial features, of input images. This parameter is only supported for `gpt-image-1`. + * Supports `high` and `low`. Defaults to `low`. + */ + fun inputFidelity(inputFidelity: InputFidelity?) = apply { + body.inputFidelity(inputFidelity) + } + + /** Alias for calling [Builder.inputFidelity] with `inputFidelity.orElse(null)`. */ + fun inputFidelity(inputFidelity: Optional) = + inputFidelity(inputFidelity.getOrNull()) + + /** + * Sets [Builder.inputFidelity] to an arbitrary multipart value. + * + * You should usually call [Builder.inputFidelity] with a well-typed [InputFidelity] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun inputFidelity(inputFidelity: MultipartField) = apply { + body.inputFidelity(inputFidelity) + } + /** * An additional image whose fully transparent areas (e.g. where alpha is zero) indicate * where `image` should be edited. If there are multiple images provided, the mask will be @@ -522,6 +582,34 @@ private constructor( body.outputFormat(outputFormat) } + /** + * The number of partial images to generate. This parameter is used for streaming responses + * that return partial images. Value must be between 0 and 3. When set to 0, the response + * will be a single image sent in one streaming event. + */ + fun partialImages(partialImages: Long?) = apply { body.partialImages(partialImages) } + + /** + * Alias for [Builder.partialImages]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun partialImages(partialImages: Long) = partialImages(partialImages as Long?) + + /** Alias for calling [Builder.partialImages] with `partialImages.orElse(null)`. */ + fun partialImages(partialImages: Optional) = partialImages(partialImages.getOrNull()) + + /** + * Sets [Builder.partialImages] to an arbitrary multipart value. + * + * You should usually call [Builder.partialImages] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun partialImages(partialImages: MultipartField) = apply { + body.partialImages(partialImages) + } + /** * The quality of the image that will be generated. `high`, `medium` and `low` are only * supported for `gpt-image-1`. `dall-e-2` only supports `standard` quality. Defaults to @@ -718,11 +806,13 @@ private constructor( "image" to _image(), "prompt" to _prompt(), "background" to _background(), + "input_fidelity" to _inputFidelity(), "mask" to _mask(), "model" to _model(), "n" to _n(), "output_compression" to _outputCompression(), "output_format" to _outputFormat(), + "partial_images" to _partialImages(), "quality" to _quality(), "response_format" to _responseFormat(), "size" to _size(), @@ -739,11 +829,13 @@ private constructor( private val image: MultipartField, private val prompt: MultipartField, private val background: MultipartField, + private val inputFidelity: MultipartField, private val mask: MultipartField, private val model: MultipartField, private val n: MultipartField, private val outputCompression: MultipartField, private val outputFormat: MultipartField, + private val partialImages: MultipartField, private val quality: MultipartField, private val responseFormat: MultipartField, private val size: MultipartField, @@ -787,6 +879,17 @@ private constructor( */ fun background(): Optional = background.value.getOptional("background") + /** + * Control how much effort the model will exert to match the style and features, especially + * facial features, of input images. This parameter is only supported for `gpt-image-1`. + * Supports `high` and `low`. Defaults to `low`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun inputFidelity(): Optional = + inputFidelity.value.getOptional("input_fidelity") + /** * An additional image whose fully transparent areas (e.g. where alpha is zero) indicate * where `image` should be edited. If there are multiple images provided, the mask will be @@ -834,6 +937,16 @@ private constructor( */ fun outputFormat(): Optional = outputFormat.value.getOptional("output_format") + /** + * The number of partial images to generate. This parameter is used for streaming responses + * that return partial images. Value must be between 0 and 3. When set to 0, the response + * will be a single image sent in one streaming event. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun partialImages(): Optional = partialImages.value.getOptional("partial_images") + /** * The quality of the image that will be generated. `high`, `medium` and `low` are only * supported for `gpt-image-1`. `dall-e-2` only supports `standard` quality. Defaults to @@ -900,6 +1013,16 @@ private constructor( @ExcludeMissing fun _background(): MultipartField = background + /** + * Returns the raw multipart value of [inputFidelity]. + * + * Unlike [inputFidelity], this method doesn't throw if the multipart field has an + * unexpected type. + */ + @JsonProperty("input_fidelity") + @ExcludeMissing + fun _inputFidelity(): MultipartField = inputFidelity + /** * Returns the raw multipart value of [mask]. * @@ -941,6 +1064,16 @@ private constructor( @ExcludeMissing fun _outputFormat(): MultipartField = outputFormat + /** + * Returns the raw multipart value of [partialImages]. + * + * Unlike [partialImages], this method doesn't throw if the multipart field has an + * unexpected type. + */ + @JsonProperty("partial_images") + @ExcludeMissing + fun _partialImages(): MultipartField = partialImages + /** * Returns the raw multipart value of [quality]. * @@ -995,11 +1128,13 @@ private constructor( private var image: MultipartField? = null private var prompt: MultipartField? = null private var background: MultipartField = MultipartField.of(null) + private var inputFidelity: MultipartField = MultipartField.of(null) private var mask: MultipartField = MultipartField.of(null) private var model: MultipartField = MultipartField.of(null) private var n: MultipartField = MultipartField.of(null) private var outputCompression: MultipartField = MultipartField.of(null) private var outputFormat: MultipartField = MultipartField.of(null) + private var partialImages: MultipartField = MultipartField.of(null) private var quality: MultipartField = MultipartField.of(null) private var responseFormat: MultipartField = MultipartField.of(null) private var size: MultipartField = MultipartField.of(null) @@ -1010,11 +1145,13 @@ private constructor( image = body.image prompt = body.prompt background = body.background + inputFidelity = body.inputFidelity mask = body.mask model = body.model n = body.n outputCompression = body.outputCompression outputFormat = body.outputFormat + partialImages = body.partialImages quality = body.quality responseFormat = body.responseFormat size = body.size @@ -1116,6 +1253,29 @@ private constructor( this.background = background } + /** + * Control how much effort the model will exert to match the style and features, + * especially facial features, of input images. This parameter is only supported for + * `gpt-image-1`. Supports `high` and `low`. Defaults to `low`. + */ + fun inputFidelity(inputFidelity: InputFidelity?) = + inputFidelity(MultipartField.of(inputFidelity)) + + /** Alias for calling [Builder.inputFidelity] with `inputFidelity.orElse(null)`. */ + fun inputFidelity(inputFidelity: Optional) = + inputFidelity(inputFidelity.getOrNull()) + + /** + * Sets [Builder.inputFidelity] to an arbitrary multipart value. + * + * You should usually call [Builder.inputFidelity] with a well-typed [InputFidelity] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun inputFidelity(inputFidelity: MultipartField) = apply { + this.inputFidelity = inputFidelity + } + /** * An additional image whose fully transparent areas (e.g. where alpha is zero) indicate * where `image` should be edited. If there are multiple images provided, the mask will @@ -1261,6 +1421,36 @@ private constructor( this.outputFormat = outputFormat } + /** + * The number of partial images to generate. This parameter is used for streaming + * responses that return partial images. Value must be between 0 and 3. When set to 0, + * the response will be a single image sent in one streaming event. + */ + fun partialImages(partialImages: Long?) = + partialImages(MultipartField.of(partialImages)) + + /** + * Alias for [Builder.partialImages]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun partialImages(partialImages: Long) = partialImages(partialImages as Long?) + + /** Alias for calling [Builder.partialImages] with `partialImages.orElse(null)`. */ + fun partialImages(partialImages: Optional) = + partialImages(partialImages.getOrNull()) + + /** + * Sets [Builder.partialImages] to an arbitrary multipart value. + * + * You should usually call [Builder.partialImages] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun partialImages(partialImages: MultipartField) = apply { + this.partialImages = partialImages + } + /** * The quality of the image that will be generated. `high`, `medium` and `low` are only * supported for `gpt-image-1`. `dall-e-2` only supports `standard` quality. Defaults to @@ -1357,11 +1547,13 @@ private constructor( checkRequired("image", image), checkRequired("prompt", prompt), background, + inputFidelity, mask, model, n, outputCompression, outputFormat, + partialImages, quality, responseFormat, size, @@ -1379,11 +1571,13 @@ private constructor( image().validate() prompt() background().ifPresent { it.validate() } + inputFidelity().ifPresent { it.validate() } mask() model().ifPresent { it.validate() } n() outputCompression() outputFormat().ifPresent { it.validate() } + partialImages() quality().ifPresent { it.validate() } responseFormat().ifPresent { it.validate() } size().ifPresent { it.validate() } @@ -1404,17 +1598,17 @@ private constructor( return true } - return /* spotless:off */ other is Body && image == other.image && prompt == other.prompt && background == other.background && mask == other.mask && model == other.model && n == other.n && outputCompression == other.outputCompression && outputFormat == other.outputFormat && quality == other.quality && responseFormat == other.responseFormat && size == other.size && user == other.user /* spotless:on */ + return /* spotless:off */ other is Body && image == other.image && prompt == other.prompt && background == other.background && inputFidelity == other.inputFidelity && mask == other.mask && model == other.model && n == other.n && outputCompression == other.outputCompression && outputFormat == other.outputFormat && partialImages == other.partialImages && quality == other.quality && responseFormat == other.responseFormat && size == other.size && user == other.user /* spotless:on */ } /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(image, prompt, background, mask, model, n, outputCompression, outputFormat, quality, responseFormat, size, user) } + private val hashCode: Int by lazy { Objects.hash(image, prompt, background, inputFidelity, mask, model, n, outputCompression, outputFormat, partialImages, quality, responseFormat, size, user) } /* spotless:on */ override fun hashCode(): Int = hashCode override fun toString() = - "Body{image=$image, prompt=$prompt, background=$background, mask=$mask, model=$model, n=$n, outputCompression=$outputCompression, outputFormat=$outputFormat, quality=$quality, responseFormat=$responseFormat, size=$size, user=$user}" + "Body{image=$image, prompt=$prompt, background=$background, inputFidelity=$inputFidelity, mask=$mask, model=$model, n=$n, outputCompression=$outputCompression, outputFormat=$outputFormat, partialImages=$partialImages, quality=$quality, responseFormat=$responseFormat, size=$size, user=$user}" } /** @@ -1738,6 +1932,140 @@ private constructor( override fun toString() = value.toString() } + /** + * Control how much effort the model will exert to match the style and features, especially + * facial features, of input images. This parameter is only supported for `gpt-image-1`. + * Supports `high` and `low`. Defaults to `low`. + */ + class InputFidelity @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val HIGH = of("high") + + @JvmField val LOW = of("low") + + @JvmStatic fun of(value: String) = InputFidelity(JsonField.of(value)) + } + + /** An enum containing [InputFidelity]'s known values. */ + enum class Known { + HIGH, + LOW, + } + + /** + * An enum containing [InputFidelity]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [InputFidelity] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + HIGH, + LOW, + /** + * An enum member indicating that [InputFidelity] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + HIGH -> Value.HIGH + LOW -> Value.LOW + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + HIGH -> Known.HIGH + LOW -> Known.LOW + else -> throw OpenAIInvalidDataException("Unknown InputFidelity: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): InputFidelity = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is InputFidelity && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + /** * The format in which the generated images are returned. This parameter is only supported for * `gpt-image-1`. Must be one of `png`, `jpeg`, or `webp`. The default value is `png`. diff --git a/openai-java-core/src/main/kotlin/com/openai/models/images/ImageEditPartialImageEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/images/ImageEditPartialImageEvent.kt new file mode 100644 index 00000000..a0c6bcb2 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/images/ImageEditPartialImageEvent.kt @@ -0,0 +1,1001 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.images + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.Enum +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.checkRequired +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import kotlin.jvm.optionals.getOrNull + +/** Emitted when a partial image is available during image editing streaming. */ +class ImageEditPartialImageEvent +private constructor( + private val b64Json: JsonField, + private val background: JsonField, + private val createdAt: JsonField, + private val outputFormat: JsonField, + private val partialImageIndex: JsonField, + private val quality: JsonField, + private val size: JsonField, + private val type: JsonValue, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("b64_json") @ExcludeMissing b64Json: JsonField = JsonMissing.of(), + @JsonProperty("background") + @ExcludeMissing + background: JsonField = JsonMissing.of(), + @JsonProperty("created_at") @ExcludeMissing createdAt: JsonField = JsonMissing.of(), + @JsonProperty("output_format") + @ExcludeMissing + outputFormat: JsonField = JsonMissing.of(), + @JsonProperty("partial_image_index") + @ExcludeMissing + partialImageIndex: JsonField = JsonMissing.of(), + @JsonProperty("quality") @ExcludeMissing quality: JsonField = JsonMissing.of(), + @JsonProperty("size") @ExcludeMissing size: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + ) : this( + b64Json, + background, + createdAt, + outputFormat, + partialImageIndex, + quality, + size, + type, + mutableMapOf(), + ) + + /** + * Base64-encoded partial image data, suitable for rendering as an image. + * + * @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 b64Json(): String = b64Json.getRequired("b64_json") + + /** + * The background setting for the requested edited image. + * + * @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 background(): Background = background.getRequired("background") + + /** + * The Unix timestamp when the event was created. + * + * @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 createdAt(): Long = createdAt.getRequired("created_at") + + /** + * The output format for the requested edited image. + * + * @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 outputFormat(): OutputFormat = outputFormat.getRequired("output_format") + + /** + * 0-based index for the partial image (streaming). + * + * @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 partialImageIndex(): Long = partialImageIndex.getRequired("partial_image_index") + + /** + * The quality setting for the requested edited image. + * + * @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 quality(): Quality = quality.getRequired("quality") + + /** + * The size of the requested edited image. + * + * @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 size(): Size = size.getRequired("size") + + /** + * The type of the event. Always `image_edit.partial_image`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("image_edit.partial_image") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server responded + * with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * Returns the raw JSON value of [b64Json]. + * + * Unlike [b64Json], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("b64_json") @ExcludeMissing fun _b64Json(): JsonField = b64Json + + /** + * Returns the raw JSON value of [background]. + * + * Unlike [background], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("background") + @ExcludeMissing + fun _background(): JsonField = background + + /** + * Returns the raw JSON value of [createdAt]. + * + * Unlike [createdAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created_at") @ExcludeMissing fun _createdAt(): JsonField = createdAt + + /** + * Returns the raw JSON value of [outputFormat]. + * + * Unlike [outputFormat], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("output_format") + @ExcludeMissing + fun _outputFormat(): JsonField = outputFormat + + /** + * Returns the raw JSON value of [partialImageIndex]. + * + * Unlike [partialImageIndex], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("partial_image_index") + @ExcludeMissing + fun _partialImageIndex(): JsonField = partialImageIndex + + /** + * Returns the raw JSON value of [quality]. + * + * Unlike [quality], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("quality") @ExcludeMissing fun _quality(): JsonField = quality + + /** + * Returns the raw JSON value of [size]. + * + * Unlike [size], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("size") @ExcludeMissing fun _size(): JsonField = size + + @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 [ImageEditPartialImageEvent]. + * + * The following fields are required: + * ```java + * .b64Json() + * .background() + * .createdAt() + * .outputFormat() + * .partialImageIndex() + * .quality() + * .size() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ImageEditPartialImageEvent]. */ + class Builder internal constructor() { + + private var b64Json: JsonField? = null + private var background: JsonField? = null + private var createdAt: JsonField? = null + private var outputFormat: JsonField? = null + private var partialImageIndex: JsonField? = null + private var quality: JsonField? = null + private var size: JsonField? = null + private var type: JsonValue = JsonValue.from("image_edit.partial_image") + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(imageEditPartialImageEvent: ImageEditPartialImageEvent) = apply { + b64Json = imageEditPartialImageEvent.b64Json + background = imageEditPartialImageEvent.background + createdAt = imageEditPartialImageEvent.createdAt + outputFormat = imageEditPartialImageEvent.outputFormat + partialImageIndex = imageEditPartialImageEvent.partialImageIndex + quality = imageEditPartialImageEvent.quality + size = imageEditPartialImageEvent.size + type = imageEditPartialImageEvent.type + additionalProperties = imageEditPartialImageEvent.additionalProperties.toMutableMap() + } + + /** Base64-encoded partial image data, suitable for rendering as an image. */ + fun b64Json(b64Json: String) = b64Json(JsonField.of(b64Json)) + + /** + * Sets [Builder.b64Json] to an arbitrary JSON value. + * + * You should usually call [Builder.b64Json] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun b64Json(b64Json: JsonField) = apply { this.b64Json = b64Json } + + /** The background setting for the requested edited image. */ + fun background(background: Background) = background(JsonField.of(background)) + + /** + * Sets [Builder.background] to an arbitrary JSON value. + * + * You should usually call [Builder.background] with a well-typed [Background] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun background(background: JsonField) = apply { this.background = background } + + /** The Unix timestamp when the event was created. */ + fun createdAt(createdAt: Long) = createdAt(JsonField.of(createdAt)) + + /** + * Sets [Builder.createdAt] to an arbitrary JSON value. + * + * You should usually call [Builder.createdAt] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun createdAt(createdAt: JsonField) = apply { this.createdAt = createdAt } + + /** The output format for the requested edited image. */ + fun outputFormat(outputFormat: OutputFormat) = outputFormat(JsonField.of(outputFormat)) + + /** + * Sets [Builder.outputFormat] to an arbitrary JSON value. + * + * You should usually call [Builder.outputFormat] with a well-typed [OutputFormat] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun outputFormat(outputFormat: JsonField) = apply { + this.outputFormat = outputFormat + } + + /** 0-based index for the partial image (streaming). */ + fun partialImageIndex(partialImageIndex: Long) = + partialImageIndex(JsonField.of(partialImageIndex)) + + /** + * Sets [Builder.partialImageIndex] to an arbitrary JSON value. + * + * You should usually call [Builder.partialImageIndex] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun partialImageIndex(partialImageIndex: JsonField) = apply { + this.partialImageIndex = partialImageIndex + } + + /** The quality setting for the requested edited image. */ + fun quality(quality: Quality) = quality(JsonField.of(quality)) + + /** + * Sets [Builder.quality] to an arbitrary JSON value. + * + * You should usually call [Builder.quality] with a well-typed [Quality] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun quality(quality: JsonField) = apply { this.quality = quality } + + /** The size of the requested edited image. */ + fun size(size: Size) = size(JsonField.of(size)) + + /** + * Sets [Builder.size] to an arbitrary JSON value. + * + * You should usually call [Builder.size] with a well-typed [Size] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun size(size: JsonField) = apply { this.size = size } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("image_edit.partial_image") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [ImageEditPartialImageEvent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .b64Json() + * .background() + * .createdAt() + * .outputFormat() + * .partialImageIndex() + * .quality() + * .size() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ImageEditPartialImageEvent = + ImageEditPartialImageEvent( + checkRequired("b64Json", b64Json), + checkRequired("background", background), + checkRequired("createdAt", createdAt), + checkRequired("outputFormat", outputFormat), + checkRequired("partialImageIndex", partialImageIndex), + checkRequired("quality", quality), + checkRequired("size", size), + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): ImageEditPartialImageEvent = apply { + if (validated) { + return@apply + } + + b64Json() + background().validate() + createdAt() + outputFormat().validate() + partialImageIndex() + quality().validate() + size().validate() + _type().let { + if (it != JsonValue.from("image_edit.partial_image")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (b64Json.asKnown().isPresent) 1 else 0) + + (background.asKnown().getOrNull()?.validity() ?: 0) + + (if (createdAt.asKnown().isPresent) 1 else 0) + + (outputFormat.asKnown().getOrNull()?.validity() ?: 0) + + (if (partialImageIndex.asKnown().isPresent) 1 else 0) + + (quality.asKnown().getOrNull()?.validity() ?: 0) + + (size.asKnown().getOrNull()?.validity() ?: 0) + + type.let { if (it == JsonValue.from("image_edit.partial_image")) 1 else 0 } + + /** The background setting for the requested edited image. */ + class Background @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val TRANSPARENT = of("transparent") + + @JvmField val OPAQUE = of("opaque") + + @JvmField val AUTO = of("auto") + + @JvmStatic fun of(value: String) = Background(JsonField.of(value)) + } + + /** An enum containing [Background]'s known values. */ + enum class Known { + TRANSPARENT, + OPAQUE, + AUTO, + } + + /** + * An enum containing [Background]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Background] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + TRANSPARENT, + OPAQUE, + AUTO, + /** + * An enum member indicating that [Background] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + TRANSPARENT -> Value.TRANSPARENT + OPAQUE -> Value.OPAQUE + AUTO -> Value.AUTO + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + TRANSPARENT -> Known.TRANSPARENT + OPAQUE -> Known.OPAQUE + AUTO -> Known.AUTO + else -> throw OpenAIInvalidDataException("Unknown Background: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): Background = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Background && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** The output format for the requested edited image. */ + class OutputFormat @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val PNG = of("png") + + @JvmField val WEBP = of("webp") + + @JvmField val JPEG = of("jpeg") + + @JvmStatic fun of(value: String) = OutputFormat(JsonField.of(value)) + } + + /** An enum containing [OutputFormat]'s known values. */ + enum class Known { + PNG, + WEBP, + JPEG, + } + + /** + * An enum containing [OutputFormat]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [OutputFormat] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + PNG, + WEBP, + JPEG, + /** + * An enum member indicating that [OutputFormat] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + PNG -> Value.PNG + WEBP -> Value.WEBP + JPEG -> Value.JPEG + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + PNG -> Known.PNG + WEBP -> Known.WEBP + JPEG -> Known.JPEG + else -> throw OpenAIInvalidDataException("Unknown OutputFormat: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): OutputFormat = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is OutputFormat && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** The quality setting for the requested edited image. */ + class Quality @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val LOW = of("low") + + @JvmField val MEDIUM = of("medium") + + @JvmField val HIGH = of("high") + + @JvmField val AUTO = of("auto") + + @JvmStatic fun of(value: String) = Quality(JsonField.of(value)) + } + + /** An enum containing [Quality]'s known values. */ + enum class Known { + LOW, + MEDIUM, + HIGH, + AUTO, + } + + /** + * An enum containing [Quality]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Quality] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + LOW, + MEDIUM, + HIGH, + AUTO, + /** An enum member indicating that [Quality] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + LOW -> Value.LOW + MEDIUM -> Value.MEDIUM + HIGH -> Value.HIGH + AUTO -> Value.AUTO + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + LOW -> Known.LOW + MEDIUM -> Known.MEDIUM + HIGH -> Known.HIGH + AUTO -> Known.AUTO + else -> throw OpenAIInvalidDataException("Unknown Quality: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): Quality = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Quality && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** The size of the requested edited image. */ + class Size @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val _1024X1024 = of("1024x1024") + + @JvmField val _1024X1536 = of("1024x1536") + + @JvmField val _1536X1024 = of("1536x1024") + + @JvmField val AUTO = of("auto") + + @JvmStatic fun of(value: String) = Size(JsonField.of(value)) + } + + /** An enum containing [Size]'s known values. */ + enum class Known { + _1024X1024, + _1024X1536, + _1536X1024, + AUTO, + } + + /** + * An enum containing [Size]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Size] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + _1024X1024, + _1024X1536, + _1536X1024, + AUTO, + /** An enum member indicating that [Size] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + _1024X1024 -> Value._1024X1024 + _1024X1536 -> Value._1024X1536 + _1536X1024 -> Value._1536X1024 + AUTO -> Value.AUTO + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + _1024X1024 -> Known._1024X1024 + _1024X1536 -> Known._1024X1536 + _1536X1024 -> Known._1536X1024 + AUTO -> Known.AUTO + else -> throw OpenAIInvalidDataException("Unknown Size: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): Size = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Size && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ImageEditPartialImageEvent && b64Json == other.b64Json && background == other.background && createdAt == other.createdAt && outputFormat == other.outputFormat && partialImageIndex == other.partialImageIndex && quality == other.quality && size == other.size && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(b64Json, background, createdAt, outputFormat, partialImageIndex, quality, size, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ImageEditPartialImageEvent{b64Json=$b64Json, background=$background, createdAt=$createdAt, outputFormat=$outputFormat, partialImageIndex=$partialImageIndex, quality=$quality, size=$size, type=$type, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/images/ImageEditStreamEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/images/ImageEditStreamEvent.kt new file mode 100644 index 00000000..30ba40ab --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/images/ImageEditStreamEvent.kt @@ -0,0 +1,201 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.images + +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.BaseDeserializer +import com.openai.core.BaseSerializer +import com.openai.core.JsonValue +import com.openai.core.getOrThrow +import com.openai.errors.OpenAIInvalidDataException +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Emitted when a partial image is available during image editing streaming. */ +@JsonDeserialize(using = ImageEditStreamEvent.Deserializer::class) +@JsonSerialize(using = ImageEditStreamEvent.Serializer::class) +class ImageEditStreamEvent +private constructor( + private val partialImage: ImageEditPartialImageEvent? = null, + private val completed: ImageEditCompletedEvent? = null, + private val _json: JsonValue? = null, +) { + + /** Emitted when a partial image is available during image editing streaming. */ + fun partialImage(): Optional = Optional.ofNullable(partialImage) + + /** Emitted when image editing has completed and the final image is available. */ + fun completed(): Optional = Optional.ofNullable(completed) + + fun isPartialImage(): Boolean = partialImage != null + + fun isCompleted(): Boolean = completed != null + + /** Emitted when a partial image is available during image editing streaming. */ + fun asPartialImage(): ImageEditPartialImageEvent = partialImage.getOrThrow("partialImage") + + /** Emitted when image editing has completed and the final image is available. */ + fun asCompleted(): ImageEditCompletedEvent = completed.getOrThrow("completed") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + partialImage != null -> visitor.visitPartialImage(partialImage) + completed != null -> visitor.visitCompleted(completed) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): ImageEditStreamEvent = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitPartialImage(partialImage: ImageEditPartialImageEvent) { + partialImage.validate() + } + + override fun visitCompleted(completed: ImageEditCompletedEvent) { + completed.validate() + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitPartialImage(partialImage: ImageEditPartialImageEvent) = + partialImage.validity() + + override fun visitCompleted(completed: ImageEditCompletedEvent) = + completed.validity() + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ImageEditStreamEvent && partialImage == other.partialImage && completed == other.completed /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(partialImage, completed) /* spotless:on */ + + override fun toString(): String = + when { + partialImage != null -> "ImageEditStreamEvent{partialImage=$partialImage}" + completed != null -> "ImageEditStreamEvent{completed=$completed}" + _json != null -> "ImageEditStreamEvent{_unknown=$_json}" + else -> throw IllegalStateException("Invalid ImageEditStreamEvent") + } + + companion object { + + /** Emitted when a partial image is available during image editing streaming. */ + @JvmStatic + fun ofPartialImage(partialImage: ImageEditPartialImageEvent) = + ImageEditStreamEvent(partialImage = partialImage) + + /** Emitted when image editing has completed and the final image is available. */ + @JvmStatic + fun ofCompleted(completed: ImageEditCompletedEvent) = + ImageEditStreamEvent(completed = completed) + } + + /** + * An interface that defines how to map each variant of [ImageEditStreamEvent] to a value of + * type [T]. + */ + interface Visitor { + + /** Emitted when a partial image is available during image editing streaming. */ + fun visitPartialImage(partialImage: ImageEditPartialImageEvent): T + + /** Emitted when image editing has completed and the final image is available. */ + fun visitCompleted(completed: ImageEditCompletedEvent): T + + /** + * Maps an unknown variant of [ImageEditStreamEvent] to a value of type [T]. + * + * An instance of [ImageEditStreamEvent] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For example, if the SDK is + * on an older version than the API, then the API may respond with new variants that the SDK + * is unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown ImageEditStreamEvent: $json") + } + } + + internal class Deserializer : + BaseDeserializer(ImageEditStreamEvent::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): ImageEditStreamEvent { + val json = JsonValue.fromJsonNode(node) + val type = json.asObject().getOrNull()?.get("type")?.asString()?.getOrNull() + + when (type) { + "image_edit.partial_image" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + ImageEditStreamEvent(partialImage = it, _json = json) + } ?: ImageEditStreamEvent(_json = json) + } + "image_edit.completed" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + ImageEditStreamEvent(completed = it, _json = json) + } ?: ImageEditStreamEvent(_json = json) + } + } + + return ImageEditStreamEvent(_json = json) + } + } + + internal class Serializer : BaseSerializer(ImageEditStreamEvent::class) { + + override fun serialize( + value: ImageEditStreamEvent, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.partialImage != null -> generator.writeObject(value.partialImage) + value.completed != null -> generator.writeObject(value.completed) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid ImageEditStreamEvent") + } + } + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/images/ImageGenCompletedEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/images/ImageGenCompletedEvent.kt new file mode 100644 index 00000000..3366989f --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/images/ImageGenCompletedEvent.kt @@ -0,0 +1,1499 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.images + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.Enum +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.checkRequired +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import kotlin.jvm.optionals.getOrNull + +/** Emitted when image generation has completed and the final image is available. */ +class ImageGenCompletedEvent +private constructor( + private val b64Json: JsonField, + private val background: JsonField, + private val createdAt: JsonField, + private val outputFormat: JsonField, + private val quality: JsonField, + private val size: JsonField, + private val type: JsonValue, + private val usage: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("b64_json") @ExcludeMissing b64Json: JsonField = JsonMissing.of(), + @JsonProperty("background") + @ExcludeMissing + background: JsonField = JsonMissing.of(), + @JsonProperty("created_at") @ExcludeMissing createdAt: JsonField = JsonMissing.of(), + @JsonProperty("output_format") + @ExcludeMissing + outputFormat: JsonField = JsonMissing.of(), + @JsonProperty("quality") @ExcludeMissing quality: JsonField = JsonMissing.of(), + @JsonProperty("size") @ExcludeMissing size: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + @JsonProperty("usage") @ExcludeMissing usage: JsonField = JsonMissing.of(), + ) : this( + b64Json, + background, + createdAt, + outputFormat, + quality, + size, + type, + usage, + mutableMapOf(), + ) + + /** + * Base64-encoded image data, suitable for rendering as an image. + * + * @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 b64Json(): String = b64Json.getRequired("b64_json") + + /** + * The background setting for the generated image. + * + * @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 background(): Background = background.getRequired("background") + + /** + * The Unix timestamp when the event was created. + * + * @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 createdAt(): Long = createdAt.getRequired("created_at") + + /** + * The output format for the generated image. + * + * @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 outputFormat(): OutputFormat = outputFormat.getRequired("output_format") + + /** + * The quality setting for the generated image. + * + * @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 quality(): Quality = quality.getRequired("quality") + + /** + * The size of the generated image. + * + * @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 size(): Size = size.getRequired("size") + + /** + * The type of the event. Always `image_generation.completed`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("image_generation.completed") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server responded + * with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * For `gpt-image-1` only, the token usage information for the image generation. + * + * @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 usage(): Usage = usage.getRequired("usage") + + /** + * Returns the raw JSON value of [b64Json]. + * + * Unlike [b64Json], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("b64_json") @ExcludeMissing fun _b64Json(): JsonField = b64Json + + /** + * Returns the raw JSON value of [background]. + * + * Unlike [background], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("background") + @ExcludeMissing + fun _background(): JsonField = background + + /** + * Returns the raw JSON value of [createdAt]. + * + * Unlike [createdAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created_at") @ExcludeMissing fun _createdAt(): JsonField = createdAt + + /** + * Returns the raw JSON value of [outputFormat]. + * + * Unlike [outputFormat], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("output_format") + @ExcludeMissing + fun _outputFormat(): JsonField = outputFormat + + /** + * Returns the raw JSON value of [quality]. + * + * Unlike [quality], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("quality") @ExcludeMissing fun _quality(): JsonField = quality + + /** + * Returns the raw JSON value of [size]. + * + * Unlike [size], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("size") @ExcludeMissing fun _size(): JsonField = size + + /** + * Returns the raw JSON value of [usage]. + * + * Unlike [usage], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("usage") @ExcludeMissing fun _usage(): JsonField = usage + + @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 [ImageGenCompletedEvent]. + * + * The following fields are required: + * ```java + * .b64Json() + * .background() + * .createdAt() + * .outputFormat() + * .quality() + * .size() + * .usage() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ImageGenCompletedEvent]. */ + class Builder internal constructor() { + + private var b64Json: JsonField? = null + private var background: JsonField? = null + private var createdAt: JsonField? = null + private var outputFormat: JsonField? = null + private var quality: JsonField? = null + private var size: JsonField? = null + private var type: JsonValue = JsonValue.from("image_generation.completed") + private var usage: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(imageGenCompletedEvent: ImageGenCompletedEvent) = apply { + b64Json = imageGenCompletedEvent.b64Json + background = imageGenCompletedEvent.background + createdAt = imageGenCompletedEvent.createdAt + outputFormat = imageGenCompletedEvent.outputFormat + quality = imageGenCompletedEvent.quality + size = imageGenCompletedEvent.size + type = imageGenCompletedEvent.type + usage = imageGenCompletedEvent.usage + additionalProperties = imageGenCompletedEvent.additionalProperties.toMutableMap() + } + + /** Base64-encoded image data, suitable for rendering as an image. */ + fun b64Json(b64Json: String) = b64Json(JsonField.of(b64Json)) + + /** + * Sets [Builder.b64Json] to an arbitrary JSON value. + * + * You should usually call [Builder.b64Json] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun b64Json(b64Json: JsonField) = apply { this.b64Json = b64Json } + + /** The background setting for the generated image. */ + fun background(background: Background) = background(JsonField.of(background)) + + /** + * Sets [Builder.background] to an arbitrary JSON value. + * + * You should usually call [Builder.background] with a well-typed [Background] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun background(background: JsonField) = apply { this.background = background } + + /** The Unix timestamp when the event was created. */ + fun createdAt(createdAt: Long) = createdAt(JsonField.of(createdAt)) + + /** + * Sets [Builder.createdAt] to an arbitrary JSON value. + * + * You should usually call [Builder.createdAt] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun createdAt(createdAt: JsonField) = apply { this.createdAt = createdAt } + + /** The output format for the generated image. */ + fun outputFormat(outputFormat: OutputFormat) = outputFormat(JsonField.of(outputFormat)) + + /** + * Sets [Builder.outputFormat] to an arbitrary JSON value. + * + * You should usually call [Builder.outputFormat] with a well-typed [OutputFormat] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun outputFormat(outputFormat: JsonField) = apply { + this.outputFormat = outputFormat + } + + /** The quality setting for the generated image. */ + fun quality(quality: Quality) = quality(JsonField.of(quality)) + + /** + * Sets [Builder.quality] to an arbitrary JSON value. + * + * You should usually call [Builder.quality] with a well-typed [Quality] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun quality(quality: JsonField) = apply { this.quality = quality } + + /** The size of the generated image. */ + fun size(size: Size) = size(JsonField.of(size)) + + /** + * Sets [Builder.size] to an arbitrary JSON value. + * + * You should usually call [Builder.size] with a well-typed [Size] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun size(size: JsonField) = apply { this.size = size } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("image_generation.completed") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + /** For `gpt-image-1` only, the token usage information for the image generation. */ + fun usage(usage: Usage) = usage(JsonField.of(usage)) + + /** + * Sets [Builder.usage] to an arbitrary JSON value. + * + * You should usually call [Builder.usage] with a well-typed [Usage] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun usage(usage: JsonField) = apply { this.usage = usage } + + 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 [ImageGenCompletedEvent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .b64Json() + * .background() + * .createdAt() + * .outputFormat() + * .quality() + * .size() + * .usage() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ImageGenCompletedEvent = + ImageGenCompletedEvent( + checkRequired("b64Json", b64Json), + checkRequired("background", background), + checkRequired("createdAt", createdAt), + checkRequired("outputFormat", outputFormat), + checkRequired("quality", quality), + checkRequired("size", size), + type, + checkRequired("usage", usage), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): ImageGenCompletedEvent = apply { + if (validated) { + return@apply + } + + b64Json() + background().validate() + createdAt() + outputFormat().validate() + quality().validate() + size().validate() + _type().let { + if (it != JsonValue.from("image_generation.completed")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + usage().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (b64Json.asKnown().isPresent) 1 else 0) + + (background.asKnown().getOrNull()?.validity() ?: 0) + + (if (createdAt.asKnown().isPresent) 1 else 0) + + (outputFormat.asKnown().getOrNull()?.validity() ?: 0) + + (quality.asKnown().getOrNull()?.validity() ?: 0) + + (size.asKnown().getOrNull()?.validity() ?: 0) + + type.let { if (it == JsonValue.from("image_generation.completed")) 1 else 0 } + + (usage.asKnown().getOrNull()?.validity() ?: 0) + + /** The background setting for the generated image. */ + class Background @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val TRANSPARENT = of("transparent") + + @JvmField val OPAQUE = of("opaque") + + @JvmField val AUTO = of("auto") + + @JvmStatic fun of(value: String) = Background(JsonField.of(value)) + } + + /** An enum containing [Background]'s known values. */ + enum class Known { + TRANSPARENT, + OPAQUE, + AUTO, + } + + /** + * An enum containing [Background]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Background] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + TRANSPARENT, + OPAQUE, + AUTO, + /** + * An enum member indicating that [Background] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + TRANSPARENT -> Value.TRANSPARENT + OPAQUE -> Value.OPAQUE + AUTO -> Value.AUTO + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + TRANSPARENT -> Known.TRANSPARENT + OPAQUE -> Known.OPAQUE + AUTO -> Known.AUTO + else -> throw OpenAIInvalidDataException("Unknown Background: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): Background = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Background && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** The output format for the generated image. */ + class OutputFormat @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val PNG = of("png") + + @JvmField val WEBP = of("webp") + + @JvmField val JPEG = of("jpeg") + + @JvmStatic fun of(value: String) = OutputFormat(JsonField.of(value)) + } + + /** An enum containing [OutputFormat]'s known values. */ + enum class Known { + PNG, + WEBP, + JPEG, + } + + /** + * An enum containing [OutputFormat]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [OutputFormat] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + PNG, + WEBP, + JPEG, + /** + * An enum member indicating that [OutputFormat] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + PNG -> Value.PNG + WEBP -> Value.WEBP + JPEG -> Value.JPEG + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + PNG -> Known.PNG + WEBP -> Known.WEBP + JPEG -> Known.JPEG + else -> throw OpenAIInvalidDataException("Unknown OutputFormat: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): OutputFormat = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is OutputFormat && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** The quality setting for the generated image. */ + class Quality @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val LOW = of("low") + + @JvmField val MEDIUM = of("medium") + + @JvmField val HIGH = of("high") + + @JvmField val AUTO = of("auto") + + @JvmStatic fun of(value: String) = Quality(JsonField.of(value)) + } + + /** An enum containing [Quality]'s known values. */ + enum class Known { + LOW, + MEDIUM, + HIGH, + AUTO, + } + + /** + * An enum containing [Quality]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Quality] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + LOW, + MEDIUM, + HIGH, + AUTO, + /** An enum member indicating that [Quality] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + LOW -> Value.LOW + MEDIUM -> Value.MEDIUM + HIGH -> Value.HIGH + AUTO -> Value.AUTO + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + LOW -> Known.LOW + MEDIUM -> Known.MEDIUM + HIGH -> Known.HIGH + AUTO -> Known.AUTO + else -> throw OpenAIInvalidDataException("Unknown Quality: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): Quality = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Quality && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** The size of the generated image. */ + class Size @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val _1024X1024 = of("1024x1024") + + @JvmField val _1024X1536 = of("1024x1536") + + @JvmField val _1536X1024 = of("1536x1024") + + @JvmField val AUTO = of("auto") + + @JvmStatic fun of(value: String) = Size(JsonField.of(value)) + } + + /** An enum containing [Size]'s known values. */ + enum class Known { + _1024X1024, + _1024X1536, + _1536X1024, + AUTO, + } + + /** + * An enum containing [Size]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Size] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + _1024X1024, + _1024X1536, + _1536X1024, + AUTO, + /** An enum member indicating that [Size] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + _1024X1024 -> Value._1024X1024 + _1024X1536 -> Value._1024X1536 + _1536X1024 -> Value._1536X1024 + AUTO -> Value.AUTO + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + _1024X1024 -> Known._1024X1024 + _1024X1536 -> Known._1024X1536 + _1536X1024 -> Known._1536X1024 + AUTO -> Known.AUTO + else -> throw OpenAIInvalidDataException("Unknown Size: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): Size = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Size && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** For `gpt-image-1` only, the token usage information for the image generation. */ + class Usage + private constructor( + private val inputTokens: JsonField, + private val inputTokensDetails: JsonField, + private val outputTokens: JsonField, + private val totalTokens: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("input_tokens") + @ExcludeMissing + inputTokens: JsonField = JsonMissing.of(), + @JsonProperty("input_tokens_details") + @ExcludeMissing + inputTokensDetails: JsonField = JsonMissing.of(), + @JsonProperty("output_tokens") + @ExcludeMissing + outputTokens: JsonField = JsonMissing.of(), + @JsonProperty("total_tokens") + @ExcludeMissing + totalTokens: JsonField = JsonMissing.of(), + ) : this(inputTokens, inputTokensDetails, outputTokens, totalTokens, mutableMapOf()) + + /** + * The number of tokens (images and text) in the input prompt. + * + * @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 inputTokens(): Long = inputTokens.getRequired("input_tokens") + + /** + * The input tokens detailed information for the image generation. + * + * @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 inputTokensDetails(): InputTokensDetails = + inputTokensDetails.getRequired("input_tokens_details") + + /** + * The number of image tokens in the output image. + * + * @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 outputTokens(): Long = outputTokens.getRequired("output_tokens") + + /** + * The total number of tokens (images and text) used for the image generation. + * + * @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 totalTokens(): Long = totalTokens.getRequired("total_tokens") + + /** + * Returns the raw JSON value of [inputTokens]. + * + * Unlike [inputTokens], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("input_tokens") + @ExcludeMissing + fun _inputTokens(): JsonField = inputTokens + + /** + * Returns the raw JSON value of [inputTokensDetails]. + * + * Unlike [inputTokensDetails], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("input_tokens_details") + @ExcludeMissing + fun _inputTokensDetails(): JsonField = inputTokensDetails + + /** + * Returns the raw JSON value of [outputTokens]. + * + * Unlike [outputTokens], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("output_tokens") + @ExcludeMissing + fun _outputTokens(): JsonField = outputTokens + + /** + * Returns the raw JSON value of [totalTokens]. + * + * Unlike [totalTokens], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("total_tokens") + @ExcludeMissing + fun _totalTokens(): JsonField = totalTokens + + @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 [Usage]. + * + * The following fields are required: + * ```java + * .inputTokens() + * .inputTokensDetails() + * .outputTokens() + * .totalTokens() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Usage]. */ + class Builder internal constructor() { + + private var inputTokens: JsonField? = null + private var inputTokensDetails: JsonField? = null + private var outputTokens: JsonField? = null + private var totalTokens: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(usage: Usage) = apply { + inputTokens = usage.inputTokens + inputTokensDetails = usage.inputTokensDetails + outputTokens = usage.outputTokens + totalTokens = usage.totalTokens + additionalProperties = usage.additionalProperties.toMutableMap() + } + + /** The number of tokens (images and text) in the input prompt. */ + fun inputTokens(inputTokens: Long) = inputTokens(JsonField.of(inputTokens)) + + /** + * Sets [Builder.inputTokens] to an arbitrary JSON value. + * + * You should usually call [Builder.inputTokens] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun inputTokens(inputTokens: JsonField) = apply { this.inputTokens = inputTokens } + + /** The input tokens detailed information for the image generation. */ + fun inputTokensDetails(inputTokensDetails: InputTokensDetails) = + inputTokensDetails(JsonField.of(inputTokensDetails)) + + /** + * Sets [Builder.inputTokensDetails] to an arbitrary JSON value. + * + * You should usually call [Builder.inputTokensDetails] with a well-typed + * [InputTokensDetails] value instead. This method is primarily for setting the field to + * an undocumented or not yet supported value. + */ + fun inputTokensDetails(inputTokensDetails: JsonField) = apply { + this.inputTokensDetails = inputTokensDetails + } + + /** The number of image tokens in the output image. */ + fun outputTokens(outputTokens: Long) = outputTokens(JsonField.of(outputTokens)) + + /** + * Sets [Builder.outputTokens] to an arbitrary JSON value. + * + * You should usually call [Builder.outputTokens] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun outputTokens(outputTokens: JsonField) = apply { + this.outputTokens = outputTokens + } + + /** The total number of tokens (images and text) used for the image generation. */ + fun totalTokens(totalTokens: Long) = totalTokens(JsonField.of(totalTokens)) + + /** + * Sets [Builder.totalTokens] to an arbitrary JSON value. + * + * You should usually call [Builder.totalTokens] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun totalTokens(totalTokens: JsonField) = apply { this.totalTokens = totalTokens } + + 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 [Usage]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .inputTokens() + * .inputTokensDetails() + * .outputTokens() + * .totalTokens() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Usage = + Usage( + checkRequired("inputTokens", inputTokens), + checkRequired("inputTokensDetails", inputTokensDetails), + checkRequired("outputTokens", outputTokens), + checkRequired("totalTokens", totalTokens), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Usage = apply { + if (validated) { + return@apply + } + + inputTokens() + inputTokensDetails().validate() + outputTokens() + totalTokens() + 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 (inputTokens.asKnown().isPresent) 1 else 0) + + (inputTokensDetails.asKnown().getOrNull()?.validity() ?: 0) + + (if (outputTokens.asKnown().isPresent) 1 else 0) + + (if (totalTokens.asKnown().isPresent) 1 else 0) + + /** The input tokens detailed information for the image generation. */ + class InputTokensDetails + private constructor( + private val imageTokens: JsonField, + private val textTokens: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("image_tokens") + @ExcludeMissing + imageTokens: JsonField = JsonMissing.of(), + @JsonProperty("text_tokens") + @ExcludeMissing + textTokens: JsonField = JsonMissing.of(), + ) : this(imageTokens, textTokens, mutableMapOf()) + + /** + * The number of image tokens in the input prompt. + * + * @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 imageTokens(): Long = imageTokens.getRequired("image_tokens") + + /** + * The number of text tokens in the input prompt. + * + * @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 textTokens(): Long = textTokens.getRequired("text_tokens") + + /** + * Returns the raw JSON value of [imageTokens]. + * + * Unlike [imageTokens], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("image_tokens") + @ExcludeMissing + fun _imageTokens(): JsonField = imageTokens + + /** + * Returns the raw JSON value of [textTokens]. + * + * Unlike [textTokens], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("text_tokens") + @ExcludeMissing + fun _textTokens(): JsonField = textTokens + + @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 [InputTokensDetails]. + * + * The following fields are required: + * ```java + * .imageTokens() + * .textTokens() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InputTokensDetails]. */ + class Builder internal constructor() { + + private var imageTokens: JsonField? = null + private var textTokens: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(inputTokensDetails: InputTokensDetails) = apply { + imageTokens = inputTokensDetails.imageTokens + textTokens = inputTokensDetails.textTokens + additionalProperties = inputTokensDetails.additionalProperties.toMutableMap() + } + + /** The number of image tokens in the input prompt. */ + fun imageTokens(imageTokens: Long) = imageTokens(JsonField.of(imageTokens)) + + /** + * Sets [Builder.imageTokens] to an arbitrary JSON value. + * + * You should usually call [Builder.imageTokens] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun imageTokens(imageTokens: JsonField) = apply { + this.imageTokens = imageTokens + } + + /** The number of text tokens in the input prompt. */ + fun textTokens(textTokens: Long) = textTokens(JsonField.of(textTokens)) + + /** + * Sets [Builder.textTokens] to an arbitrary JSON value. + * + * You should usually call [Builder.textTokens] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun textTokens(textTokens: JsonField) = apply { this.textTokens = textTokens } + + 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 [InputTokensDetails]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .imageTokens() + * .textTokens() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): InputTokensDetails = + InputTokensDetails( + checkRequired("imageTokens", imageTokens), + checkRequired("textTokens", textTokens), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): InputTokensDetails = apply { + if (validated) { + return@apply + } + + imageTokens() + textTokens() + 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 (imageTokens.asKnown().isPresent) 1 else 0) + + (if (textTokens.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is InputTokensDetails && imageTokens == other.imageTokens && textTokens == other.textTokens && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(imageTokens, textTokens, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "InputTokensDetails{imageTokens=$imageTokens, textTokens=$textTokens, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Usage && inputTokens == other.inputTokens && inputTokensDetails == other.inputTokensDetails && outputTokens == other.outputTokens && totalTokens == other.totalTokens && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(inputTokens, inputTokensDetails, outputTokens, totalTokens, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Usage{inputTokens=$inputTokens, inputTokensDetails=$inputTokensDetails, outputTokens=$outputTokens, totalTokens=$totalTokens, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ImageGenCompletedEvent && b64Json == other.b64Json && background == other.background && createdAt == other.createdAt && outputFormat == other.outputFormat && quality == other.quality && size == other.size && type == other.type && usage == other.usage && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(b64Json, background, createdAt, outputFormat, quality, size, type, usage, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ImageGenCompletedEvent{b64Json=$b64Json, background=$background, createdAt=$createdAt, outputFormat=$outputFormat, quality=$quality, size=$size, type=$type, usage=$usage, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/images/ImageGenPartialImageEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/images/ImageGenPartialImageEvent.kt new file mode 100644 index 00000000..dc8f891e --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/images/ImageGenPartialImageEvent.kt @@ -0,0 +1,1001 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.images + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.Enum +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.checkRequired +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import kotlin.jvm.optionals.getOrNull + +/** Emitted when a partial image is available during image generation streaming. */ +class ImageGenPartialImageEvent +private constructor( + private val b64Json: JsonField, + private val background: JsonField, + private val createdAt: JsonField, + private val outputFormat: JsonField, + private val partialImageIndex: JsonField, + private val quality: JsonField, + private val size: JsonField, + private val type: JsonValue, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("b64_json") @ExcludeMissing b64Json: JsonField = JsonMissing.of(), + @JsonProperty("background") + @ExcludeMissing + background: JsonField = JsonMissing.of(), + @JsonProperty("created_at") @ExcludeMissing createdAt: JsonField = JsonMissing.of(), + @JsonProperty("output_format") + @ExcludeMissing + outputFormat: JsonField = JsonMissing.of(), + @JsonProperty("partial_image_index") + @ExcludeMissing + partialImageIndex: JsonField = JsonMissing.of(), + @JsonProperty("quality") @ExcludeMissing quality: JsonField = JsonMissing.of(), + @JsonProperty("size") @ExcludeMissing size: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + ) : this( + b64Json, + background, + createdAt, + outputFormat, + partialImageIndex, + quality, + size, + type, + mutableMapOf(), + ) + + /** + * Base64-encoded partial image data, suitable for rendering as an image. + * + * @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 b64Json(): String = b64Json.getRequired("b64_json") + + /** + * The background setting for the requested image. + * + * @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 background(): Background = background.getRequired("background") + + /** + * The Unix timestamp when the event was created. + * + * @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 createdAt(): Long = createdAt.getRequired("created_at") + + /** + * The output format for the requested image. + * + * @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 outputFormat(): OutputFormat = outputFormat.getRequired("output_format") + + /** + * 0-based index for the partial image (streaming). + * + * @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 partialImageIndex(): Long = partialImageIndex.getRequired("partial_image_index") + + /** + * The quality setting for the requested image. + * + * @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 quality(): Quality = quality.getRequired("quality") + + /** + * The size of the requested image. + * + * @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 size(): Size = size.getRequired("size") + + /** + * The type of the event. Always `image_generation.partial_image`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("image_generation.partial_image") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server responded + * with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * Returns the raw JSON value of [b64Json]. + * + * Unlike [b64Json], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("b64_json") @ExcludeMissing fun _b64Json(): JsonField = b64Json + + /** + * Returns the raw JSON value of [background]. + * + * Unlike [background], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("background") + @ExcludeMissing + fun _background(): JsonField = background + + /** + * Returns the raw JSON value of [createdAt]. + * + * Unlike [createdAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created_at") @ExcludeMissing fun _createdAt(): JsonField = createdAt + + /** + * Returns the raw JSON value of [outputFormat]. + * + * Unlike [outputFormat], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("output_format") + @ExcludeMissing + fun _outputFormat(): JsonField = outputFormat + + /** + * Returns the raw JSON value of [partialImageIndex]. + * + * Unlike [partialImageIndex], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("partial_image_index") + @ExcludeMissing + fun _partialImageIndex(): JsonField = partialImageIndex + + /** + * Returns the raw JSON value of [quality]. + * + * Unlike [quality], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("quality") @ExcludeMissing fun _quality(): JsonField = quality + + /** + * Returns the raw JSON value of [size]. + * + * Unlike [size], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("size") @ExcludeMissing fun _size(): JsonField = size + + @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 [ImageGenPartialImageEvent]. + * + * The following fields are required: + * ```java + * .b64Json() + * .background() + * .createdAt() + * .outputFormat() + * .partialImageIndex() + * .quality() + * .size() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ImageGenPartialImageEvent]. */ + class Builder internal constructor() { + + private var b64Json: JsonField? = null + private var background: JsonField? = null + private var createdAt: JsonField? = null + private var outputFormat: JsonField? = null + private var partialImageIndex: JsonField? = null + private var quality: JsonField? = null + private var size: JsonField? = null + private var type: JsonValue = JsonValue.from("image_generation.partial_image") + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(imageGenPartialImageEvent: ImageGenPartialImageEvent) = apply { + b64Json = imageGenPartialImageEvent.b64Json + background = imageGenPartialImageEvent.background + createdAt = imageGenPartialImageEvent.createdAt + outputFormat = imageGenPartialImageEvent.outputFormat + partialImageIndex = imageGenPartialImageEvent.partialImageIndex + quality = imageGenPartialImageEvent.quality + size = imageGenPartialImageEvent.size + type = imageGenPartialImageEvent.type + additionalProperties = imageGenPartialImageEvent.additionalProperties.toMutableMap() + } + + /** Base64-encoded partial image data, suitable for rendering as an image. */ + fun b64Json(b64Json: String) = b64Json(JsonField.of(b64Json)) + + /** + * Sets [Builder.b64Json] to an arbitrary JSON value. + * + * You should usually call [Builder.b64Json] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun b64Json(b64Json: JsonField) = apply { this.b64Json = b64Json } + + /** The background setting for the requested image. */ + fun background(background: Background) = background(JsonField.of(background)) + + /** + * Sets [Builder.background] to an arbitrary JSON value. + * + * You should usually call [Builder.background] with a well-typed [Background] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun background(background: JsonField) = apply { this.background = background } + + /** The Unix timestamp when the event was created. */ + fun createdAt(createdAt: Long) = createdAt(JsonField.of(createdAt)) + + /** + * Sets [Builder.createdAt] to an arbitrary JSON value. + * + * You should usually call [Builder.createdAt] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun createdAt(createdAt: JsonField) = apply { this.createdAt = createdAt } + + /** The output format for the requested image. */ + fun outputFormat(outputFormat: OutputFormat) = outputFormat(JsonField.of(outputFormat)) + + /** + * Sets [Builder.outputFormat] to an arbitrary JSON value. + * + * You should usually call [Builder.outputFormat] with a well-typed [OutputFormat] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun outputFormat(outputFormat: JsonField) = apply { + this.outputFormat = outputFormat + } + + /** 0-based index for the partial image (streaming). */ + fun partialImageIndex(partialImageIndex: Long) = + partialImageIndex(JsonField.of(partialImageIndex)) + + /** + * Sets [Builder.partialImageIndex] to an arbitrary JSON value. + * + * You should usually call [Builder.partialImageIndex] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun partialImageIndex(partialImageIndex: JsonField) = apply { + this.partialImageIndex = partialImageIndex + } + + /** The quality setting for the requested image. */ + fun quality(quality: Quality) = quality(JsonField.of(quality)) + + /** + * Sets [Builder.quality] to an arbitrary JSON value. + * + * You should usually call [Builder.quality] with a well-typed [Quality] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun quality(quality: JsonField) = apply { this.quality = quality } + + /** The size of the requested image. */ + fun size(size: Size) = size(JsonField.of(size)) + + /** + * Sets [Builder.size] to an arbitrary JSON value. + * + * You should usually call [Builder.size] with a well-typed [Size] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun size(size: JsonField) = apply { this.size = size } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("image_generation.partial_image") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [ImageGenPartialImageEvent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .b64Json() + * .background() + * .createdAt() + * .outputFormat() + * .partialImageIndex() + * .quality() + * .size() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ImageGenPartialImageEvent = + ImageGenPartialImageEvent( + checkRequired("b64Json", b64Json), + checkRequired("background", background), + checkRequired("createdAt", createdAt), + checkRequired("outputFormat", outputFormat), + checkRequired("partialImageIndex", partialImageIndex), + checkRequired("quality", quality), + checkRequired("size", size), + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): ImageGenPartialImageEvent = apply { + if (validated) { + return@apply + } + + b64Json() + background().validate() + createdAt() + outputFormat().validate() + partialImageIndex() + quality().validate() + size().validate() + _type().let { + if (it != JsonValue.from("image_generation.partial_image")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (b64Json.asKnown().isPresent) 1 else 0) + + (background.asKnown().getOrNull()?.validity() ?: 0) + + (if (createdAt.asKnown().isPresent) 1 else 0) + + (outputFormat.asKnown().getOrNull()?.validity() ?: 0) + + (if (partialImageIndex.asKnown().isPresent) 1 else 0) + + (quality.asKnown().getOrNull()?.validity() ?: 0) + + (size.asKnown().getOrNull()?.validity() ?: 0) + + type.let { if (it == JsonValue.from("image_generation.partial_image")) 1 else 0 } + + /** The background setting for the requested image. */ + class Background @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val TRANSPARENT = of("transparent") + + @JvmField val OPAQUE = of("opaque") + + @JvmField val AUTO = of("auto") + + @JvmStatic fun of(value: String) = Background(JsonField.of(value)) + } + + /** An enum containing [Background]'s known values. */ + enum class Known { + TRANSPARENT, + OPAQUE, + AUTO, + } + + /** + * An enum containing [Background]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Background] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + TRANSPARENT, + OPAQUE, + AUTO, + /** + * An enum member indicating that [Background] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + TRANSPARENT -> Value.TRANSPARENT + OPAQUE -> Value.OPAQUE + AUTO -> Value.AUTO + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + TRANSPARENT -> Known.TRANSPARENT + OPAQUE -> Known.OPAQUE + AUTO -> Known.AUTO + else -> throw OpenAIInvalidDataException("Unknown Background: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): Background = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Background && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** The output format for the requested image. */ + class OutputFormat @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val PNG = of("png") + + @JvmField val WEBP = of("webp") + + @JvmField val JPEG = of("jpeg") + + @JvmStatic fun of(value: String) = OutputFormat(JsonField.of(value)) + } + + /** An enum containing [OutputFormat]'s known values. */ + enum class Known { + PNG, + WEBP, + JPEG, + } + + /** + * An enum containing [OutputFormat]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [OutputFormat] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + PNG, + WEBP, + JPEG, + /** + * An enum member indicating that [OutputFormat] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + PNG -> Value.PNG + WEBP -> Value.WEBP + JPEG -> Value.JPEG + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + PNG -> Known.PNG + WEBP -> Known.WEBP + JPEG -> Known.JPEG + else -> throw OpenAIInvalidDataException("Unknown OutputFormat: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): OutputFormat = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is OutputFormat && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** The quality setting for the requested image. */ + class Quality @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val LOW = of("low") + + @JvmField val MEDIUM = of("medium") + + @JvmField val HIGH = of("high") + + @JvmField val AUTO = of("auto") + + @JvmStatic fun of(value: String) = Quality(JsonField.of(value)) + } + + /** An enum containing [Quality]'s known values. */ + enum class Known { + LOW, + MEDIUM, + HIGH, + AUTO, + } + + /** + * An enum containing [Quality]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Quality] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + LOW, + MEDIUM, + HIGH, + AUTO, + /** An enum member indicating that [Quality] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + LOW -> Value.LOW + MEDIUM -> Value.MEDIUM + HIGH -> Value.HIGH + AUTO -> Value.AUTO + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + LOW -> Known.LOW + MEDIUM -> Known.MEDIUM + HIGH -> Known.HIGH + AUTO -> Known.AUTO + else -> throw OpenAIInvalidDataException("Unknown Quality: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): Quality = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Quality && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** The size of the requested image. */ + class Size @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val _1024X1024 = of("1024x1024") + + @JvmField val _1024X1536 = of("1024x1536") + + @JvmField val _1536X1024 = of("1536x1024") + + @JvmField val AUTO = of("auto") + + @JvmStatic fun of(value: String) = Size(JsonField.of(value)) + } + + /** An enum containing [Size]'s known values. */ + enum class Known { + _1024X1024, + _1024X1536, + _1536X1024, + AUTO, + } + + /** + * An enum containing [Size]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Size] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + _1024X1024, + _1024X1536, + _1536X1024, + AUTO, + /** An enum member indicating that [Size] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + _1024X1024 -> Value._1024X1024 + _1024X1536 -> Value._1024X1536 + _1536X1024 -> Value._1536X1024 + AUTO -> Value.AUTO + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + _1024X1024 -> Known._1024X1024 + _1024X1536 -> Known._1024X1536 + _1536X1024 -> Known._1536X1024 + AUTO -> Known.AUTO + else -> throw OpenAIInvalidDataException("Unknown Size: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): Size = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Size && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ImageGenPartialImageEvent && b64Json == other.b64Json && background == other.background && createdAt == other.createdAt && outputFormat == other.outputFormat && partialImageIndex == other.partialImageIndex && quality == other.quality && size == other.size && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(b64Json, background, createdAt, outputFormat, partialImageIndex, quality, size, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ImageGenPartialImageEvent{b64Json=$b64Json, background=$background, createdAt=$createdAt, outputFormat=$outputFormat, partialImageIndex=$partialImageIndex, quality=$quality, size=$size, type=$type, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/images/ImageGenStreamEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/images/ImageGenStreamEvent.kt new file mode 100644 index 00000000..b12a44b1 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/images/ImageGenStreamEvent.kt @@ -0,0 +1,213 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.images + +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.BaseDeserializer +import com.openai.core.BaseSerializer +import com.openai.core.JsonValue +import com.openai.core.getOrThrow +import com.openai.errors.OpenAIInvalidDataException +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Emitted when a partial image is available during image generation streaming. */ +@JsonDeserialize(using = ImageGenStreamEvent.Deserializer::class) +@JsonSerialize(using = ImageGenStreamEvent.Serializer::class) +class ImageGenStreamEvent +private constructor( + private val generationPartialImage: ImageGenPartialImageEvent? = null, + private val generationCompleted: ImageGenCompletedEvent? = null, + private val _json: JsonValue? = null, +) { + + /** Emitted when a partial image is available during image generation streaming. */ + fun generationPartialImage(): Optional = + Optional.ofNullable(generationPartialImage) + + /** Emitted when image generation has completed and the final image is available. */ + fun generationCompleted(): Optional = + Optional.ofNullable(generationCompleted) + + fun isGenerationPartialImage(): Boolean = generationPartialImage != null + + fun isGenerationCompleted(): Boolean = generationCompleted != null + + /** Emitted when a partial image is available during image generation streaming. */ + fun asGenerationPartialImage(): ImageGenPartialImageEvent = + generationPartialImage.getOrThrow("generationPartialImage") + + /** Emitted when image generation has completed and the final image is available. */ + fun asGenerationCompleted(): ImageGenCompletedEvent = + generationCompleted.getOrThrow("generationCompleted") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + generationPartialImage != null -> + visitor.visitGenerationPartialImage(generationPartialImage) + generationCompleted != null -> visitor.visitGenerationCompleted(generationCompleted) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): ImageGenStreamEvent = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitGenerationPartialImage( + generationPartialImage: ImageGenPartialImageEvent + ) { + generationPartialImage.validate() + } + + override fun visitGenerationCompleted(generationCompleted: ImageGenCompletedEvent) { + generationCompleted.validate() + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitGenerationPartialImage( + generationPartialImage: ImageGenPartialImageEvent + ) = generationPartialImage.validity() + + override fun visitGenerationCompleted(generationCompleted: ImageGenCompletedEvent) = + generationCompleted.validity() + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ImageGenStreamEvent && generationPartialImage == other.generationPartialImage && generationCompleted == other.generationCompleted /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(generationPartialImage, generationCompleted) /* spotless:on */ + + override fun toString(): String = + when { + generationPartialImage != null -> + "ImageGenStreamEvent{generationPartialImage=$generationPartialImage}" + generationCompleted != null -> + "ImageGenStreamEvent{generationCompleted=$generationCompleted}" + _json != null -> "ImageGenStreamEvent{_unknown=$_json}" + else -> throw IllegalStateException("Invalid ImageGenStreamEvent") + } + + companion object { + + /** Emitted when a partial image is available during image generation streaming. */ + @JvmStatic + fun ofGenerationPartialImage(generationPartialImage: ImageGenPartialImageEvent) = + ImageGenStreamEvent(generationPartialImage = generationPartialImage) + + /** Emitted when image generation has completed and the final image is available. */ + @JvmStatic + fun ofGenerationCompleted(generationCompleted: ImageGenCompletedEvent) = + ImageGenStreamEvent(generationCompleted = generationCompleted) + } + + /** + * An interface that defines how to map each variant of [ImageGenStreamEvent] to a value of type + * [T]. + */ + interface Visitor { + + /** Emitted when a partial image is available during image generation streaming. */ + fun visitGenerationPartialImage(generationPartialImage: ImageGenPartialImageEvent): T + + /** Emitted when image generation has completed and the final image is available. */ + fun visitGenerationCompleted(generationCompleted: ImageGenCompletedEvent): T + + /** + * Maps an unknown variant of [ImageGenStreamEvent] to a value of type [T]. + * + * An instance of [ImageGenStreamEvent] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For example, if the SDK is + * on an older version than the API, then the API may respond with new variants that the SDK + * is unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown ImageGenStreamEvent: $json") + } + } + + internal class Deserializer : + BaseDeserializer(ImageGenStreamEvent::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): ImageGenStreamEvent { + val json = JsonValue.fromJsonNode(node) + val type = json.asObject().getOrNull()?.get("type")?.asString()?.getOrNull() + + when (type) { + "image_generation.partial_image" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + ImageGenStreamEvent(generationPartialImage = it, _json = json) + } ?: ImageGenStreamEvent(_json = json) + } + "image_generation.completed" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + ImageGenStreamEvent(generationCompleted = it, _json = json) + } ?: ImageGenStreamEvent(_json = json) + } + } + + return ImageGenStreamEvent(_json = json) + } + } + + internal class Serializer : BaseSerializer(ImageGenStreamEvent::class) { + + override fun serialize( + value: ImageGenStreamEvent, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.generationPartialImage != null -> + generator.writeObject(value.generationPartialImage) + value.generationCompleted != null -> + generator.writeObject(value.generationCompleted) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid ImageGenStreamEvent") + } + } + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/images/ImageGenerateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/images/ImageGenerateParams.kt index 97602340..5a6f7feb 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/images/ImageGenerateParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/images/ImageGenerateParams.kt @@ -99,6 +99,16 @@ private constructor( */ fun outputFormat(): Optional = body.outputFormat() + /** + * The number of partial images to generate. This parameter is used for streaming responses that + * return partial images. Value must be between 0 and 3. When set to 0, the response will be a + * single image sent in one streaming event. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun partialImages(): Optional = body.partialImages() + /** * The quality of the image that will be generated. * - `auto` (default value) will automatically select the best quality for the given model. @@ -204,6 +214,13 @@ private constructor( */ fun _outputFormat(): JsonField = body._outputFormat() + /** + * Returns the raw JSON value of [partialImages]. + * + * Unlike [partialImages], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _partialImages(): JsonField = body._partialImages() + /** * Returns the raw JSON value of [quality]. * @@ -445,6 +462,34 @@ private constructor( body.outputFormat(outputFormat) } + /** + * The number of partial images to generate. This parameter is used for streaming responses + * that return partial images. Value must be between 0 and 3. When set to 0, the response + * will be a single image sent in one streaming event. + */ + fun partialImages(partialImages: Long?) = apply { body.partialImages(partialImages) } + + /** + * Alias for [Builder.partialImages]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun partialImages(partialImages: Long) = partialImages(partialImages as Long?) + + /** Alias for calling [Builder.partialImages] with `partialImages.orElse(null)`. */ + fun partialImages(partialImages: Optional) = partialImages(partialImages.getOrNull()) + + /** + * Sets [Builder.partialImages] to an arbitrary JSON value. + * + * You should usually call [Builder.partialImages] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun partialImages(partialImages: JsonField) = apply { + body.partialImages(partialImages) + } + /** * The quality of the image that will be generated. * - `auto` (default value) will automatically select the best quality for the given model. @@ -695,6 +740,7 @@ private constructor( private val n: JsonField, private val outputCompression: JsonField, private val outputFormat: JsonField, + private val partialImages: JsonField, private val quality: JsonField, private val responseFormat: JsonField, private val size: JsonField, @@ -720,6 +766,9 @@ private constructor( @JsonProperty("output_format") @ExcludeMissing outputFormat: JsonField = JsonMissing.of(), + @JsonProperty("partial_images") + @ExcludeMissing + partialImages: JsonField = JsonMissing.of(), @JsonProperty("quality") @ExcludeMissing quality: JsonField = JsonMissing.of(), @JsonProperty("response_format") @ExcludeMissing @@ -735,6 +784,7 @@ private constructor( n, outputCompression, outputFormat, + partialImages, quality, responseFormat, size, @@ -812,6 +862,16 @@ private constructor( */ fun outputFormat(): Optional = outputFormat.getOptional("output_format") + /** + * The number of partial images to generate. This parameter is used for streaming responses + * that return partial images. Value must be between 0 and 3. When set to 0, the response + * will be a single image sent in one streaming event. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun partialImages(): Optional = partialImages.getOptional("partial_images") + /** * The quality of the image that will be generated. * - `auto` (default value) will automatically select the best quality for the given model. @@ -927,6 +987,16 @@ private constructor( @ExcludeMissing fun _outputFormat(): JsonField = outputFormat + /** + * Returns the raw JSON value of [partialImages]. + * + * Unlike [partialImages], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("partial_images") + @ExcludeMissing + fun _partialImages(): JsonField = partialImages + /** * Returns the raw JSON value of [quality]. * @@ -1000,6 +1070,7 @@ private constructor( private var n: JsonField = JsonMissing.of() private var outputCompression: JsonField = JsonMissing.of() private var outputFormat: JsonField = JsonMissing.of() + private var partialImages: JsonField = JsonMissing.of() private var quality: JsonField = JsonMissing.of() private var responseFormat: JsonField = JsonMissing.of() private var size: JsonField = JsonMissing.of() @@ -1016,6 +1087,7 @@ private constructor( n = body.n outputCompression = body.outputCompression outputFormat = body.outputFormat + partialImages = body.partialImages quality = body.quality responseFormat = body.responseFormat size = body.size @@ -1192,6 +1264,36 @@ private constructor( this.outputFormat = outputFormat } + /** + * The number of partial images to generate. This parameter is used for streaming + * responses that return partial images. Value must be between 0 and 3. When set to 0, + * the response will be a single image sent in one streaming event. + */ + fun partialImages(partialImages: Long?) = + partialImages(JsonField.ofNullable(partialImages)) + + /** + * Alias for [Builder.partialImages]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun partialImages(partialImages: Long) = partialImages(partialImages as Long?) + + /** Alias for calling [Builder.partialImages] with `partialImages.orElse(null)`. */ + fun partialImages(partialImages: Optional) = + partialImages(partialImages.getOrNull()) + + /** + * Sets [Builder.partialImages] to an arbitrary JSON value. + * + * You should usually call [Builder.partialImages] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun partialImages(partialImages: JsonField) = apply { + this.partialImages = partialImages + } + /** * The quality of the image that will be generated. * - `auto` (default value) will automatically select the best quality for the given @@ -1334,6 +1436,7 @@ private constructor( n, outputCompression, outputFormat, + partialImages, quality, responseFormat, size, @@ -1357,6 +1460,7 @@ private constructor( n() outputCompression() outputFormat().ifPresent { it.validate() } + partialImages() quality().ifPresent { it.validate() } responseFormat().ifPresent { it.validate() } size().ifPresent { it.validate() } @@ -1388,6 +1492,7 @@ private constructor( (if (n.asKnown().isPresent) 1 else 0) + (if (outputCompression.asKnown().isPresent) 1 else 0) + (outputFormat.asKnown().getOrNull()?.validity() ?: 0) + + (if (partialImages.asKnown().isPresent) 1 else 0) + (quality.asKnown().getOrNull()?.validity() ?: 0) + (responseFormat.asKnown().getOrNull()?.validity() ?: 0) + (size.asKnown().getOrNull()?.validity() ?: 0) + @@ -1399,17 +1504,17 @@ private constructor( return true } - return /* spotless:off */ other is Body && prompt == other.prompt && background == other.background && model == other.model && moderation == other.moderation && n == other.n && outputCompression == other.outputCompression && outputFormat == other.outputFormat && quality == other.quality && responseFormat == other.responseFormat && size == other.size && style == other.style && user == other.user && additionalProperties == other.additionalProperties /* spotless:on */ + return /* spotless:off */ other is Body && prompt == other.prompt && background == other.background && model == other.model && moderation == other.moderation && n == other.n && outputCompression == other.outputCompression && outputFormat == other.outputFormat && partialImages == other.partialImages && quality == other.quality && responseFormat == other.responseFormat && size == other.size && style == other.style && user == other.user && additionalProperties == other.additionalProperties /* spotless:on */ } /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(prompt, background, model, moderation, n, outputCompression, outputFormat, quality, responseFormat, size, style, user, additionalProperties) } + private val hashCode: Int by lazy { Objects.hash(prompt, background, model, moderation, n, outputCompression, outputFormat, partialImages, quality, responseFormat, size, style, user, additionalProperties) } /* spotless:on */ override fun hashCode(): Int = hashCode override fun toString() = - "Body{prompt=$prompt, background=$background, model=$model, moderation=$moderation, n=$n, outputCompression=$outputCompression, outputFormat=$outputFormat, quality=$quality, responseFormat=$responseFormat, size=$size, style=$style, user=$user, additionalProperties=$additionalProperties}" + "Body{prompt=$prompt, background=$background, model=$model, moderation=$moderation, n=$n, outputCompression=$outputCompression, outputFormat=$outputFormat, partialImages=$partialImages, quality=$quality, responseFormat=$responseFormat, size=$size, style=$style, user=$user, additionalProperties=$additionalProperties}" } /** diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseOutputRefusal.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseOutputRefusal.kt index 9248f645..a4ded1e1 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseOutputRefusal.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseOutputRefusal.kt @@ -30,7 +30,7 @@ private constructor( ) : this(refusal, type, mutableMapOf()) /** - * The refusal explanationfrom the model. + * The refusal explanation from the model. * * @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). @@ -96,7 +96,7 @@ private constructor( additionalProperties = responseOutputRefusal.additionalProperties.toMutableMap() } - /** The refusal explanationfrom the model. */ + /** The refusal explanation from the model. */ fun refusal(refusal: String) = refusal(JsonField.of(refusal)) /** diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/Tool.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/Tool.kt index a3697f5e..5c47b572 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/Tool.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/Tool.kt @@ -2915,6 +2915,7 @@ private constructor( private constructor( private val type: JsonValue, private val background: JsonField, + private val inputFidelity: JsonField, private val inputImageMask: JsonField, private val model: JsonField, private val moderation: JsonField, @@ -2932,6 +2933,9 @@ private constructor( @JsonProperty("background") @ExcludeMissing background: JsonField = JsonMissing.of(), + @JsonProperty("input_fidelity") + @ExcludeMissing + inputFidelity: JsonField = JsonMissing.of(), @JsonProperty("input_image_mask") @ExcludeMissing inputImageMask: JsonField = JsonMissing.of(), @@ -2953,6 +2957,7 @@ private constructor( ) : this( type, background, + inputFidelity, inputImageMask, model, moderation, @@ -2986,6 +2991,16 @@ private constructor( */ fun background(): Optional = background.getOptional("background") + /** + * Control how much effort the model will exert to match the style and features, especially + * facial features, of input images. This parameter is only supported for `gpt-image-1`. + * Supports `high` and `low`. Defaults to `low`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun inputFidelity(): Optional = inputFidelity.getOptional("input_fidelity") + /** * Optional mask for inpainting. Contains `image_url` (string, optional) and `file_id` * (string, optional). @@ -3065,6 +3080,16 @@ private constructor( @ExcludeMissing fun _background(): JsonField = background + /** + * Returns the raw JSON value of [inputFidelity]. + * + * Unlike [inputFidelity], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("input_fidelity") + @ExcludeMissing + fun _inputFidelity(): JsonField = inputFidelity + /** * Returns the raw JSON value of [inputImageMask]. * @@ -3158,6 +3183,7 @@ private constructor( private var type: JsonValue = JsonValue.from("image_generation") private var background: JsonField = JsonMissing.of() + private var inputFidelity: JsonField = JsonMissing.of() private var inputImageMask: JsonField = JsonMissing.of() private var model: JsonField = JsonMissing.of() private var moderation: JsonField = JsonMissing.of() @@ -3172,6 +3198,7 @@ private constructor( internal fun from(imageGeneration: ImageGeneration) = apply { type = imageGeneration.type background = imageGeneration.background + inputFidelity = imageGeneration.inputFidelity inputImageMask = imageGeneration.inputImageMask model = imageGeneration.model moderation = imageGeneration.moderation @@ -3214,6 +3241,29 @@ private constructor( this.background = background } + /** + * Control how much effort the model will exert to match the style and features, + * especially facial features, of input images. This parameter is only supported for + * `gpt-image-1`. Supports `high` and `low`. Defaults to `low`. + */ + fun inputFidelity(inputFidelity: InputFidelity?) = + inputFidelity(JsonField.ofNullable(inputFidelity)) + + /** Alias for calling [Builder.inputFidelity] with `inputFidelity.orElse(null)`. */ + fun inputFidelity(inputFidelity: Optional) = + inputFidelity(inputFidelity.getOrNull()) + + /** + * Sets [Builder.inputFidelity] to an arbitrary JSON value. + * + * You should usually call [Builder.inputFidelity] with a well-typed [InputFidelity] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun inputFidelity(inputFidelity: JsonField) = apply { + this.inputFidelity = inputFidelity + } + /** * Optional mask for inpainting. Contains `image_url` (string, optional) and `file_id` * (string, optional). @@ -3364,6 +3414,7 @@ private constructor( ImageGeneration( type, background, + inputFidelity, inputImageMask, model, moderation, @@ -3389,6 +3440,7 @@ private constructor( } } background().ifPresent { it.validate() } + inputFidelity().ifPresent { it.validate() } inputImageMask().ifPresent { it.validate() } model().ifPresent { it.validate() } moderation().ifPresent { it.validate() } @@ -3418,6 +3470,7 @@ private constructor( internal fun validity(): Int = type.let { if (it == JsonValue.from("image_generation")) 1 else 0 } + (background.asKnown().getOrNull()?.validity() ?: 0) + + (inputFidelity.asKnown().getOrNull()?.validity() ?: 0) + (inputImageMask.asKnown().getOrNull()?.validity() ?: 0) + (model.asKnown().getOrNull()?.validity() ?: 0) + (moderation.asKnown().getOrNull()?.validity() ?: 0) + @@ -3568,6 +3621,142 @@ private constructor( override fun toString() = value.toString() } + /** + * Control how much effort the model will exert to match the style and features, especially + * facial features, of input images. This parameter is only supported for `gpt-image-1`. + * Supports `high` and `low`. Defaults to `low`. + */ + class InputFidelity @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val HIGH = of("high") + + @JvmField val LOW = of("low") + + @JvmStatic fun of(value: String) = InputFidelity(JsonField.of(value)) + } + + /** An enum containing [InputFidelity]'s known values. */ + enum class Known { + HIGH, + LOW, + } + + /** + * An enum containing [InputFidelity]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [InputFidelity] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + HIGH, + LOW, + /** + * An enum member indicating that [InputFidelity] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you + * want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + HIGH -> Value.HIGH + LOW -> Value.LOW + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + HIGH -> Known.HIGH + LOW -> Known.LOW + else -> throw OpenAIInvalidDataException("Unknown InputFidelity: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + OpenAIInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): InputFidelity = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is InputFidelity && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + /** * Optional mask for inpainting. Contains `image_url` (string, optional) and `file_id` * (string, optional). @@ -4447,16 +4636,16 @@ private constructor( return true } - return /* spotless:off */ other is ImageGeneration && type == other.type && background == other.background && inputImageMask == other.inputImageMask && model == other.model && moderation == other.moderation && outputCompression == other.outputCompression && outputFormat == other.outputFormat && partialImages == other.partialImages && quality == other.quality && size == other.size && additionalProperties == other.additionalProperties /* spotless:on */ + return /* spotless:off */ other is ImageGeneration && type == other.type && background == other.background && inputFidelity == other.inputFidelity && inputImageMask == other.inputImageMask && model == other.model && moderation == other.moderation && outputCompression == other.outputCompression && outputFormat == other.outputFormat && partialImages == other.partialImages && quality == other.quality && size == other.size && additionalProperties == other.additionalProperties /* spotless:on */ } /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(type, background, inputImageMask, model, moderation, outputCompression, outputFormat, partialImages, quality, size, additionalProperties) } + private val hashCode: Int by lazy { Objects.hash(type, background, inputFidelity, inputImageMask, model, moderation, outputCompression, outputFormat, partialImages, quality, size, additionalProperties) } /* spotless:on */ override fun hashCode(): Int = hashCode override fun toString() = - "ImageGeneration{type=$type, background=$background, inputImageMask=$inputImageMask, model=$model, moderation=$moderation, outputCompression=$outputCompression, outputFormat=$outputFormat, partialImages=$partialImages, quality=$quality, size=$size, additionalProperties=$additionalProperties}" + "ImageGeneration{type=$type, background=$background, inputFidelity=$inputFidelity, inputImageMask=$inputImageMask, model=$model, moderation=$moderation, outputCompression=$outputCompression, outputFormat=$outputFormat, partialImages=$partialImages, quality=$quality, size=$size, additionalProperties=$additionalProperties}" } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/ImageServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/ImageServiceAsync.kt index 946ddbaa..a2daad9f 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/ImageServiceAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/ImageServiceAsync.kt @@ -2,11 +2,16 @@ package com.openai.services.async +import com.google.errorprone.annotations.MustBeClosed import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.http.AsyncStreamResponse import com.openai.core.http.HttpResponseFor +import com.openai.core.http.StreamResponse import com.openai.models.images.ImageCreateVariationParams import com.openai.models.images.ImageEditParams +import com.openai.models.images.ImageEditStreamEvent +import com.openai.models.images.ImageGenStreamEvent import com.openai.models.images.ImageGenerateParams import com.openai.models.images.ImagesResponse import java.util.concurrent.CompletableFuture @@ -49,6 +54,19 @@ interface ImageServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** + * Creates an edited or extended image given one or more source images and a prompt. This + * endpoint only supports `gpt-image-1` and `dall-e-2`. + */ + fun editStreaming(params: ImageEditParams): AsyncStreamResponse = + editStreaming(params, RequestOptions.none()) + + /** @see [editStreaming] */ + fun editStreaming( + params: ImageEditParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): AsyncStreamResponse + /** * Creates an image given a prompt. * [Learn more](https://platform.openai.com/docs/guides/images). @@ -62,6 +80,19 @@ interface ImageServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** + * Creates an image given a prompt. + * [Learn more](https://platform.openai.com/docs/guides/images). + */ + fun generateStreaming(params: ImageGenerateParams): AsyncStreamResponse = + generateStreaming(params, RequestOptions.none()) + + /** @see [generateStreaming] */ + fun generateStreaming( + params: ImageGenerateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): AsyncStreamResponse + /** A view of [ImageServiceAsync] that provides access to raw HTTP responses for each method. */ interface WithRawResponse { @@ -102,6 +133,23 @@ interface ImageServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** + * Returns a raw HTTP response for `post /images/edits`, but is otherwise the same as + * [ImageServiceAsync.editStreaming]. + */ + @MustBeClosed + fun editStreaming( + params: ImageEditParams + ): CompletableFuture>> = + editStreaming(params, RequestOptions.none()) + + /** @see [editStreaming] */ + @MustBeClosed + fun editStreaming( + params: ImageEditParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture>> + /** * Returns a raw HTTP response for `post /images/generations`, but is otherwise the same as * [ImageServiceAsync.generate]. @@ -116,5 +164,22 @@ interface ImageServiceAsync { params: ImageGenerateParams, requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + + /** + * Returns a raw HTTP response for `post /images/generations`, but is otherwise the same as + * [ImageServiceAsync.generateStreaming]. + */ + @MustBeClosed + fun generateStreaming( + params: ImageGenerateParams + ): CompletableFuture>> = + generateStreaming(params, RequestOptions.none()) + + /** @see [generateStreaming] */ + @MustBeClosed + fun generateStreaming( + params: ImageGenerateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture>> } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/ImageServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/ImageServiceAsyncImpl.kt index 63b4e9a5..b5383141 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/ImageServiceAsyncImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/ImageServiceAsyncImpl.kt @@ -3,21 +3,31 @@ package com.openai.services.async import com.openai.core.ClientOptions +import com.openai.core.JsonValue +import com.openai.core.MultipartField import com.openai.core.RequestOptions import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler +import com.openai.core.handlers.mapJson +import com.openai.core.handlers.sseHandler import com.openai.core.handlers.withErrorHandler +import com.openai.core.http.AsyncStreamResponse import com.openai.core.http.HttpMethod import com.openai.core.http.HttpRequest import com.openai.core.http.HttpResponse.Handler import com.openai.core.http.HttpResponseFor +import com.openai.core.http.StreamResponse import com.openai.core.http.json +import com.openai.core.http.map import com.openai.core.http.multipartFormData import com.openai.core.http.parseable +import com.openai.core.http.toAsync import com.openai.core.prepareAsync import com.openai.models.ErrorObject import com.openai.models.images.ImageCreateVariationParams import com.openai.models.images.ImageEditParams +import com.openai.models.images.ImageEditStreamEvent +import com.openai.models.images.ImageGenStreamEvent import com.openai.models.images.ImageGenerateParams import com.openai.models.images.ImagesResponse import java.util.concurrent.CompletableFuture @@ -49,6 +59,16 @@ class ImageServiceAsyncImpl internal constructor(private val clientOptions: Clie // post /images/edits withRawResponse().edit(params, requestOptions).thenApply { it.parse() } + override fun editStreaming( + params: ImageEditParams, + requestOptions: RequestOptions, + ): AsyncStreamResponse = + // post /images/edits + withRawResponse() + .editStreaming(params, requestOptions) + .thenApply { it.parse() } + .toAsync(clientOptions.streamHandlerExecutor) + override fun generate( params: ImageGenerateParams, requestOptions: RequestOptions, @@ -56,6 +76,16 @@ class ImageServiceAsyncImpl internal constructor(private val clientOptions: Clie // post /images/generations withRawResponse().generate(params, requestOptions).thenApply { it.parse() } + override fun generateStreaming( + params: ImageGenerateParams, + requestOptions: RequestOptions, + ): AsyncStreamResponse = + // post /images/generations + withRawResponse() + .generateStreaming(params, requestOptions) + .thenApply { it.parse() } + .toAsync(clientOptions.streamHandlerExecutor) + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : ImageServiceAsync.WithRawResponse { @@ -138,6 +168,46 @@ class ImageServiceAsyncImpl internal constructor(private val clientOptions: Clie } } + private val editStreamingHandler: Handler> = + sseHandler(clientOptions.jsonMapper) + .mapJson() + .withErrorHandler(errorHandler) + + override fun editStreaming( + params: ImageEditParams, + requestOptions: RequestOptions, + ): CompletableFuture>> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("images", "edits") + .body( + multipartFormData( + clientOptions.jsonMapper, + params._body() + ("stream" to MultipartField.of(true)), + ) + ) + .build() + .prepareAsync(clientOptions, params, deploymentModel = null) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .let { editStreamingHandler.handle(it) } + .let { streamResponse -> + if (requestOptions.responseValidation!!) { + streamResponse.map { it.validate() } + } else { + streamResponse + } + } + } + } + } + private val generateHandler: Handler = jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) @@ -172,5 +242,49 @@ class ImageServiceAsyncImpl internal constructor(private val clientOptions: Clie } } } + + private val generateStreamingHandler: Handler> = + sseHandler(clientOptions.jsonMapper) + .mapJson() + .withErrorHandler(errorHandler) + + override fun generateStreaming( + params: ImageGenerateParams, + requestOptions: RequestOptions, + ): CompletableFuture>> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("images", "generations") + .body( + json( + clientOptions.jsonMapper, + params + ._body() + .toBuilder() + .putAdditionalProperty("stream", JsonValue.from(true)) + .build(), + ) + ) + .build() + .prepareAsync(clientOptions, params, deploymentModel = null) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .let { generateStreamingHandler.handle(it) } + .let { streamResponse -> + if (requestOptions.responseValidation!!) { + streamResponse.map { it.validate() } + } else { + streamResponse + } + } + } + } + } } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/ImageService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/ImageService.kt index fe6c391a..00cc23cb 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/ImageService.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/ImageService.kt @@ -6,8 +6,11 @@ import com.google.errorprone.annotations.MustBeClosed import com.openai.core.ClientOptions import com.openai.core.RequestOptions import com.openai.core.http.HttpResponseFor +import com.openai.core.http.StreamResponse import com.openai.models.images.ImageCreateVariationParams import com.openai.models.images.ImageEditParams +import com.openai.models.images.ImageEditStreamEvent +import com.openai.models.images.ImageGenStreamEvent import com.openai.models.images.ImageGenerateParams import com.openai.models.images.ImagesResponse import java.util.function.Consumer @@ -48,6 +51,21 @@ interface ImageService { requestOptions: RequestOptions = RequestOptions.none(), ): ImagesResponse + /** + * Creates an edited or extended image given one or more source images and a prompt. This + * endpoint only supports `gpt-image-1` and `dall-e-2`. + */ + @MustBeClosed + fun editStreaming(params: ImageEditParams): StreamResponse = + editStreaming(params, RequestOptions.none()) + + /** @see [editStreaming] */ + @MustBeClosed + fun editStreaming( + params: ImageEditParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): StreamResponse + /** * Creates an image given a prompt. * [Learn more](https://platform.openai.com/docs/guides/images). @@ -61,6 +79,21 @@ interface ImageService { requestOptions: RequestOptions = RequestOptions.none(), ): ImagesResponse + /** + * Creates an image given a prompt. + * [Learn more](https://platform.openai.com/docs/guides/images). + */ + @MustBeClosed + fun generateStreaming(params: ImageGenerateParams): StreamResponse = + generateStreaming(params, RequestOptions.none()) + + /** @see [generateStreaming] */ + @MustBeClosed + fun generateStreaming( + params: ImageGenerateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): StreamResponse + /** A view of [ImageService] that provides access to raw HTTP responses for each method. */ interface WithRawResponse { @@ -101,6 +134,23 @@ interface ImageService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** + * Returns a raw HTTP response for `post /images/edits`, but is otherwise the same as + * [ImageService.editStreaming]. + */ + @MustBeClosed + fun editStreaming( + params: ImageEditParams + ): HttpResponseFor> = + editStreaming(params, RequestOptions.none()) + + /** @see [editStreaming] */ + @MustBeClosed + fun editStreaming( + params: ImageEditParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor> + /** * Returns a raw HTTP response for `post /images/generations`, but is otherwise the same as * [ImageService.generate]. @@ -115,5 +165,22 @@ interface ImageService { params: ImageGenerateParams, requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + + /** + * Returns a raw HTTP response for `post /images/generations`, but is otherwise the same as + * [ImageService.generateStreaming]. + */ + @MustBeClosed + fun generateStreaming( + params: ImageGenerateParams + ): HttpResponseFor> = + generateStreaming(params, RequestOptions.none()) + + /** @see [generateStreaming] */ + @MustBeClosed + fun generateStreaming( + params: ImageGenerateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor> } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/ImageServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/ImageServiceImpl.kt index faa63d58..5cc08430 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/ImageServiceImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/ImageServiceImpl.kt @@ -3,21 +3,29 @@ package com.openai.services.blocking import com.openai.core.ClientOptions +import com.openai.core.JsonValue +import com.openai.core.MultipartField import com.openai.core.RequestOptions import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler +import com.openai.core.handlers.mapJson +import com.openai.core.handlers.sseHandler import com.openai.core.handlers.withErrorHandler import com.openai.core.http.HttpMethod import com.openai.core.http.HttpRequest import com.openai.core.http.HttpResponse.Handler import com.openai.core.http.HttpResponseFor +import com.openai.core.http.StreamResponse import com.openai.core.http.json +import com.openai.core.http.map import com.openai.core.http.multipartFormData import com.openai.core.http.parseable import com.openai.core.prepare import com.openai.models.ErrorObject import com.openai.models.images.ImageCreateVariationParams import com.openai.models.images.ImageEditParams +import com.openai.models.images.ImageEditStreamEvent +import com.openai.models.images.ImageGenStreamEvent import com.openai.models.images.ImageGenerateParams import com.openai.models.images.ImagesResponse import java.util.function.Consumer @@ -45,6 +53,13 @@ class ImageServiceImpl internal constructor(private val clientOptions: ClientOpt // post /images/edits withRawResponse().edit(params, requestOptions).parse() + override fun editStreaming( + params: ImageEditParams, + requestOptions: RequestOptions, + ): StreamResponse = + // post /images/edits + withRawResponse().editStreaming(params, requestOptions).parse() + override fun generate( params: ImageGenerateParams, requestOptions: RequestOptions, @@ -52,6 +67,13 @@ class ImageServiceImpl internal constructor(private val clientOptions: ClientOpt // post /images/generations withRawResponse().generate(params, requestOptions).parse() + override fun generateStreaming( + params: ImageGenerateParams, + requestOptions: RequestOptions, + ): StreamResponse = + // post /images/generations + withRawResponse().generateStreaming(params, requestOptions).parse() + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : ImageService.WithRawResponse { @@ -60,9 +82,7 @@ class ImageServiceImpl internal constructor(private val clientOptions: ClientOpt override fun withOptions( modifier: Consumer ): ImageService.WithRawResponse = - ImageServiceImpl.WithRawResponseImpl( - clientOptions.toBuilder().apply(modifier::accept).build() - ) + WithRawResponseImpl(clientOptions.toBuilder().apply(modifier::accept).build()) private val createVariationHandler: Handler = jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) @@ -128,6 +148,43 @@ class ImageServiceImpl internal constructor(private val clientOptions: ClientOpt } } + private val editStreamingHandler: Handler> = + sseHandler(clientOptions.jsonMapper) + .mapJson() + .withErrorHandler(errorHandler) + + override fun editStreaming( + params: ImageEditParams, + requestOptions: RequestOptions, + ): HttpResponseFor> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("images", "edits") + .body( + multipartFormData( + clientOptions.jsonMapper, + params._body() + ("stream" to MultipartField.of(true)), + ) + ) + .build() + .prepare(clientOptions, params, deploymentModel = null) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .let { editStreamingHandler.handle(it) } + .let { streamResponse -> + if (requestOptions.responseValidation!!) { + streamResponse.map { it.validate() } + } else { + streamResponse + } + } + } + } + private val generateHandler: Handler = jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) @@ -159,5 +216,46 @@ class ImageServiceImpl internal constructor(private val clientOptions: ClientOpt } } } + + private val generateStreamingHandler: Handler> = + sseHandler(clientOptions.jsonMapper) + .mapJson() + .withErrorHandler(errorHandler) + + override fun generateStreaming( + params: ImageGenerateParams, + requestOptions: RequestOptions, + ): HttpResponseFor> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("images", "generations") + .body( + json( + clientOptions.jsonMapper, + params + ._body() + .toBuilder() + .putAdditionalProperty("stream", JsonValue.from(true)) + .build(), + ) + ) + .build() + .prepare(clientOptions, params, deploymentModel = null) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .let { generateStreamingHandler.handle(it) } + .let { streamResponse -> + if (requestOptions.responseValidation!!) { + streamResponse.map { it.validate() } + } else { + streamResponse + } + } + } + } } } diff --git a/openai-java-core/src/test/kotlin/com/openai/models/images/ImageEditCompletedEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/images/ImageEditCompletedEventTest.kt new file mode 100644 index 00000000..18cae519 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/images/ImageEditCompletedEventTest.kt @@ -0,0 +1,96 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.images + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class ImageEditCompletedEventTest { + + @Test + fun create() { + val imageEditCompletedEvent = + ImageEditCompletedEvent.builder() + .b64Json("b64_json") + .background(ImageEditCompletedEvent.Background.TRANSPARENT) + .createdAt(0L) + .outputFormat(ImageEditCompletedEvent.OutputFormat.PNG) + .quality(ImageEditCompletedEvent.Quality.LOW) + .size(ImageEditCompletedEvent.Size._1024X1024) + .usage( + ImageEditCompletedEvent.Usage.builder() + .inputTokens(0L) + .inputTokensDetails( + ImageEditCompletedEvent.Usage.InputTokensDetails.builder() + .imageTokens(0L) + .textTokens(0L) + .build() + ) + .outputTokens(0L) + .totalTokens(0L) + .build() + ) + .build() + + assertThat(imageEditCompletedEvent.b64Json()).isEqualTo("b64_json") + assertThat(imageEditCompletedEvent.background()) + .isEqualTo(ImageEditCompletedEvent.Background.TRANSPARENT) + assertThat(imageEditCompletedEvent.createdAt()).isEqualTo(0L) + assertThat(imageEditCompletedEvent.outputFormat()) + .isEqualTo(ImageEditCompletedEvent.OutputFormat.PNG) + assertThat(imageEditCompletedEvent.quality()).isEqualTo(ImageEditCompletedEvent.Quality.LOW) + assertThat(imageEditCompletedEvent.size()) + .isEqualTo(ImageEditCompletedEvent.Size._1024X1024) + assertThat(imageEditCompletedEvent.usage()) + .isEqualTo( + ImageEditCompletedEvent.Usage.builder() + .inputTokens(0L) + .inputTokensDetails( + ImageEditCompletedEvent.Usage.InputTokensDetails.builder() + .imageTokens(0L) + .textTokens(0L) + .build() + ) + .outputTokens(0L) + .totalTokens(0L) + .build() + ) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val imageEditCompletedEvent = + ImageEditCompletedEvent.builder() + .b64Json("b64_json") + .background(ImageEditCompletedEvent.Background.TRANSPARENT) + .createdAt(0L) + .outputFormat(ImageEditCompletedEvent.OutputFormat.PNG) + .quality(ImageEditCompletedEvent.Quality.LOW) + .size(ImageEditCompletedEvent.Size._1024X1024) + .usage( + ImageEditCompletedEvent.Usage.builder() + .inputTokens(0L) + .inputTokensDetails( + ImageEditCompletedEvent.Usage.InputTokensDetails.builder() + .imageTokens(0L) + .textTokens(0L) + .build() + ) + .outputTokens(0L) + .totalTokens(0L) + .build() + ) + .build() + + val roundtrippedImageEditCompletedEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(imageEditCompletedEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedImageEditCompletedEvent).isEqualTo(imageEditCompletedEvent) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/images/ImageEditParamsTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/images/ImageEditParamsTest.kt index 7d1174bd..6dc0a40a 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/images/ImageEditParamsTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/images/ImageEditParamsTest.kt @@ -15,11 +15,13 @@ internal class ImageEditParamsTest { .image("some content".byteInputStream()) .prompt("A cute baby sea otter wearing a beret") .background(ImageEditParams.Background.TRANSPARENT) + .inputFidelity(ImageEditParams.InputFidelity.HIGH) .mask("some content".byteInputStream()) .model(ImageModel.DALL_E_2) .n(1L) .outputCompression(100L) .outputFormat(ImageEditParams.OutputFormat.PNG) + .partialImages(1L) .quality(ImageEditParams.Quality.HIGH) .responseFormat(ImageEditParams.ResponseFormat.URL) .size(ImageEditParams.Size._1024X1024) @@ -34,11 +36,13 @@ internal class ImageEditParamsTest { .image("some content".byteInputStream()) .prompt("A cute baby sea otter wearing a beret") .background(ImageEditParams.Background.TRANSPARENT) + .inputFidelity(ImageEditParams.InputFidelity.HIGH) .mask("some content".byteInputStream()) .model(ImageModel.DALL_E_2) .n(1L) .outputCompression(100L) .outputFormat(ImageEditParams.OutputFormat.PNG) + .partialImages(1L) .quality(ImageEditParams.Quality.HIGH) .responseFormat(ImageEditParams.ResponseFormat.URL) .size(ImageEditParams.Size._1024X1024) @@ -65,11 +69,13 @@ internal class ImageEditParamsTest { ), "prompt" to MultipartField.of("A cute baby sea otter wearing a beret"), "background" to MultipartField.of(ImageEditParams.Background.TRANSPARENT), + "input_fidelity" to MultipartField.of(ImageEditParams.InputFidelity.HIGH), "mask" to MultipartField.of("some content".byteInputStream()), "model" to MultipartField.of(ImageModel.DALL_E_2), "n" to MultipartField.of(1L), "output_compression" to MultipartField.of(100L), "output_format" to MultipartField.of(ImageEditParams.OutputFormat.PNG), + "partial_images" to MultipartField.of(1L), "quality" to MultipartField.of(ImageEditParams.Quality.HIGH), "response_format" to MultipartField.of(ImageEditParams.ResponseFormat.URL), "size" to MultipartField.of(ImageEditParams.Size._1024X1024), diff --git a/openai-java-core/src/test/kotlin/com/openai/models/images/ImageEditPartialImageEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/images/ImageEditPartialImageEventTest.kt new file mode 100644 index 00000000..a636f6b1 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/images/ImageEditPartialImageEventTest.kt @@ -0,0 +1,60 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.images + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class ImageEditPartialImageEventTest { + + @Test + fun create() { + val imageEditPartialImageEvent = + ImageEditPartialImageEvent.builder() + .b64Json("b64_json") + .background(ImageEditPartialImageEvent.Background.TRANSPARENT) + .createdAt(0L) + .outputFormat(ImageEditPartialImageEvent.OutputFormat.PNG) + .partialImageIndex(0L) + .quality(ImageEditPartialImageEvent.Quality.LOW) + .size(ImageEditPartialImageEvent.Size._1024X1024) + .build() + + assertThat(imageEditPartialImageEvent.b64Json()).isEqualTo("b64_json") + assertThat(imageEditPartialImageEvent.background()) + .isEqualTo(ImageEditPartialImageEvent.Background.TRANSPARENT) + assertThat(imageEditPartialImageEvent.createdAt()).isEqualTo(0L) + assertThat(imageEditPartialImageEvent.outputFormat()) + .isEqualTo(ImageEditPartialImageEvent.OutputFormat.PNG) + assertThat(imageEditPartialImageEvent.partialImageIndex()).isEqualTo(0L) + assertThat(imageEditPartialImageEvent.quality()) + .isEqualTo(ImageEditPartialImageEvent.Quality.LOW) + assertThat(imageEditPartialImageEvent.size()) + .isEqualTo(ImageEditPartialImageEvent.Size._1024X1024) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val imageEditPartialImageEvent = + ImageEditPartialImageEvent.builder() + .b64Json("b64_json") + .background(ImageEditPartialImageEvent.Background.TRANSPARENT) + .createdAt(0L) + .outputFormat(ImageEditPartialImageEvent.OutputFormat.PNG) + .partialImageIndex(0L) + .quality(ImageEditPartialImageEvent.Quality.LOW) + .size(ImageEditPartialImageEvent.Size._1024X1024) + .build() + + val roundtrippedImageEditPartialImageEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(imageEditPartialImageEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedImageEditPartialImageEvent).isEqualTo(imageEditPartialImageEvent) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/images/ImageEditStreamEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/images/ImageEditStreamEventTest.kt new file mode 100644 index 00000000..19fedaa0 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/images/ImageEditStreamEventTest.kt @@ -0,0 +1,146 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.images + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.JsonValue +import com.openai.core.jsonMapper +import com.openai.errors.OpenAIInvalidDataException +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.EnumSource + +internal class ImageEditStreamEventTest { + + @Test + fun ofPartialImage() { + val partialImage = + ImageEditPartialImageEvent.builder() + .b64Json("b64_json") + .background(ImageEditPartialImageEvent.Background.TRANSPARENT) + .createdAt(0L) + .outputFormat(ImageEditPartialImageEvent.OutputFormat.PNG) + .partialImageIndex(0L) + .quality(ImageEditPartialImageEvent.Quality.LOW) + .size(ImageEditPartialImageEvent.Size._1024X1024) + .build() + + val imageEditStreamEvent = ImageEditStreamEvent.ofPartialImage(partialImage) + + assertThat(imageEditStreamEvent.partialImage()).contains(partialImage) + assertThat(imageEditStreamEvent.completed()).isEmpty + } + + @Test + fun ofPartialImageRoundtrip() { + val jsonMapper = jsonMapper() + val imageEditStreamEvent = + ImageEditStreamEvent.ofPartialImage( + ImageEditPartialImageEvent.builder() + .b64Json("b64_json") + .background(ImageEditPartialImageEvent.Background.TRANSPARENT) + .createdAt(0L) + .outputFormat(ImageEditPartialImageEvent.OutputFormat.PNG) + .partialImageIndex(0L) + .quality(ImageEditPartialImageEvent.Quality.LOW) + .size(ImageEditPartialImageEvent.Size._1024X1024) + .build() + ) + + val roundtrippedImageEditStreamEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(imageEditStreamEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedImageEditStreamEvent).isEqualTo(imageEditStreamEvent) + } + + @Test + fun ofCompleted() { + val completed = + ImageEditCompletedEvent.builder() + .b64Json("b64_json") + .background(ImageEditCompletedEvent.Background.TRANSPARENT) + .createdAt(0L) + .outputFormat(ImageEditCompletedEvent.OutputFormat.PNG) + .quality(ImageEditCompletedEvent.Quality.LOW) + .size(ImageEditCompletedEvent.Size._1024X1024) + .usage( + ImageEditCompletedEvent.Usage.builder() + .inputTokens(0L) + .inputTokensDetails( + ImageEditCompletedEvent.Usage.InputTokensDetails.builder() + .imageTokens(0L) + .textTokens(0L) + .build() + ) + .outputTokens(0L) + .totalTokens(0L) + .build() + ) + .build() + + val imageEditStreamEvent = ImageEditStreamEvent.ofCompleted(completed) + + assertThat(imageEditStreamEvent.partialImage()).isEmpty + assertThat(imageEditStreamEvent.completed()).contains(completed) + } + + @Test + fun ofCompletedRoundtrip() { + val jsonMapper = jsonMapper() + val imageEditStreamEvent = + ImageEditStreamEvent.ofCompleted( + ImageEditCompletedEvent.builder() + .b64Json("b64_json") + .background(ImageEditCompletedEvent.Background.TRANSPARENT) + .createdAt(0L) + .outputFormat(ImageEditCompletedEvent.OutputFormat.PNG) + .quality(ImageEditCompletedEvent.Quality.LOW) + .size(ImageEditCompletedEvent.Size._1024X1024) + .usage( + ImageEditCompletedEvent.Usage.builder() + .inputTokens(0L) + .inputTokensDetails( + ImageEditCompletedEvent.Usage.InputTokensDetails.builder() + .imageTokens(0L) + .textTokens(0L) + .build() + ) + .outputTokens(0L) + .totalTokens(0L) + .build() + ) + .build() + ) + + val roundtrippedImageEditStreamEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(imageEditStreamEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedImageEditStreamEvent).isEqualTo(imageEditStreamEvent) + } + + enum class IncompatibleJsonShapeTestCase(val value: JsonValue) { + BOOLEAN(JsonValue.from(false)), + STRING(JsonValue.from("invalid")), + INTEGER(JsonValue.from(-1)), + FLOAT(JsonValue.from(3.14)), + ARRAY(JsonValue.from(listOf("invalid", "array"))), + } + + @ParameterizedTest + @EnumSource + fun incompatibleJsonShapeDeserializesToUnknown(testCase: IncompatibleJsonShapeTestCase) { + val imageEditStreamEvent = + jsonMapper().convertValue(testCase.value, jacksonTypeRef()) + + val e = assertThrows { imageEditStreamEvent.validate() } + assertThat(e).hasMessageStartingWith("Unknown ") + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/images/ImageGenCompletedEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/images/ImageGenCompletedEventTest.kt new file mode 100644 index 00000000..25368338 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/images/ImageGenCompletedEventTest.kt @@ -0,0 +1,95 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.images + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class ImageGenCompletedEventTest { + + @Test + fun create() { + val imageGenCompletedEvent = + ImageGenCompletedEvent.builder() + .b64Json("b64_json") + .background(ImageGenCompletedEvent.Background.TRANSPARENT) + .createdAt(0L) + .outputFormat(ImageGenCompletedEvent.OutputFormat.PNG) + .quality(ImageGenCompletedEvent.Quality.LOW) + .size(ImageGenCompletedEvent.Size._1024X1024) + .usage( + ImageGenCompletedEvent.Usage.builder() + .inputTokens(0L) + .inputTokensDetails( + ImageGenCompletedEvent.Usage.InputTokensDetails.builder() + .imageTokens(0L) + .textTokens(0L) + .build() + ) + .outputTokens(0L) + .totalTokens(0L) + .build() + ) + .build() + + assertThat(imageGenCompletedEvent.b64Json()).isEqualTo("b64_json") + assertThat(imageGenCompletedEvent.background()) + .isEqualTo(ImageGenCompletedEvent.Background.TRANSPARENT) + assertThat(imageGenCompletedEvent.createdAt()).isEqualTo(0L) + assertThat(imageGenCompletedEvent.outputFormat()) + .isEqualTo(ImageGenCompletedEvent.OutputFormat.PNG) + assertThat(imageGenCompletedEvent.quality()).isEqualTo(ImageGenCompletedEvent.Quality.LOW) + assertThat(imageGenCompletedEvent.size()).isEqualTo(ImageGenCompletedEvent.Size._1024X1024) + assertThat(imageGenCompletedEvent.usage()) + .isEqualTo( + ImageGenCompletedEvent.Usage.builder() + .inputTokens(0L) + .inputTokensDetails( + ImageGenCompletedEvent.Usage.InputTokensDetails.builder() + .imageTokens(0L) + .textTokens(0L) + .build() + ) + .outputTokens(0L) + .totalTokens(0L) + .build() + ) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val imageGenCompletedEvent = + ImageGenCompletedEvent.builder() + .b64Json("b64_json") + .background(ImageGenCompletedEvent.Background.TRANSPARENT) + .createdAt(0L) + .outputFormat(ImageGenCompletedEvent.OutputFormat.PNG) + .quality(ImageGenCompletedEvent.Quality.LOW) + .size(ImageGenCompletedEvent.Size._1024X1024) + .usage( + ImageGenCompletedEvent.Usage.builder() + .inputTokens(0L) + .inputTokensDetails( + ImageGenCompletedEvent.Usage.InputTokensDetails.builder() + .imageTokens(0L) + .textTokens(0L) + .build() + ) + .outputTokens(0L) + .totalTokens(0L) + .build() + ) + .build() + + val roundtrippedImageGenCompletedEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(imageGenCompletedEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedImageGenCompletedEvent).isEqualTo(imageGenCompletedEvent) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/images/ImageGenPartialImageEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/images/ImageGenPartialImageEventTest.kt new file mode 100644 index 00000000..2ff6a261 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/images/ImageGenPartialImageEventTest.kt @@ -0,0 +1,60 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.images + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class ImageGenPartialImageEventTest { + + @Test + fun create() { + val imageGenPartialImageEvent = + ImageGenPartialImageEvent.builder() + .b64Json("b64_json") + .background(ImageGenPartialImageEvent.Background.TRANSPARENT) + .createdAt(0L) + .outputFormat(ImageGenPartialImageEvent.OutputFormat.PNG) + .partialImageIndex(0L) + .quality(ImageGenPartialImageEvent.Quality.LOW) + .size(ImageGenPartialImageEvent.Size._1024X1024) + .build() + + assertThat(imageGenPartialImageEvent.b64Json()).isEqualTo("b64_json") + assertThat(imageGenPartialImageEvent.background()) + .isEqualTo(ImageGenPartialImageEvent.Background.TRANSPARENT) + assertThat(imageGenPartialImageEvent.createdAt()).isEqualTo(0L) + assertThat(imageGenPartialImageEvent.outputFormat()) + .isEqualTo(ImageGenPartialImageEvent.OutputFormat.PNG) + assertThat(imageGenPartialImageEvent.partialImageIndex()).isEqualTo(0L) + assertThat(imageGenPartialImageEvent.quality()) + .isEqualTo(ImageGenPartialImageEvent.Quality.LOW) + assertThat(imageGenPartialImageEvent.size()) + .isEqualTo(ImageGenPartialImageEvent.Size._1024X1024) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val imageGenPartialImageEvent = + ImageGenPartialImageEvent.builder() + .b64Json("b64_json") + .background(ImageGenPartialImageEvent.Background.TRANSPARENT) + .createdAt(0L) + .outputFormat(ImageGenPartialImageEvent.OutputFormat.PNG) + .partialImageIndex(0L) + .quality(ImageGenPartialImageEvent.Quality.LOW) + .size(ImageGenPartialImageEvent.Size._1024X1024) + .build() + + val roundtrippedImageGenPartialImageEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(imageGenPartialImageEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedImageGenPartialImageEvent).isEqualTo(imageGenPartialImageEvent) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/images/ImageGenStreamEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/images/ImageGenStreamEventTest.kt new file mode 100644 index 00000000..a5996e8f --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/images/ImageGenStreamEventTest.kt @@ -0,0 +1,147 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.images + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.JsonValue +import com.openai.core.jsonMapper +import com.openai.errors.OpenAIInvalidDataException +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.EnumSource + +internal class ImageGenStreamEventTest { + + @Test + fun ofGenerationPartialImage() { + val generationPartialImage = + ImageGenPartialImageEvent.builder() + .b64Json("b64_json") + .background(ImageGenPartialImageEvent.Background.TRANSPARENT) + .createdAt(0L) + .outputFormat(ImageGenPartialImageEvent.OutputFormat.PNG) + .partialImageIndex(0L) + .quality(ImageGenPartialImageEvent.Quality.LOW) + .size(ImageGenPartialImageEvent.Size._1024X1024) + .build() + + val imageGenStreamEvent = + ImageGenStreamEvent.ofGenerationPartialImage(generationPartialImage) + + assertThat(imageGenStreamEvent.generationPartialImage()).contains(generationPartialImage) + assertThat(imageGenStreamEvent.generationCompleted()).isEmpty + } + + @Test + fun ofGenerationPartialImageRoundtrip() { + val jsonMapper = jsonMapper() + val imageGenStreamEvent = + ImageGenStreamEvent.ofGenerationPartialImage( + ImageGenPartialImageEvent.builder() + .b64Json("b64_json") + .background(ImageGenPartialImageEvent.Background.TRANSPARENT) + .createdAt(0L) + .outputFormat(ImageGenPartialImageEvent.OutputFormat.PNG) + .partialImageIndex(0L) + .quality(ImageGenPartialImageEvent.Quality.LOW) + .size(ImageGenPartialImageEvent.Size._1024X1024) + .build() + ) + + val roundtrippedImageGenStreamEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(imageGenStreamEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedImageGenStreamEvent).isEqualTo(imageGenStreamEvent) + } + + @Test + fun ofGenerationCompleted() { + val generationCompleted = + ImageGenCompletedEvent.builder() + .b64Json("b64_json") + .background(ImageGenCompletedEvent.Background.TRANSPARENT) + .createdAt(0L) + .outputFormat(ImageGenCompletedEvent.OutputFormat.PNG) + .quality(ImageGenCompletedEvent.Quality.LOW) + .size(ImageGenCompletedEvent.Size._1024X1024) + .usage( + ImageGenCompletedEvent.Usage.builder() + .inputTokens(0L) + .inputTokensDetails( + ImageGenCompletedEvent.Usage.InputTokensDetails.builder() + .imageTokens(0L) + .textTokens(0L) + .build() + ) + .outputTokens(0L) + .totalTokens(0L) + .build() + ) + .build() + + val imageGenStreamEvent = ImageGenStreamEvent.ofGenerationCompleted(generationCompleted) + + assertThat(imageGenStreamEvent.generationPartialImage()).isEmpty + assertThat(imageGenStreamEvent.generationCompleted()).contains(generationCompleted) + } + + @Test + fun ofGenerationCompletedRoundtrip() { + val jsonMapper = jsonMapper() + val imageGenStreamEvent = + ImageGenStreamEvent.ofGenerationCompleted( + ImageGenCompletedEvent.builder() + .b64Json("b64_json") + .background(ImageGenCompletedEvent.Background.TRANSPARENT) + .createdAt(0L) + .outputFormat(ImageGenCompletedEvent.OutputFormat.PNG) + .quality(ImageGenCompletedEvent.Quality.LOW) + .size(ImageGenCompletedEvent.Size._1024X1024) + .usage( + ImageGenCompletedEvent.Usage.builder() + .inputTokens(0L) + .inputTokensDetails( + ImageGenCompletedEvent.Usage.InputTokensDetails.builder() + .imageTokens(0L) + .textTokens(0L) + .build() + ) + .outputTokens(0L) + .totalTokens(0L) + .build() + ) + .build() + ) + + val roundtrippedImageGenStreamEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(imageGenStreamEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedImageGenStreamEvent).isEqualTo(imageGenStreamEvent) + } + + enum class IncompatibleJsonShapeTestCase(val value: JsonValue) { + BOOLEAN(JsonValue.from(false)), + STRING(JsonValue.from("invalid")), + INTEGER(JsonValue.from(-1)), + FLOAT(JsonValue.from(3.14)), + ARRAY(JsonValue.from(listOf("invalid", "array"))), + } + + @ParameterizedTest + @EnumSource + fun incompatibleJsonShapeDeserializesToUnknown(testCase: IncompatibleJsonShapeTestCase) { + val imageGenStreamEvent = + jsonMapper().convertValue(testCase.value, jacksonTypeRef()) + + val e = assertThrows { imageGenStreamEvent.validate() } + assertThat(e).hasMessageStartingWith("Unknown ") + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/images/ImageGenerateParamsTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/images/ImageGenerateParamsTest.kt index b08ab312..8cd1386e 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/images/ImageGenerateParamsTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/images/ImageGenerateParamsTest.kt @@ -17,6 +17,7 @@ internal class ImageGenerateParamsTest { .n(1L) .outputCompression(100L) .outputFormat(ImageGenerateParams.OutputFormat.PNG) + .partialImages(1L) .quality(ImageGenerateParams.Quality.MEDIUM) .responseFormat(ImageGenerateParams.ResponseFormat.URL) .size(ImageGenerateParams.Size._1024X1024) @@ -36,6 +37,7 @@ internal class ImageGenerateParamsTest { .n(1L) .outputCompression(100L) .outputFormat(ImageGenerateParams.OutputFormat.PNG) + .partialImages(1L) .quality(ImageGenerateParams.Quality.MEDIUM) .responseFormat(ImageGenerateParams.ResponseFormat.URL) .size(ImageGenerateParams.Size._1024X1024) @@ -52,6 +54,7 @@ internal class ImageGenerateParamsTest { assertThat(body.n()).contains(1L) assertThat(body.outputCompression()).contains(100L) assertThat(body.outputFormat()).contains(ImageGenerateParams.OutputFormat.PNG) + assertThat(body.partialImages()).contains(1L) assertThat(body.quality()).contains(ImageGenerateParams.Quality.MEDIUM) assertThat(body.responseFormat()).contains(ImageGenerateParams.ResponseFormat.URL) assertThat(body.size()).contains(ImageGenerateParams.Size._1024X1024) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ToolTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ToolTest.kt index 952d2f79..6ce60980 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ToolTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ToolTest.kt @@ -331,6 +331,7 @@ internal class ToolTest { val imageGeneration = Tool.ImageGeneration.builder() .background(Tool.ImageGeneration.Background.TRANSPARENT) + .inputFidelity(Tool.ImageGeneration.InputFidelity.HIGH) .inputImageMask( Tool.ImageGeneration.InputImageMask.builder() .fileId("file_id") @@ -365,6 +366,7 @@ internal class ToolTest { Tool.ofImageGeneration( Tool.ImageGeneration.builder() .background(Tool.ImageGeneration.Background.TRANSPARENT) + .inputFidelity(Tool.ImageGeneration.InputFidelity.HIGH) .inputImageMask( Tool.ImageGeneration.InputImageMask.builder() .fileId("file_id") diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/ImageServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/ImageServiceAsyncTest.kt index 66e8e4de..22903460 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/async/ImageServiceAsyncTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/ImageServiceAsyncTest.kt @@ -54,11 +54,13 @@ internal class ImageServiceAsyncTest { .image("some content".byteInputStream()) .prompt("A cute baby sea otter wearing a beret") .background(ImageEditParams.Background.TRANSPARENT) + .inputFidelity(ImageEditParams.InputFidelity.HIGH) .mask("some content".byteInputStream()) .model(ImageModel.DALL_E_2) .n(1L) .outputCompression(100L) .outputFormat(ImageEditParams.OutputFormat.PNG) + .partialImages(1L) .quality(ImageEditParams.Quality.HIGH) .responseFormat(ImageEditParams.ResponseFormat.URL) .size(ImageEditParams.Size._1024X1024) @@ -70,6 +72,42 @@ internal class ImageServiceAsyncTest { imagesResponse.validate() } + @Test + fun editStreaming() { + val client = + OpenAIOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val imageServiceAsync = client.images() + + val imagesResponseStreamResponse = + imageServiceAsync.editStreaming( + ImageEditParams.builder() + .image("some content".byteInputStream()) + .prompt("A cute baby sea otter wearing a beret") + .background(ImageEditParams.Background.TRANSPARENT) + .inputFidelity(ImageEditParams.InputFidelity.HIGH) + .mask("some content".byteInputStream()) + .model(ImageModel.DALL_E_2) + .n(1L) + .outputCompression(100L) + .outputFormat(ImageEditParams.OutputFormat.PNG) + .partialImages(1L) + .quality(ImageEditParams.Quality.HIGH) + .responseFormat(ImageEditParams.ResponseFormat.URL) + .size(ImageEditParams.Size._1024X1024) + .user("user-1234") + .build() + ) + + val onCompleteFuture = + imagesResponseStreamResponse + .subscribe { imagesResponse -> imagesResponse.validate() } + .onCompleteFuture() + onCompleteFuture.get() + } + @Test fun generate() { val client = @@ -89,6 +127,7 @@ internal class ImageServiceAsyncTest { .n(1L) .outputCompression(100L) .outputFormat(ImageGenerateParams.OutputFormat.PNG) + .partialImages(1L) .quality(ImageGenerateParams.Quality.MEDIUM) .responseFormat(ImageGenerateParams.ResponseFormat.URL) .size(ImageGenerateParams.Size._1024X1024) @@ -100,4 +139,39 @@ internal class ImageServiceAsyncTest { val imagesResponse = imagesResponseFuture.get() imagesResponse.validate() } + + @Test + fun generateStreaming() { + val client = + OpenAIOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val imageServiceAsync = client.images() + + val imagesResponseStreamResponse = + imageServiceAsync.generateStreaming( + ImageGenerateParams.builder() + .prompt("A cute baby sea otter") + .background(ImageGenerateParams.Background.TRANSPARENT) + .model(ImageModel.DALL_E_2) + .moderation(ImageGenerateParams.Moderation.LOW) + .n(1L) + .outputCompression(100L) + .outputFormat(ImageGenerateParams.OutputFormat.PNG) + .partialImages(1L) + .quality(ImageGenerateParams.Quality.MEDIUM) + .responseFormat(ImageGenerateParams.ResponseFormat.URL) + .size(ImageGenerateParams.Size._1024X1024) + .style(ImageGenerateParams.Style.VIVID) + .user("user-1234") + .build() + ) + + val onCompleteFuture = + imagesResponseStreamResponse + .subscribe { imagesResponse -> imagesResponse.validate() } + .onCompleteFuture() + onCompleteFuture.get() + } } diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/ImageServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/ImageServiceTest.kt index df8559c5..c014b8ef 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/blocking/ImageServiceTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/ImageServiceTest.kt @@ -53,11 +53,13 @@ internal class ImageServiceTest { .image("some content".byteInputStream()) .prompt("A cute baby sea otter wearing a beret") .background(ImageEditParams.Background.TRANSPARENT) + .inputFidelity(ImageEditParams.InputFidelity.HIGH) .mask("some content".byteInputStream()) .model(ImageModel.DALL_E_2) .n(1L) .outputCompression(100L) .outputFormat(ImageEditParams.OutputFormat.PNG) + .partialImages(1L) .quality(ImageEditParams.Quality.HIGH) .responseFormat(ImageEditParams.ResponseFormat.URL) .size(ImageEditParams.Size._1024X1024) @@ -68,6 +70,42 @@ internal class ImageServiceTest { imagesResponse.validate() } + @Test + fun editStreaming() { + val client = + OpenAIOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val imageService = client.images() + + val imagesResponseStreamResponse = + imageService.editStreaming( + ImageEditParams.builder() + .image("some content".byteInputStream()) + .prompt("A cute baby sea otter wearing a beret") + .background(ImageEditParams.Background.TRANSPARENT) + .inputFidelity(ImageEditParams.InputFidelity.HIGH) + .mask("some content".byteInputStream()) + .model(ImageModel.DALL_E_2) + .n(1L) + .outputCompression(100L) + .outputFormat(ImageEditParams.OutputFormat.PNG) + .partialImages(1L) + .quality(ImageEditParams.Quality.HIGH) + .responseFormat(ImageEditParams.ResponseFormat.URL) + .size(ImageEditParams.Size._1024X1024) + .user("user-1234") + .build() + ) + + imagesResponseStreamResponse.use { + imagesResponseStreamResponse.stream().forEach { imagesResponse -> + imagesResponse.validate() + } + } + } + @Test fun generate() { val client = @@ -87,6 +125,7 @@ internal class ImageServiceTest { .n(1L) .outputCompression(100L) .outputFormat(ImageGenerateParams.OutputFormat.PNG) + .partialImages(1L) .quality(ImageGenerateParams.Quality.MEDIUM) .responseFormat(ImageGenerateParams.ResponseFormat.URL) .size(ImageGenerateParams.Size._1024X1024) @@ -97,4 +136,39 @@ internal class ImageServiceTest { imagesResponse.validate() } + + @Test + fun generateStreaming() { + val client = + OpenAIOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val imageService = client.images() + + val imagesResponseStreamResponse = + imageService.generateStreaming( + ImageGenerateParams.builder() + .prompt("A cute baby sea otter") + .background(ImageGenerateParams.Background.TRANSPARENT) + .model(ImageModel.DALL_E_2) + .moderation(ImageGenerateParams.Moderation.LOW) + .n(1L) + .outputCompression(100L) + .outputFormat(ImageGenerateParams.OutputFormat.PNG) + .partialImages(1L) + .quality(ImageGenerateParams.Quality.MEDIUM) + .responseFormat(ImageGenerateParams.ResponseFormat.URL) + .size(ImageGenerateParams.Size._1024X1024) + .style(ImageGenerateParams.Style.VIVID) + .user("user-1234") + .build() + ) + + imagesResponseStreamResponse.use { + imagesResponseStreamResponse.stream().forEach { imagesResponse -> + imagesResponse.validate() + } + } + } } diff --git a/openai-java-example/src/main/java/com/openai/example/ImageStreamingExample.java b/openai-java-example/src/main/java/com/openai/example/ImageStreamingExample.java new file mode 100644 index 00000000..8110fe10 --- /dev/null +++ b/openai-java-example/src/main/java/com/openai/example/ImageStreamingExample.java @@ -0,0 +1,74 @@ +package com.openai.example; + +import com.openai.client.OpenAIClient; +import com.openai.client.okhttp.OpenAIOkHttpClient; +import com.openai.core.http.StreamResponse; +import com.openai.models.images.*; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Base64; + +public final class ImageStreamingExample { + private ImageStreamingExample() {} + + public static void main(String[] args) throws IOException { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + System.out.println("Starting image streaming example..."); + + ImageGenerateParams params = ImageGenerateParams.builder() + .model(ImageModel.GPT_IMAGE_1) + .prompt("A cute baby sea otter") + .n(1L) + .size(ImageGenerateParams.Size._1024X1024) + .partialImages(3L) + .build(); + + StreamResponse stream = client.images().generateStreaming(params); + + stream.stream().forEach(event -> { + try { + if (event.isGenerationPartialImage()) { + ImageGenPartialImageEvent partialEvent = event.asGenerationPartialImage(); + System.out.printf(" Partial image %d/3 received%n", partialEvent.partialImageIndex() + 1); + System.out.printf( + " Size: %d characters (base64)%n", + partialEvent.b64Json().length()); + + // Save partial image to file + String filename = String.format("partial_%d.png", partialEvent.partialImageIndex() + 1); + saveBase64Image(partialEvent.b64Json(), filename); + Path absolutePath = Paths.get(filename).toAbsolutePath(); + System.out.printf(" šŸ’¾ Saved to: %s%n", absolutePath); + + } else if (event.isGenerationCompleted()) { + ImageGenCompletedEvent completedEvent = event.asGenerationCompleted(); + System.out.println("\nāœ… Final image completed!"); + System.out.printf( + " Size: %d characters (base64)%n", + completedEvent.b64Json().length()); + + // Save final image to file + String filename = "final_image.png"; + saveBase64Image(completedEvent.b64Json(), filename); + Path absolutePath = Paths.get(filename).toAbsolutePath(); + System.out.printf(" šŸ’¾ Saved to: %s%n", absolutePath); + + } else { + System.out.println("ā“ Unknown event received"); + } + } catch (IOException e) { + System.err.println("Error saving image: " + e.getMessage()); + } + }); + + System.out.println("Image streaming completed!"); + } + + private static void saveBase64Image(String b64Data, String filename) throws IOException { + byte[] imageData = Base64.getDecoder().decode(b64Data); + Files.write(Paths.get(filename), imageData); + } +} From d363245365a618bfd75e05f905af4eda90d24e96 Mon Sep 17 00:00:00 2001 From: David Meadows Date: Wed, 16 Jul 2025 15:04:39 -0400 Subject: [PATCH 4/7] fix(internal): add back addAssistantMessage --- .../StructuredChatCompletionCreateParams.kt | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/StructuredChatCompletionCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/StructuredChatCompletionCreateParams.kt index 8c67696f..20eec834 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/StructuredChatCompletionCreateParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/StructuredChatCompletionCreateParams.kt @@ -139,6 +139,28 @@ internal constructor( paramsBuilder.addMessage(assistant) } + /** @see ChatCompletionCreateParams.Builder.addAssistantMessage */ + fun addAssistantMessage(content: ChatCompletionAssistantMessageParam.Content?) = apply { + paramsBuilder.addAssistantMessage(content) + } + + /** @see ChatCompletionCreateParams.Builder.addAssistantMessage */ + fun addAssistantMessage(content: Optional) = + apply { + paramsBuilder.addAssistantMessage(content) + } + + /** @see ChatCompletionCreateParams.Builder.addAssistantMessage */ + fun addAssistantMessage(text: String) = apply { paramsBuilder.addAssistantMessage(text) } + + /** @see ChatCompletionCreateParams.Builder.addAssistantMessageOfArrayOfContentParts */ + fun addAssistantMessageOfArrayOfContentParts( + arrayOfContentParts: + List< + ChatCompletionAssistantMessageParam.Content.ChatCompletionRequestAssistantMessageContentPart + > + ) = apply { paramsBuilder.addAssistantMessageOfArrayOfContentParts(arrayOfContentParts) } + /** @see ChatCompletionCreateParams.Builder.addMessage */ fun addMessage(tool: ChatCompletionToolMessageParam) = apply { paramsBuilder.addMessage(tool) From 7bedb3a568ee44137c860fb5e7ca92b60772bc41 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 16 Jul 2025 19:09:04 +0000 Subject: [PATCH 5/7] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index e9e1048c..100cfb7c 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 88 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-670ea0d2cc44f52a87dd3cadea45632953283e0636ba30788fdbdb22a232ccac.yml openapi_spec_hash: d8b7d38911fead545adf3e4297956410 -config_hash: 5525bda35e48ea6387c6175c4d1651fa +config_hash: b2a4028fdbb27a08de89831ed310e244 From e27b476b2c4e8287407b40bc2e683c33af992c43 Mon Sep 17 00:00:00 2001 From: David Meadows Date: Wed, 16 Jul 2025 15:39:20 -0400 Subject: [PATCH 6/7] fix(internal): add back addAssistantMessage From 4c787fd2e5be254f325475b09a1e1f3430b4a7d5 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 16 Jul 2025 19:40:28 +0000 Subject: [PATCH 7/7] release: 2.14.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 20 ++++++++++++++++++++ README.md | 10 +++++----- build.gradle.kts | 2 +- 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index a042f3d3..58682893 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.13.1" + ".": "2.14.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index af2892ad..3b4858db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,25 @@ # Changelog +## 2.14.0 (2025-07-16) + +Full Changelog: [v2.13.1...v2.14.0](https://github.com/openai/openai-java/compare/v2.13.1...v2.14.0) + +### Features + +* **api:** manual updates ([d3dd5be](https://github.com/openai/openai-java/commit/d3dd5be0c6797f7f7fb7935df27b7ad67177f6ea)) + + +### Bug Fixes + +* **internal:** add back addAssistantMessage ([e27b476](https://github.com/openai/openai-java/commit/e27b476b2c4e8287407b40bc2e683c33af992c43)) +* **internal:** add back addAssistantMessage ([d363245](https://github.com/openai/openai-java/commit/d363245365a618bfd75e05f905af4eda90d24e96)) + + +### Chores + +* **api:** update realtime specs ([dd24c50](https://github.com/openai/openai-java/commit/dd24c500f029db5c1d38e9659eafb3bcd4d6fe99)) +* **ci:** bump `actions/setup-java` to v4 ([e5112cd](https://github.com/openai/openai-java/commit/e5112cdb3d411357886c334b15cc3de62e2fc9c3)) + ## 2.13.1 (2025-07-15) Full Changelog: [v2.13.0...v2.13.1](https://github.com/openai/openai-java/compare/v2.13.0...v2.13.1) diff --git a/README.md b/README.md index 0ad4362e..67ea87d5 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/2.13.1) -[![javadoc](https://javadoc.io/badge2/com.openai/openai-java/2.13.1/javadoc.svg)](https://javadoc.io/doc/com.openai/openai-java/2.13.1) +[![Maven Central](https://img.shields.io/maven-central/v/com.openai/openai-java)](https://central.sonatype.com/artifact/com.openai/openai-java/2.14.0) +[![javadoc](https://javadoc.io/badge2/com.openai/openai-java/2.14.0/javadoc.svg)](https://javadoc.io/doc/com.openai/openai-java/2.14.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/2.13.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/2.14.0). @@ -22,7 +22,7 @@ The REST API documentation can be found on [platform.openai.com](https://platfor ### Gradle ```kotlin -implementation("com.openai:openai-java:2.13.1") +implementation("com.openai:openai-java:2.14.0") ``` ### Maven @@ -31,7 +31,7 @@ implementation("com.openai:openai-java:2.13.1") com.openai openai-java - 2.13.1 + 2.14.0 ``` diff --git a/build.gradle.kts b/build.gradle.kts index 280c35b0..79685bb9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ repositories { allprojects { group = "com.openai" - version = "2.13.1" // x-release-please-version + version = "2.14.0" // x-release-please-version } subprojects {