diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index a43b15a4..03276cfb 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "4.11.0"
+ ".": "4.12.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index da4ec1f6..a6811613 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 136
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-41f98da99f44ebe6204fce5c1dc9940f85f3472779e797b674c4fdc20306c77d.yml
-openapi_spec_hash: c61259027f421f501bdc6b23cf9e430e
-config_hash: 141b101c9f13b90e21af74e1686f1f41
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-fe8e67bdc351a518b113ab48e775750190e207807903d6b03ab22c438c38a588.yml
+openapi_spec_hash: 8af972190647ffb9dcec516e19d8761a
+config_hash: 856bee50ee3617e85a9bc9274db01dbb
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0752c1a4..5f1df44c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,14 @@
# Changelog
+## 4.12.0 (2025-12-15)
+
+Full Changelog: [v4.11.0...v4.12.0](https://github.com/openai/openai-java/compare/v4.11.0...v4.12.0)
+
+### Features
+
+* **api:** api update ([29174d7](https://github.com/openai/openai-java/commit/29174d7275d95ef5a6d4f88d4ebe2bcd178746b5))
+* **api:** fix grader input list, add dated slugs for sora-2 ([f75af83](https://github.com/openai/openai-java/commit/f75af830fdaf2874313c125a8de0aecde6f447b7))
+
## 4.11.0 (2025-12-12)
Full Changelog: [v4.10.0...v4.11.0](https://github.com/openai/openai-java/compare/v4.10.0...v4.11.0)
diff --git a/README.md b/README.md
index 6136d625..91e42936 100644
--- a/README.md
+++ b/README.md
@@ -2,8 +2,8 @@
-[](https://central.sonatype.com/artifact/com.openai/openai-java/4.11.0)
-[](https://javadoc.io/doc/com.openai/openai-java/4.11.0)
+[](https://central.sonatype.com/artifact/com.openai/openai-java/4.12.0)
+[](https://javadoc.io/doc/com.openai/openai-java/4.12.0)
@@ -11,7 +11,7 @@ The OpenAI Java SDK provides convenient access to the [OpenAI REST API](https://
-The REST API documentation can be found on [platform.openai.com](https://platform.openai.com/docs). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.openai/openai-java/4.11.0).
+The REST API documentation can be found on [platform.openai.com](https://platform.openai.com/docs). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.openai/openai-java/4.12.0).
@@ -24,7 +24,7 @@ The REST API documentation can be found on [platform.openai.com](https://platfor
### Gradle
```kotlin
-implementation("com.openai:openai-java:4.11.0")
+implementation("com.openai:openai-java:4.12.0")
```
### Maven
@@ -33,7 +33,7 @@ implementation("com.openai:openai-java:4.11.0")
com.openai
openai-java
- 4.11.0
+ 4.12.0
```
@@ -1342,7 +1342,7 @@ If you're using Spring Boot, then you can use the SDK's [Spring Boot starter](ht
#### Gradle
```kotlin
-implementation("com.openai:openai-java-spring-boot-starter:4.11.0")
+implementation("com.openai:openai-java-spring-boot-starter:4.12.0")
```
#### Maven
@@ -1351,7 +1351,7 @@ implementation("com.openai:openai-java-spring-boot-starter:4.11.0")
com.openai
openai-java-spring-boot-starter
- 4.11.0
+ 4.12.0
```
diff --git a/build.gradle.kts b/build.gradle.kts
index 01745c5a..0aac8875 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -8,7 +8,7 @@ repositories {
allprojects {
group = "com.openai"
- version = "4.11.0" // x-release-please-version
+ version = "4.12.0" // x-release-please-version
}
subprojects {
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalCreateParams.kt
index 7807447f..1974483f 100644
--- a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalCreateParams.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalCreateParams.kt
@@ -29,6 +29,7 @@ import com.openai.core.http.Headers
import com.openai.core.http.QueryParams
import com.openai.core.toImmutable
import com.openai.errors.OpenAIInvalidDataException
+import com.openai.models.EvalContentItem
import com.openai.models.graders.gradermodels.PythonGrader
import com.openai.models.graders.gradermodels.ScoreModelGrader
import com.openai.models.graders.gradermodels.StringCheckGrader
@@ -3239,7 +3240,9 @@ private constructor(
) : this(content, role, type, mutableMapOf())
/**
- * Inputs to the model - can contain template strings.
+ * Inputs to the model - can contain template strings. Supports text, output
+ * text, input images, and input audio, either as a single item or an array of
+ * items.
*
* @throws OpenAIInvalidDataException if the JSON field has an unexpected type
* or is unexpectedly missing or null (e.g. if the server responded with an
@@ -3334,7 +3337,11 @@ private constructor(
additionalProperties = evalItem.additionalProperties.toMutableMap()
}
- /** Inputs to the model - can contain template strings. */
+ /**
+ * Inputs to the model - can contain template strings. Supports text, output
+ * text, input images, and input audio, either as a single item or an array
+ * of items.
+ */
fun content(content: Content) = content(JsonField.of(content))
/**
@@ -3372,17 +3379,10 @@ private constructor(
content(Content.ofResponseInputAudio(responseInputAudio))
/**
- * Alias for calling [content] with
- * `Content.ofAnArrayOfInputTextInputImageAndInputAudio(anArrayOfInputTextInputImageAndInputAudio)`.
+ * Alias for calling [content] with `Content.ofGraderInputs(graderInputs)`.
*/
- fun contentOfAnArrayOfInputTextInputImageAndInputAudio(
- anArrayOfInputTextInputImageAndInputAudio: List
- ) =
- content(
- Content.ofAnArrayOfInputTextInputImageAndInputAudio(
- anArrayOfInputTextInputImageAndInputAudio
- )
- )
+ fun contentOfGraderInputs(graderInputs: List) =
+ content(Content.ofGraderInputs(graderInputs))
/**
* The role of the message input. One of `user`, `assistant`, `system`, or
@@ -3488,7 +3488,11 @@ private constructor(
(role.asKnown().getOrNull()?.validity() ?: 0) +
(type.asKnown().getOrNull()?.validity() ?: 0)
- /** Inputs to the model - can contain template strings. */
+ /**
+ * Inputs to the model - can contain template strings. Supports text, output
+ * text, input images, and input audio, either as a single item or an array of
+ * items.
+ */
@JsonDeserialize(using = Content.Deserializer::class)
@JsonSerialize(using = Content.Serializer::class)
class Content
@@ -3498,8 +3502,7 @@ private constructor(
private val outputText: OutputText? = null,
private val inputImage: InputImage? = null,
private val responseInputAudio: ResponseInputAudio? = null,
- private val anArrayOfInputTextInputImageAndInputAudio: List? =
- null,
+ private val graderInputs: List? = null,
private val _json: JsonValue? = null,
) {
@@ -3513,7 +3516,7 @@ private constructor(
/** A text output from the model. */
fun outputText(): Optional = Optional.ofNullable(outputText)
- /** An image input to the model. */
+ /** An image input block used within EvalItem content arrays. */
fun inputImage(): Optional = Optional.ofNullable(inputImage)
/** An audio input to the model. */
@@ -3521,11 +3524,11 @@ private constructor(
Optional.ofNullable(responseInputAudio)
/**
- * A list of inputs, each of which may be either an input text, input image,
- * or input audio object.
+ * A list of inputs, each of which may be either an input text, output text,
+ * input image, or input audio object.
*/
- fun anArrayOfInputTextInputImageAndInputAudio(): Optional> =
- Optional.ofNullable(anArrayOfInputTextInputImageAndInputAudio)
+ fun graderInputs(): Optional> =
+ Optional.ofNullable(graderInputs)
fun isTextInput(): Boolean = textInput != null
@@ -3537,8 +3540,7 @@ private constructor(
fun isResponseInputAudio(): Boolean = responseInputAudio != null
- fun isAnArrayOfInputTextInputImageAndInputAudio(): Boolean =
- anArrayOfInputTextInputImageAndInputAudio != null
+ fun isGraderInputs(): Boolean = graderInputs != null
/** A text input to the model. */
fun asTextInput(): String = textInput.getOrThrow("textInput")
@@ -3550,7 +3552,7 @@ private constructor(
/** A text output from the model. */
fun asOutputText(): OutputText = outputText.getOrThrow("outputText")
- /** An image input to the model. */
+ /** An image input block used within EvalItem content arrays. */
fun asInputImage(): InputImage = inputImage.getOrThrow("inputImage")
/** An audio input to the model. */
@@ -3558,13 +3560,11 @@ private constructor(
responseInputAudio.getOrThrow("responseInputAudio")
/**
- * A list of inputs, each of which may be either an input text, input image,
- * or input audio object.
+ * A list of inputs, each of which may be either an input text, output text,
+ * input image, or input audio object.
*/
- fun asAnArrayOfInputTextInputImageAndInputAudio(): List =
- anArrayOfInputTextInputImageAndInputAudio.getOrThrow(
- "anArrayOfInputTextInputImageAndInputAudio"
- )
+ fun asGraderInputs(): List =
+ graderInputs.getOrThrow("graderInputs")
fun _json(): Optional = Optional.ofNullable(_json)
@@ -3577,10 +3577,7 @@ private constructor(
inputImage != null -> visitor.visitInputImage(inputImage)
responseInputAudio != null ->
visitor.visitResponseInputAudio(responseInputAudio)
- anArrayOfInputTextInputImageAndInputAudio != null ->
- visitor.visitAnArrayOfInputTextInputImageAndInputAudio(
- anArrayOfInputTextInputImageAndInputAudio
- )
+ graderInputs != null -> visitor.visitGraderInputs(graderInputs)
else -> visitor.unknown(_json)
}
@@ -3615,9 +3612,11 @@ private constructor(
responseInputAudio.validate()
}
- override fun visitAnArrayOfInputTextInputImageAndInputAudio(
- anArrayOfInputTextInputImageAndInputAudio: List
- ) {}
+ override fun visitGraderInputs(
+ graderInputs: List
+ ) {
+ graderInputs.forEach { it.validate() }
+ }
}
)
validated = true
@@ -3657,9 +3656,9 @@ private constructor(
responseInputAudio: ResponseInputAudio
) = responseInputAudio.validity()
- override fun visitAnArrayOfInputTextInputImageAndInputAudio(
- anArrayOfInputTextInputImageAndInputAudio: List
- ) = anArrayOfInputTextInputImageAndInputAudio.size
+ override fun visitGraderInputs(
+ graderInputs: List
+ ) = graderInputs.sumOf { it.validity().toInt() }
override fun unknown(json: JsonValue?) = 0
}
@@ -3676,8 +3675,7 @@ private constructor(
outputText == other.outputText &&
inputImage == other.inputImage &&
responseInputAudio == other.responseInputAudio &&
- anArrayOfInputTextInputImageAndInputAudio ==
- other.anArrayOfInputTextInputImageAndInputAudio
+ graderInputs == other.graderInputs
}
override fun hashCode(): Int =
@@ -3687,7 +3685,7 @@ private constructor(
outputText,
inputImage,
responseInputAudio,
- anArrayOfInputTextInputImageAndInputAudio,
+ graderInputs,
)
override fun toString(): String =
@@ -3699,8 +3697,7 @@ private constructor(
inputImage != null -> "Content{inputImage=$inputImage}"
responseInputAudio != null ->
"Content{responseInputAudio=$responseInputAudio}"
- anArrayOfInputTextInputImageAndInputAudio != null ->
- "Content{anArrayOfInputTextInputImageAndInputAudio=$anArrayOfInputTextInputImageAndInputAudio}"
+ graderInputs != null -> "Content{graderInputs=$graderInputs}"
_json != null -> "Content{_unknown=$_json}"
else -> throw IllegalStateException("Invalid Content")
}
@@ -3721,7 +3718,7 @@ private constructor(
fun ofOutputText(outputText: OutputText) =
Content(outputText = outputText)
- /** An image input to the model. */
+ /** An image input block used within EvalItem content arrays. */
@JvmStatic
fun ofInputImage(inputImage: InputImage) =
Content(inputImage = inputImage)
@@ -3732,17 +3729,12 @@ private constructor(
Content(responseInputAudio = responseInputAudio)
/**
- * A list of inputs, each of which may be either an input text, input
- * image, or input audio object.
+ * A list of inputs, each of which may be either an input text, output
+ * text, input image, or input audio object.
*/
@JvmStatic
- fun ofAnArrayOfInputTextInputImageAndInputAudio(
- anArrayOfInputTextInputImageAndInputAudio: List
- ) =
- Content(
- anArrayOfInputTextInputImageAndInputAudio =
- anArrayOfInputTextInputImageAndInputAudio.toImmutable()
- )
+ fun ofGraderInputs(graderInputs: List) =
+ Content(graderInputs = graderInputs.toImmutable())
}
/**
@@ -3760,19 +3752,17 @@ private constructor(
/** A text output from the model. */
fun visitOutputText(outputText: OutputText): T
- /** An image input to the model. */
+ /** An image input block used within EvalItem content arrays. */
fun visitInputImage(inputImage: InputImage): T
/** An audio input to the model. */
fun visitResponseInputAudio(responseInputAudio: ResponseInputAudio): T
/**
- * A list of inputs, each of which may be either an input text, input
- * image, or input audio object.
+ * A list of inputs, each of which may be either an input text, output
+ * text, input image, or input audio object.
*/
- fun visitAnArrayOfInputTextInputImageAndInputAudio(
- anArrayOfInputTextInputImageAndInputAudio: List
- ): T
+ fun visitGraderInputs(graderInputs: List): T
/**
* Maps an unknown variant of [Content] to a value of type [T].
@@ -3817,14 +3807,11 @@ private constructor(
tryDeserialize(node, jacksonTypeRef())?.let {
Content(textInput = it, _json = json)
},
- tryDeserialize(node, jacksonTypeRef>())
- ?.let {
- Content(
- anArrayOfInputTextInputImageAndInputAudio =
- it,
- _json = json,
- )
- },
+ tryDeserialize(
+ node,
+ jacksonTypeRef>(),
+ )
+ ?.let { Content(graderInputs = it, _json = json) },
)
.filterNotNull()
.allMaxBy { it.validity() }
@@ -3862,10 +3849,8 @@ private constructor(
generator.writeObject(value.inputImage)
value.responseInputAudio != null ->
generator.writeObject(value.responseInputAudio)
- value.anArrayOfInputTextInputImageAndInputAudio != null ->
- generator.writeObject(
- value.anArrayOfInputTextInputImageAndInputAudio
- )
+ value.graderInputs != null ->
+ generator.writeObject(value.graderInputs)
value._json != null -> generator.writeObject(value._json)
else -> throw IllegalStateException("Invalid Content")
}
@@ -4093,7 +4078,7 @@ private constructor(
"OutputText{text=$text, type=$type, additionalProperties=$additionalProperties}"
}
- /** An image input to the model. */
+ /** An image input block used within EvalItem content arrays. */
class InputImage
@JsonCreator(mode = JsonCreator.Mode.DISABLED)
private constructor(
@@ -4362,6 +4347,860 @@ private constructor(
override fun toString() =
"InputImage{imageUrl=$imageUrl, type=$type, detail=$detail, additionalProperties=$additionalProperties}"
}
+
+ /**
+ * A single content item: input text, output text, input image, or input
+ * audio.
+ */
+ @JsonDeserialize(using = EvalContentItem.Deserializer::class)
+ @JsonSerialize(using = EvalContentItem.Serializer::class)
+ class EvalContentItem
+ private constructor(
+ private val textInput: String? = null,
+ private val responseInputText: ResponseInputText? = null,
+ private val outputText: OutputText? = null,
+ private val inputImage: InputImage? = null,
+ private val responseInputAudio: ResponseInputAudio? = null,
+ private val _json: JsonValue? = null,
+ ) {
+
+ /** A text input to the model. */
+ fun textInput(): Optional = Optional.ofNullable(textInput)
+
+ /** A text input to the model. */
+ fun responseInputText(): Optional =
+ Optional.ofNullable(responseInputText)
+
+ /** A text output from the model. */
+ fun outputText(): Optional = Optional.ofNullable(outputText)
+
+ /** An image input block used within EvalItem content arrays. */
+ fun inputImage(): Optional = Optional.ofNullable(inputImage)
+
+ /** An audio input to the model. */
+ fun responseInputAudio(): Optional =
+ Optional.ofNullable(responseInputAudio)
+
+ fun isTextInput(): Boolean = textInput != null
+
+ fun isResponseInputText(): Boolean = responseInputText != null
+
+ fun isOutputText(): Boolean = outputText != null
+
+ fun isInputImage(): Boolean = inputImage != null
+
+ fun isResponseInputAudio(): Boolean = responseInputAudio != null
+
+ /** A text input to the model. */
+ fun asTextInput(): String = textInput.getOrThrow("textInput")
+
+ /** A text input to the model. */
+ fun asResponseInputText(): ResponseInputText =
+ responseInputText.getOrThrow("responseInputText")
+
+ /** A text output from the model. */
+ fun asOutputText(): OutputText = outputText.getOrThrow("outputText")
+
+ /** An image input block used within EvalItem content arrays. */
+ fun asInputImage(): InputImage = inputImage.getOrThrow("inputImage")
+
+ /** An audio input to the model. */
+ fun asResponseInputAudio(): ResponseInputAudio =
+ responseInputAudio.getOrThrow("responseInputAudio")
+
+ fun _json(): Optional = Optional.ofNullable(_json)
+
+ fun accept(visitor: Visitor): T =
+ when {
+ textInput != null -> visitor.visitTextInput(textInput)
+ responseInputText != null ->
+ visitor.visitResponseInputText(responseInputText)
+ outputText != null -> visitor.visitOutputText(outputText)
+ inputImage != null -> visitor.visitInputImage(inputImage)
+ responseInputAudio != null ->
+ visitor.visitResponseInputAudio(responseInputAudio)
+ else -> visitor.unknown(_json)
+ }
+
+ private var validated: Boolean = false
+
+ fun validate(): EvalContentItem = apply {
+ if (validated) {
+ return@apply
+ }
+
+ accept(
+ object : Visitor {
+ override fun visitTextInput(textInput: String) {}
+
+ override fun visitResponseInputText(
+ responseInputText: ResponseInputText
+ ) {
+ responseInputText.validate()
+ }
+
+ override fun visitOutputText(outputText: OutputText) {
+ outputText.validate()
+ }
+
+ override fun visitInputImage(inputImage: InputImage) {
+ inputImage.validate()
+ }
+
+ override fun visitResponseInputAudio(
+ responseInputAudio: ResponseInputAudio
+ ) {
+ responseInputAudio.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 visitTextInput(textInput: String) = 1
+
+ override fun visitResponseInputText(
+ responseInputText: ResponseInputText
+ ) = responseInputText.validity()
+
+ override fun visitOutputText(outputText: OutputText) =
+ outputText.validity()
+
+ override fun visitInputImage(inputImage: InputImage) =
+ inputImage.validity()
+
+ override fun visitResponseInputAudio(
+ responseInputAudio: ResponseInputAudio
+ ) = responseInputAudio.validity()
+
+ override fun unknown(json: JsonValue?) = 0
+ }
+ )
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) {
+ return true
+ }
+
+ return other is EvalContentItem &&
+ textInput == other.textInput &&
+ responseInputText == other.responseInputText &&
+ outputText == other.outputText &&
+ inputImage == other.inputImage &&
+ responseInputAudio == other.responseInputAudio
+ }
+
+ override fun hashCode(): Int =
+ Objects.hash(
+ textInput,
+ responseInputText,
+ outputText,
+ inputImage,
+ responseInputAudio,
+ )
+
+ override fun toString(): String =
+ when {
+ textInput != null -> "EvalContentItem{textInput=$textInput}"
+ responseInputText != null ->
+ "EvalContentItem{responseInputText=$responseInputText}"
+ outputText != null -> "EvalContentItem{outputText=$outputText}"
+ inputImage != null -> "EvalContentItem{inputImage=$inputImage}"
+ responseInputAudio != null ->
+ "EvalContentItem{responseInputAudio=$responseInputAudio}"
+ _json != null -> "EvalContentItem{_unknown=$_json}"
+ else -> throw IllegalStateException("Invalid EvalContentItem")
+ }
+
+ companion object {
+
+ /** A text input to the model. */
+ @JvmStatic
+ fun ofTextInput(textInput: String) =
+ EvalContentItem(textInput = textInput)
+
+ /** A text input to the model. */
+ @JvmStatic
+ fun ofResponseInputText(responseInputText: ResponseInputText) =
+ EvalContentItem(responseInputText = responseInputText)
+
+ /** A text output from the model. */
+ @JvmStatic
+ fun ofOutputText(outputText: OutputText) =
+ EvalContentItem(outputText = outputText)
+
+ /** An image input block used within EvalItem content arrays. */
+ @JvmStatic
+ fun ofInputImage(inputImage: InputImage) =
+ EvalContentItem(inputImage = inputImage)
+
+ /** An audio input to the model. */
+ @JvmStatic
+ fun ofResponseInputAudio(responseInputAudio: ResponseInputAudio) =
+ EvalContentItem(responseInputAudio = responseInputAudio)
+ }
+
+ /**
+ * An interface that defines how to map each variant of
+ * [EvalContentItem] to a value of type [T].
+ */
+ interface Visitor {
+
+ /** A text input to the model. */
+ fun visitTextInput(textInput: String): T
+
+ /** A text input to the model. */
+ fun visitResponseInputText(responseInputText: ResponseInputText): T
+
+ /** A text output from the model. */
+ fun visitOutputText(outputText: OutputText): T
+
+ /** An image input block used within EvalItem content arrays. */
+ fun visitInputImage(inputImage: InputImage): T
+
+ /** An audio input to the model. */
+ fun visitResponseInputAudio(
+ responseInputAudio: ResponseInputAudio
+ ): T
+
+ /**
+ * Maps an unknown variant of [EvalContentItem] to a value of type
+ * [T].
+ *
+ * An instance of [EvalContentItem] 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 EvalContentItem: $json"
+ )
+ }
+ }
+
+ internal class Deserializer :
+ BaseDeserializer(EvalContentItem::class) {
+
+ override fun ObjectCodec.deserialize(
+ node: JsonNode
+ ): EvalContentItem {
+ val json = JsonValue.fromJsonNode(node)
+
+ val bestMatches =
+ sequenceOf(
+ tryDeserialize(
+ node,
+ jacksonTypeRef(),
+ )
+ ?.let {
+ EvalContentItem(
+ responseInputText = it,
+ _json = json,
+ )
+ },
+ tryDeserialize(node, jacksonTypeRef())
+ ?.let {
+ EvalContentItem(
+ outputText = it,
+ _json = json,
+ )
+ },
+ tryDeserialize(node, jacksonTypeRef())
+ ?.let {
+ EvalContentItem(
+ inputImage = it,
+ _json = json,
+ )
+ },
+ tryDeserialize(
+ node,
+ jacksonTypeRef(),
+ )
+ ?.let {
+ EvalContentItem(
+ responseInputAudio = it,
+ _json = json,
+ )
+ },
+ tryDeserialize(node, jacksonTypeRef())
+ ?.let {
+ EvalContentItem(
+ textInput = it,
+ _json = json,
+ )
+ },
+ )
+ .filterNotNull()
+ .allMaxBy { it.validity() }
+ .toList()
+ return when (bestMatches.size) {
+ // This can happen if what we're deserializing is completely
+ // incompatible with all the possible variants (e.g.
+ // deserializing from array).
+ 0 -> EvalContentItem(_json = json)
+ 1 -> bestMatches.single()
+ // If there's more than one match with the highest validity,
+ // then use the first completely valid match, or simply the
+ // first match if none are completely valid.
+ else ->
+ bestMatches.firstOrNull { it.isValid() }
+ ?: bestMatches.first()
+ }
+ }
+ }
+
+ internal class Serializer :
+ BaseSerializer(EvalContentItem::class) {
+
+ override fun serialize(
+ value: EvalContentItem,
+ generator: JsonGenerator,
+ provider: SerializerProvider,
+ ) {
+ when {
+ value.textInput != null ->
+ generator.writeObject(value.textInput)
+ value.responseInputText != null ->
+ generator.writeObject(value.responseInputText)
+ value.outputText != null ->
+ generator.writeObject(value.outputText)
+ value.inputImage != null ->
+ generator.writeObject(value.inputImage)
+ value.responseInputAudio != null ->
+ generator.writeObject(value.responseInputAudio)
+ value._json != null -> generator.writeObject(value._json)
+ else ->
+ throw IllegalStateException("Invalid EvalContentItem")
+ }
+ }
+ }
+
+ /** A text output from the model. */
+ class OutputText
+ @JsonCreator(mode = JsonCreator.Mode.DISABLED)
+ private constructor(
+ private val text: JsonField,
+ private val type: JsonValue,
+ private val additionalProperties: MutableMap,
+ ) {
+
+ @JsonCreator
+ private constructor(
+ @JsonProperty("text")
+ @ExcludeMissing
+ text: JsonField = JsonMissing.of(),
+ @JsonProperty("type")
+ @ExcludeMissing
+ type: JsonValue = JsonMissing.of(),
+ ) : this(text, type, mutableMapOf())
+
+ /**
+ * The text output 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).
+ */
+ fun text(): String = text.getRequired("text")
+
+ /**
+ * The type of the output text. Always `output_text`.
+ *
+ * Expected to always return the following:
+ * ```java
+ * JsonValue.from("output_text")
+ * ```
+ *
+ * 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 [text].
+ *
+ * Unlike [text], this method doesn't throw if the JSON field has an
+ * unexpected type.
+ */
+ @JsonProperty("text")
+ @ExcludeMissing
+ fun _text(): JsonField = text
+
+ @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
+ * [OutputText].
+ *
+ * The following fields are required:
+ * ```java
+ * .text()
+ * ```
+ */
+ @JvmStatic fun builder() = Builder()
+ }
+
+ /** A builder for [OutputText]. */
+ class Builder internal constructor() {
+
+ private var text: JsonField? = null
+ private var type: JsonValue = JsonValue.from("output_text")
+ private var additionalProperties:
+ MutableMap =
+ mutableMapOf()
+
+ @JvmSynthetic
+ internal fun from(outputText: OutputText) = apply {
+ text = outputText.text
+ type = outputText.type
+ additionalProperties =
+ outputText.additionalProperties.toMutableMap()
+ }
+
+ /** The text output from the model. */
+ 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 }
+
+ /**
+ * 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("output_text")
+ * ```
+ *
+ * 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 [OutputText].
+ *
+ * Further updates to this [Builder] will not mutate the
+ * returned instance.
+ *
+ * The following fields are required:
+ * ```java
+ * .text()
+ * ```
+ *
+ * @throws IllegalStateException if any required field is unset.
+ */
+ fun build(): OutputText =
+ OutputText(
+ checkRequired("text", text),
+ type,
+ additionalProperties.toMutableMap(),
+ )
+ }
+
+ private var validated: Boolean = false
+
+ fun validate(): OutputText = apply {
+ if (validated) {
+ return@apply
+ }
+
+ text()
+ _type().let {
+ if (it != JsonValue.from("output_text")) {
+ 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 (text.asKnown().isPresent) 1 else 0) +
+ type.let {
+ if (it == JsonValue.from("output_text")) 1 else 0
+ }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) {
+ return true
+ }
+
+ return other is OutputText &&
+ text == other.text &&
+ type == other.type &&
+ additionalProperties == other.additionalProperties
+ }
+
+ private val hashCode: Int by lazy {
+ Objects.hash(text, type, additionalProperties)
+ }
+
+ override fun hashCode(): Int = hashCode
+
+ override fun toString() =
+ "OutputText{text=$text, type=$type, additionalProperties=$additionalProperties}"
+ }
+
+ /** An image input block used within EvalItem content arrays. */
+ class InputImage
+ @JsonCreator(mode = JsonCreator.Mode.DISABLED)
+ private constructor(
+ private val imageUrl: JsonField,
+ private val type: JsonValue,
+ private val detail: JsonField,
+ private val additionalProperties: MutableMap,
+ ) {
+
+ @JsonCreator
+ private constructor(
+ @JsonProperty("image_url")
+ @ExcludeMissing
+ imageUrl: JsonField = JsonMissing.of(),
+ @JsonProperty("type")
+ @ExcludeMissing
+ type: JsonValue = JsonMissing.of(),
+ @JsonProperty("detail")
+ @ExcludeMissing
+ detail: JsonField = JsonMissing.of(),
+ ) : this(imageUrl, type, detail, mutableMapOf())
+
+ /**
+ * The URL of the image input.
+ *
+ * @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 imageUrl(): String = imageUrl.getRequired("image_url")
+
+ /**
+ * The type of the image input. Always `input_image`.
+ *
+ * Expected to always return the following:
+ * ```java
+ * JsonValue.from("input_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
+
+ /**
+ * The detail level of the image to be sent to the model. One of
+ * `high`, `low`, or `auto`. Defaults to `auto`.
+ *
+ * @throws OpenAIInvalidDataException if the JSON field has an
+ * unexpected type (e.g. if the server responded with an
+ * unexpected value).
+ */
+ fun detail(): Optional = detail.getOptional("detail")
+
+ /**
+ * Returns the raw JSON value of [imageUrl].
+ *
+ * Unlike [imageUrl], this method doesn't throw if the JSON field
+ * has an unexpected type.
+ */
+ @JsonProperty("image_url")
+ @ExcludeMissing
+ fun _imageUrl(): JsonField = imageUrl
+
+ /**
+ * Returns the raw JSON value of [detail].
+ *
+ * Unlike [detail], this method doesn't throw if the JSON field has
+ * an unexpected type.
+ */
+ @JsonProperty("detail")
+ @ExcludeMissing
+ fun _detail(): JsonField = detail
+
+ @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
+ * [InputImage].
+ *
+ * The following fields are required:
+ * ```java
+ * .imageUrl()
+ * ```
+ */
+ @JvmStatic fun builder() = Builder()
+ }
+
+ /** A builder for [InputImage]. */
+ class Builder internal constructor() {
+
+ private var imageUrl: JsonField? = null
+ private var type: JsonValue = JsonValue.from("input_image")
+ private var detail: JsonField = JsonMissing.of()
+ private var additionalProperties:
+ MutableMap =
+ mutableMapOf()
+
+ @JvmSynthetic
+ internal fun from(inputImage: InputImage) = apply {
+ imageUrl = inputImage.imageUrl
+ type = inputImage.type
+ detail = inputImage.detail
+ additionalProperties =
+ inputImage.additionalProperties.toMutableMap()
+ }
+
+ /** The URL of the image input. */
+ fun imageUrl(imageUrl: String) =
+ imageUrl(JsonField.of(imageUrl))
+
+ /**
+ * Sets [Builder.imageUrl] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.imageUrl] with a well-typed
+ * [String] value instead. This method is primarily for setting
+ * the field to an undocumented or not yet supported value.
+ */
+ fun imageUrl(imageUrl: JsonField) = apply {
+ this.imageUrl = imageUrl
+ }
+
+ /**
+ * 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("input_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 }
+
+ /**
+ * The detail level of the image to be sent to the model. One of
+ * `high`, `low`, or `auto`. Defaults to `auto`.
+ */
+ fun detail(detail: String) = detail(JsonField.of(detail))
+
+ /**
+ * Sets [Builder.detail] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.detail] with a well-typed
+ * [String] value instead. This method is primarily for setting
+ * the field to an undocumented or not yet supported value.
+ */
+ fun detail(detail: JsonField) = apply {
+ this.detail = detail
+ }
+
+ 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 [InputImage].
+ *
+ * Further updates to this [Builder] will not mutate the
+ * returned instance.
+ *
+ * The following fields are required:
+ * ```java
+ * .imageUrl()
+ * ```
+ *
+ * @throws IllegalStateException if any required field is unset.
+ */
+ fun build(): InputImage =
+ InputImage(
+ checkRequired("imageUrl", imageUrl),
+ type,
+ detail,
+ additionalProperties.toMutableMap(),
+ )
+ }
+
+ private var validated: Boolean = false
+
+ fun validate(): InputImage = apply {
+ if (validated) {
+ return@apply
+ }
+
+ imageUrl()
+ _type().let {
+ if (it != JsonValue.from("input_image")) {
+ throw OpenAIInvalidDataException(
+ "'type' is invalid, received $it"
+ )
+ }
+ }
+ detail()
+ 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 (imageUrl.asKnown().isPresent) 1 else 0) +
+ type.let {
+ if (it == JsonValue.from("input_image")) 1 else 0
+ } +
+ (if (detail.asKnown().isPresent) 1 else 0)
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) {
+ return true
+ }
+
+ return other is InputImage &&
+ imageUrl == other.imageUrl &&
+ type == other.type &&
+ detail == other.detail &&
+ additionalProperties == other.additionalProperties
+ }
+
+ private val hashCode: Int by lazy {
+ Objects.hash(imageUrl, type, detail, additionalProperties)
+ }
+
+ override fun hashCode(): Int = hashCode
+
+ override fun toString() =
+ "InputImage{imageUrl=$imageUrl, type=$type, detail=$detail, additionalProperties=$additionalProperties}"
+ }
+ }
}
/**
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/CreateEvalCompletionsRunDataSource.kt b/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/CreateEvalCompletionsRunDataSource.kt
index c010ad47..a202c89e 100644
--- a/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/CreateEvalCompletionsRunDataSource.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/CreateEvalCompletionsRunDataSource.kt
@@ -26,6 +26,7 @@ import com.openai.core.checkRequired
import com.openai.core.getOrThrow
import com.openai.core.toImmutable
import com.openai.errors.OpenAIInvalidDataException
+import com.openai.models.EvalContentItem
import com.openai.models.ReasoningEffort
import com.openai.models.ResponseFormatJsonObject
import com.openai.models.ResponseFormatJsonSchema
@@ -2754,7 +2755,9 @@ private constructor(
) : this(content, role, type, mutableMapOf())
/**
- * Inputs to the model - can contain template strings.
+ * Inputs to the model - can contain template strings. Supports text, output
+ * text, input images, and input audio, either as a single item or an array of
+ * items.
*
* @throws OpenAIInvalidDataException if the JSON field has an unexpected type
* or is unexpectedly missing or null (e.g. if the server responded with an
@@ -2849,7 +2852,11 @@ private constructor(
additionalProperties = evalItem.additionalProperties.toMutableMap()
}
- /** Inputs to the model - can contain template strings. */
+ /**
+ * Inputs to the model - can contain template strings. Supports text, output
+ * text, input images, and input audio, either as a single item or an array
+ * of items.
+ */
fun content(content: Content) = content(JsonField.of(content))
/**
@@ -2887,17 +2894,10 @@ private constructor(
content(Content.ofResponseInputAudio(responseInputAudio))
/**
- * Alias for calling [content] with
- * `Content.ofAnArrayOfInputTextInputImageAndInputAudio(anArrayOfInputTextInputImageAndInputAudio)`.
+ * Alias for calling [content] with `Content.ofGraderInputs(graderInputs)`.
*/
- fun contentOfAnArrayOfInputTextInputImageAndInputAudio(
- anArrayOfInputTextInputImageAndInputAudio: List
- ) =
- content(
- Content.ofAnArrayOfInputTextInputImageAndInputAudio(
- anArrayOfInputTextInputImageAndInputAudio
- )
- )
+ fun contentOfGraderInputs(graderInputs: List) =
+ content(Content.ofGraderInputs(graderInputs))
/**
* The role of the message input. One of `user`, `assistant`, `system`, or
@@ -3003,7 +3003,11 @@ private constructor(
(role.asKnown().getOrNull()?.validity() ?: 0) +
(type.asKnown().getOrNull()?.validity() ?: 0)
- /** Inputs to the model - can contain template strings. */
+ /**
+ * Inputs to the model - can contain template strings. Supports text, output
+ * text, input images, and input audio, either as a single item or an array of
+ * items.
+ */
@JsonDeserialize(using = Content.Deserializer::class)
@JsonSerialize(using = Content.Serializer::class)
class Content
@@ -3013,8 +3017,7 @@ private constructor(
private val outputText: OutputText? = null,
private val inputImage: InputImage? = null,
private val responseInputAudio: ResponseInputAudio? = null,
- private val anArrayOfInputTextInputImageAndInputAudio: List? =
- null,
+ private val graderInputs: List? = null,
private val _json: JsonValue? = null,
) {
@@ -3028,7 +3031,7 @@ private constructor(
/** A text output from the model. */
fun outputText(): Optional = Optional.ofNullable(outputText)
- /** An image input to the model. */
+ /** An image input block used within EvalItem content arrays. */
fun inputImage(): Optional = Optional.ofNullable(inputImage)
/** An audio input to the model. */
@@ -3036,11 +3039,11 @@ private constructor(
Optional.ofNullable(responseInputAudio)
/**
- * A list of inputs, each of which may be either an input text, input image,
- * or input audio object.
+ * A list of inputs, each of which may be either an input text, output text,
+ * input image, or input audio object.
*/
- fun anArrayOfInputTextInputImageAndInputAudio(): Optional> =
- Optional.ofNullable(anArrayOfInputTextInputImageAndInputAudio)
+ fun graderInputs(): Optional> =
+ Optional.ofNullable(graderInputs)
fun isTextInput(): Boolean = textInput != null
@@ -3052,8 +3055,7 @@ private constructor(
fun isResponseInputAudio(): Boolean = responseInputAudio != null
- fun isAnArrayOfInputTextInputImageAndInputAudio(): Boolean =
- anArrayOfInputTextInputImageAndInputAudio != null
+ fun isGraderInputs(): Boolean = graderInputs != null
/** A text input to the model. */
fun asTextInput(): String = textInput.getOrThrow("textInput")
@@ -3065,7 +3067,7 @@ private constructor(
/** A text output from the model. */
fun asOutputText(): OutputText = outputText.getOrThrow("outputText")
- /** An image input to the model. */
+ /** An image input block used within EvalItem content arrays. */
fun asInputImage(): InputImage = inputImage.getOrThrow("inputImage")
/** An audio input to the model. */
@@ -3073,13 +3075,11 @@ private constructor(
responseInputAudio.getOrThrow("responseInputAudio")
/**
- * A list of inputs, each of which may be either an input text, input image,
- * or input audio object.
+ * A list of inputs, each of which may be either an input text, output text,
+ * input image, or input audio object.
*/
- fun asAnArrayOfInputTextInputImageAndInputAudio(): List =
- anArrayOfInputTextInputImageAndInputAudio.getOrThrow(
- "anArrayOfInputTextInputImageAndInputAudio"
- )
+ fun asGraderInputs(): List =
+ graderInputs.getOrThrow("graderInputs")
fun _json(): Optional = Optional.ofNullable(_json)
@@ -3092,10 +3092,7 @@ private constructor(
inputImage != null -> visitor.visitInputImage(inputImage)
responseInputAudio != null ->
visitor.visitResponseInputAudio(responseInputAudio)
- anArrayOfInputTextInputImageAndInputAudio != null ->
- visitor.visitAnArrayOfInputTextInputImageAndInputAudio(
- anArrayOfInputTextInputImageAndInputAudio
- )
+ graderInputs != null -> visitor.visitGraderInputs(graderInputs)
else -> visitor.unknown(_json)
}
@@ -3130,9 +3127,11 @@ private constructor(
responseInputAudio.validate()
}
- override fun visitAnArrayOfInputTextInputImageAndInputAudio(
- anArrayOfInputTextInputImageAndInputAudio: List
- ) {}
+ override fun visitGraderInputs(
+ graderInputs: List
+ ) {
+ graderInputs.forEach { it.validate() }
+ }
}
)
validated = true
@@ -3172,9 +3171,9 @@ private constructor(
responseInputAudio: ResponseInputAudio
) = responseInputAudio.validity()
- override fun visitAnArrayOfInputTextInputImageAndInputAudio(
- anArrayOfInputTextInputImageAndInputAudio: List
- ) = anArrayOfInputTextInputImageAndInputAudio.size
+ override fun visitGraderInputs(
+ graderInputs: List
+ ) = graderInputs.sumOf { it.validity().toInt() }
override fun unknown(json: JsonValue?) = 0
}
@@ -3191,8 +3190,7 @@ private constructor(
outputText == other.outputText &&
inputImage == other.inputImage &&
responseInputAudio == other.responseInputAudio &&
- anArrayOfInputTextInputImageAndInputAudio ==
- other.anArrayOfInputTextInputImageAndInputAudio
+ graderInputs == other.graderInputs
}
override fun hashCode(): Int =
@@ -3202,7 +3200,7 @@ private constructor(
outputText,
inputImage,
responseInputAudio,
- anArrayOfInputTextInputImageAndInputAudio,
+ graderInputs,
)
override fun toString(): String =
@@ -3214,8 +3212,7 @@ private constructor(
inputImage != null -> "Content{inputImage=$inputImage}"
responseInputAudio != null ->
"Content{responseInputAudio=$responseInputAudio}"
- anArrayOfInputTextInputImageAndInputAudio != null ->
- "Content{anArrayOfInputTextInputImageAndInputAudio=$anArrayOfInputTextInputImageAndInputAudio}"
+ graderInputs != null -> "Content{graderInputs=$graderInputs}"
_json != null -> "Content{_unknown=$_json}"
else -> throw IllegalStateException("Invalid Content")
}
@@ -3236,7 +3233,7 @@ private constructor(
fun ofOutputText(outputText: OutputText) =
Content(outputText = outputText)
- /** An image input to the model. */
+ /** An image input block used within EvalItem content arrays. */
@JvmStatic
fun ofInputImage(inputImage: InputImage) =
Content(inputImage = inputImage)
@@ -3247,17 +3244,12 @@ private constructor(
Content(responseInputAudio = responseInputAudio)
/**
- * A list of inputs, each of which may be either an input text, input
- * image, or input audio object.
+ * A list of inputs, each of which may be either an input text, output
+ * text, input image, or input audio object.
*/
@JvmStatic
- fun ofAnArrayOfInputTextInputImageAndInputAudio(
- anArrayOfInputTextInputImageAndInputAudio: List
- ) =
- Content(
- anArrayOfInputTextInputImageAndInputAudio =
- anArrayOfInputTextInputImageAndInputAudio.toImmutable()
- )
+ fun ofGraderInputs(graderInputs: List) =
+ Content(graderInputs = graderInputs.toImmutable())
}
/**
@@ -3275,19 +3267,17 @@ private constructor(
/** A text output from the model. */
fun visitOutputText(outputText: OutputText): T
- /** An image input to the model. */
+ /** An image input block used within EvalItem content arrays. */
fun visitInputImage(inputImage: InputImage): T
/** An audio input to the model. */
fun visitResponseInputAudio(responseInputAudio: ResponseInputAudio): T
/**
- * A list of inputs, each of which may be either an input text, input
- * image, or input audio object.
+ * A list of inputs, each of which may be either an input text, output
+ * text, input image, or input audio object.
*/
- fun visitAnArrayOfInputTextInputImageAndInputAudio(
- anArrayOfInputTextInputImageAndInputAudio: List
- ): T
+ fun visitGraderInputs(graderInputs: List): T
/**
* Maps an unknown variant of [Content] to a value of type [T].
@@ -3332,14 +3322,11 @@ private constructor(
tryDeserialize(node, jacksonTypeRef())?.let {
Content(textInput = it, _json = json)
},
- tryDeserialize(node, jacksonTypeRef>())
- ?.let {
- Content(
- anArrayOfInputTextInputImageAndInputAudio =
- it,
- _json = json,
- )
- },
+ tryDeserialize(
+ node,
+ jacksonTypeRef>(),
+ )
+ ?.let { Content(graderInputs = it, _json = json) },
)
.filterNotNull()
.allMaxBy { it.validity() }
@@ -3377,10 +3364,8 @@ private constructor(
generator.writeObject(value.inputImage)
value.responseInputAudio != null ->
generator.writeObject(value.responseInputAudio)
- value.anArrayOfInputTextInputImageAndInputAudio != null ->
- generator.writeObject(
- value.anArrayOfInputTextInputImageAndInputAudio
- )
+ value.graderInputs != null ->
+ generator.writeObject(value.graderInputs)
value._json != null -> generator.writeObject(value._json)
else -> throw IllegalStateException("Invalid Content")
}
@@ -3608,7 +3593,7 @@ private constructor(
"OutputText{text=$text, type=$type, additionalProperties=$additionalProperties}"
}
- /** An image input to the model. */
+ /** An image input block used within EvalItem content arrays. */
class InputImage
@JsonCreator(mode = JsonCreator.Mode.DISABLED)
private constructor(
@@ -3877,6 +3862,860 @@ private constructor(
override fun toString() =
"InputImage{imageUrl=$imageUrl, type=$type, detail=$detail, additionalProperties=$additionalProperties}"
}
+
+ /**
+ * A single content item: input text, output text, input image, or input
+ * audio.
+ */
+ @JsonDeserialize(using = EvalContentItem.Deserializer::class)
+ @JsonSerialize(using = EvalContentItem.Serializer::class)
+ class EvalContentItem
+ private constructor(
+ private val textInput: String? = null,
+ private val responseInputText: ResponseInputText? = null,
+ private val outputText: OutputText? = null,
+ private val inputImage: InputImage? = null,
+ private val responseInputAudio: ResponseInputAudio? = null,
+ private val _json: JsonValue? = null,
+ ) {
+
+ /** A text input to the model. */
+ fun textInput(): Optional = Optional.ofNullable(textInput)
+
+ /** A text input to the model. */
+ fun responseInputText(): Optional =
+ Optional.ofNullable(responseInputText)
+
+ /** A text output from the model. */
+ fun outputText(): Optional = Optional.ofNullable(outputText)
+
+ /** An image input block used within EvalItem content arrays. */
+ fun inputImage(): Optional = Optional.ofNullable(inputImage)
+
+ /** An audio input to the model. */
+ fun responseInputAudio(): Optional =
+ Optional.ofNullable(responseInputAudio)
+
+ fun isTextInput(): Boolean = textInput != null
+
+ fun isResponseInputText(): Boolean = responseInputText != null
+
+ fun isOutputText(): Boolean = outputText != null
+
+ fun isInputImage(): Boolean = inputImage != null
+
+ fun isResponseInputAudio(): Boolean = responseInputAudio != null
+
+ /** A text input to the model. */
+ fun asTextInput(): String = textInput.getOrThrow("textInput")
+
+ /** A text input to the model. */
+ fun asResponseInputText(): ResponseInputText =
+ responseInputText.getOrThrow("responseInputText")
+
+ /** A text output from the model. */
+ fun asOutputText(): OutputText = outputText.getOrThrow("outputText")
+
+ /** An image input block used within EvalItem content arrays. */
+ fun asInputImage(): InputImage = inputImage.getOrThrow("inputImage")
+
+ /** An audio input to the model. */
+ fun asResponseInputAudio(): ResponseInputAudio =
+ responseInputAudio.getOrThrow("responseInputAudio")
+
+ fun _json(): Optional = Optional.ofNullable(_json)
+
+ fun accept(visitor: Visitor): T =
+ when {
+ textInput != null -> visitor.visitTextInput(textInput)
+ responseInputText != null ->
+ visitor.visitResponseInputText(responseInputText)
+ outputText != null -> visitor.visitOutputText(outputText)
+ inputImage != null -> visitor.visitInputImage(inputImage)
+ responseInputAudio != null ->
+ visitor.visitResponseInputAudio(responseInputAudio)
+ else -> visitor.unknown(_json)
+ }
+
+ private var validated: Boolean = false
+
+ fun validate(): EvalContentItem = apply {
+ if (validated) {
+ return@apply
+ }
+
+ accept(
+ object : Visitor {
+ override fun visitTextInput(textInput: String) {}
+
+ override fun visitResponseInputText(
+ responseInputText: ResponseInputText
+ ) {
+ responseInputText.validate()
+ }
+
+ override fun visitOutputText(outputText: OutputText) {
+ outputText.validate()
+ }
+
+ override fun visitInputImage(inputImage: InputImage) {
+ inputImage.validate()
+ }
+
+ override fun visitResponseInputAudio(
+ responseInputAudio: ResponseInputAudio
+ ) {
+ responseInputAudio.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 visitTextInput(textInput: String) = 1
+
+ override fun visitResponseInputText(
+ responseInputText: ResponseInputText
+ ) = responseInputText.validity()
+
+ override fun visitOutputText(outputText: OutputText) =
+ outputText.validity()
+
+ override fun visitInputImage(inputImage: InputImage) =
+ inputImage.validity()
+
+ override fun visitResponseInputAudio(
+ responseInputAudio: ResponseInputAudio
+ ) = responseInputAudio.validity()
+
+ override fun unknown(json: JsonValue?) = 0
+ }
+ )
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) {
+ return true
+ }
+
+ return other is EvalContentItem &&
+ textInput == other.textInput &&
+ responseInputText == other.responseInputText &&
+ outputText == other.outputText &&
+ inputImage == other.inputImage &&
+ responseInputAudio == other.responseInputAudio
+ }
+
+ override fun hashCode(): Int =
+ Objects.hash(
+ textInput,
+ responseInputText,
+ outputText,
+ inputImage,
+ responseInputAudio,
+ )
+
+ override fun toString(): String =
+ when {
+ textInput != null -> "EvalContentItem{textInput=$textInput}"
+ responseInputText != null ->
+ "EvalContentItem{responseInputText=$responseInputText}"
+ outputText != null -> "EvalContentItem{outputText=$outputText}"
+ inputImage != null -> "EvalContentItem{inputImage=$inputImage}"
+ responseInputAudio != null ->
+ "EvalContentItem{responseInputAudio=$responseInputAudio}"
+ _json != null -> "EvalContentItem{_unknown=$_json}"
+ else -> throw IllegalStateException("Invalid EvalContentItem")
+ }
+
+ companion object {
+
+ /** A text input to the model. */
+ @JvmStatic
+ fun ofTextInput(textInput: String) =
+ EvalContentItem(textInput = textInput)
+
+ /** A text input to the model. */
+ @JvmStatic
+ fun ofResponseInputText(responseInputText: ResponseInputText) =
+ EvalContentItem(responseInputText = responseInputText)
+
+ /** A text output from the model. */
+ @JvmStatic
+ fun ofOutputText(outputText: OutputText) =
+ EvalContentItem(outputText = outputText)
+
+ /** An image input block used within EvalItem content arrays. */
+ @JvmStatic
+ fun ofInputImage(inputImage: InputImage) =
+ EvalContentItem(inputImage = inputImage)
+
+ /** An audio input to the model. */
+ @JvmStatic
+ fun ofResponseInputAudio(responseInputAudio: ResponseInputAudio) =
+ EvalContentItem(responseInputAudio = responseInputAudio)
+ }
+
+ /**
+ * An interface that defines how to map each variant of
+ * [EvalContentItem] to a value of type [T].
+ */
+ interface Visitor {
+
+ /** A text input to the model. */
+ fun visitTextInput(textInput: String): T
+
+ /** A text input to the model. */
+ fun visitResponseInputText(responseInputText: ResponseInputText): T
+
+ /** A text output from the model. */
+ fun visitOutputText(outputText: OutputText): T
+
+ /** An image input block used within EvalItem content arrays. */
+ fun visitInputImage(inputImage: InputImage): T
+
+ /** An audio input to the model. */
+ fun visitResponseInputAudio(
+ responseInputAudio: ResponseInputAudio
+ ): T
+
+ /**
+ * Maps an unknown variant of [EvalContentItem] to a value of type
+ * [T].
+ *
+ * An instance of [EvalContentItem] 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 EvalContentItem: $json"
+ )
+ }
+ }
+
+ internal class Deserializer :
+ BaseDeserializer(EvalContentItem::class) {
+
+ override fun ObjectCodec.deserialize(
+ node: JsonNode
+ ): EvalContentItem {
+ val json = JsonValue.fromJsonNode(node)
+
+ val bestMatches =
+ sequenceOf(
+ tryDeserialize(
+ node,
+ jacksonTypeRef(),
+ )
+ ?.let {
+ EvalContentItem(
+ responseInputText = it,
+ _json = json,
+ )
+ },
+ tryDeserialize(node, jacksonTypeRef())
+ ?.let {
+ EvalContentItem(
+ outputText = it,
+ _json = json,
+ )
+ },
+ tryDeserialize(node, jacksonTypeRef())
+ ?.let {
+ EvalContentItem(
+ inputImage = it,
+ _json = json,
+ )
+ },
+ tryDeserialize(
+ node,
+ jacksonTypeRef(),
+ )
+ ?.let {
+ EvalContentItem(
+ responseInputAudio = it,
+ _json = json,
+ )
+ },
+ tryDeserialize(node, jacksonTypeRef())
+ ?.let {
+ EvalContentItem(
+ textInput = it,
+ _json = json,
+ )
+ },
+ )
+ .filterNotNull()
+ .allMaxBy { it.validity() }
+ .toList()
+ return when (bestMatches.size) {
+ // This can happen if what we're deserializing is completely
+ // incompatible with all the possible variants (e.g.
+ // deserializing from array).
+ 0 -> EvalContentItem(_json = json)
+ 1 -> bestMatches.single()
+ // If there's more than one match with the highest validity,
+ // then use the first completely valid match, or simply the
+ // first match if none are completely valid.
+ else ->
+ bestMatches.firstOrNull { it.isValid() }
+ ?: bestMatches.first()
+ }
+ }
+ }
+
+ internal class Serializer :
+ BaseSerializer(EvalContentItem::class) {
+
+ override fun serialize(
+ value: EvalContentItem,
+ generator: JsonGenerator,
+ provider: SerializerProvider,
+ ) {
+ when {
+ value.textInput != null ->
+ generator.writeObject(value.textInput)
+ value.responseInputText != null ->
+ generator.writeObject(value.responseInputText)
+ value.outputText != null ->
+ generator.writeObject(value.outputText)
+ value.inputImage != null ->
+ generator.writeObject(value.inputImage)
+ value.responseInputAudio != null ->
+ generator.writeObject(value.responseInputAudio)
+ value._json != null -> generator.writeObject(value._json)
+ else ->
+ throw IllegalStateException("Invalid EvalContentItem")
+ }
+ }
+ }
+
+ /** A text output from the model. */
+ class OutputText
+ @JsonCreator(mode = JsonCreator.Mode.DISABLED)
+ private constructor(
+ private val text: JsonField,
+ private val type: JsonValue,
+ private val additionalProperties: MutableMap,
+ ) {
+
+ @JsonCreator
+ private constructor(
+ @JsonProperty("text")
+ @ExcludeMissing
+ text: JsonField = JsonMissing.of(),
+ @JsonProperty("type")
+ @ExcludeMissing
+ type: JsonValue = JsonMissing.of(),
+ ) : this(text, type, mutableMapOf())
+
+ /**
+ * The text output 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).
+ */
+ fun text(): String = text.getRequired("text")
+
+ /**
+ * The type of the output text. Always `output_text`.
+ *
+ * Expected to always return the following:
+ * ```java
+ * JsonValue.from("output_text")
+ * ```
+ *
+ * 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 [text].
+ *
+ * Unlike [text], this method doesn't throw if the JSON field has an
+ * unexpected type.
+ */
+ @JsonProperty("text")
+ @ExcludeMissing
+ fun _text(): JsonField = text
+
+ @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
+ * [OutputText].
+ *
+ * The following fields are required:
+ * ```java
+ * .text()
+ * ```
+ */
+ @JvmStatic fun builder() = Builder()
+ }
+
+ /** A builder for [OutputText]. */
+ class Builder internal constructor() {
+
+ private var text: JsonField? = null
+ private var type: JsonValue = JsonValue.from("output_text")
+ private var additionalProperties:
+ MutableMap =
+ mutableMapOf()
+
+ @JvmSynthetic
+ internal fun from(outputText: OutputText) = apply {
+ text = outputText.text
+ type = outputText.type
+ additionalProperties =
+ outputText.additionalProperties.toMutableMap()
+ }
+
+ /** The text output from the model. */
+ 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 }
+
+ /**
+ * 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("output_text")
+ * ```
+ *
+ * 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 [OutputText].
+ *
+ * Further updates to this [Builder] will not mutate the
+ * returned instance.
+ *
+ * The following fields are required:
+ * ```java
+ * .text()
+ * ```
+ *
+ * @throws IllegalStateException if any required field is unset.
+ */
+ fun build(): OutputText =
+ OutputText(
+ checkRequired("text", text),
+ type,
+ additionalProperties.toMutableMap(),
+ )
+ }
+
+ private var validated: Boolean = false
+
+ fun validate(): OutputText = apply {
+ if (validated) {
+ return@apply
+ }
+
+ text()
+ _type().let {
+ if (it != JsonValue.from("output_text")) {
+ 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 (text.asKnown().isPresent) 1 else 0) +
+ type.let {
+ if (it == JsonValue.from("output_text")) 1 else 0
+ }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) {
+ return true
+ }
+
+ return other is OutputText &&
+ text == other.text &&
+ type == other.type &&
+ additionalProperties == other.additionalProperties
+ }
+
+ private val hashCode: Int by lazy {
+ Objects.hash(text, type, additionalProperties)
+ }
+
+ override fun hashCode(): Int = hashCode
+
+ override fun toString() =
+ "OutputText{text=$text, type=$type, additionalProperties=$additionalProperties}"
+ }
+
+ /** An image input block used within EvalItem content arrays. */
+ class InputImage
+ @JsonCreator(mode = JsonCreator.Mode.DISABLED)
+ private constructor(
+ private val imageUrl: JsonField,
+ private val type: JsonValue,
+ private val detail: JsonField,
+ private val additionalProperties: MutableMap,
+ ) {
+
+ @JsonCreator
+ private constructor(
+ @JsonProperty("image_url")
+ @ExcludeMissing
+ imageUrl: JsonField = JsonMissing.of(),
+ @JsonProperty("type")
+ @ExcludeMissing
+ type: JsonValue = JsonMissing.of(),
+ @JsonProperty("detail")
+ @ExcludeMissing
+ detail: JsonField = JsonMissing.of(),
+ ) : this(imageUrl, type, detail, mutableMapOf())
+
+ /**
+ * The URL of the image input.
+ *
+ * @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 imageUrl(): String = imageUrl.getRequired("image_url")
+
+ /**
+ * The type of the image input. Always `input_image`.
+ *
+ * Expected to always return the following:
+ * ```java
+ * JsonValue.from("input_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
+
+ /**
+ * The detail level of the image to be sent to the model. One of
+ * `high`, `low`, or `auto`. Defaults to `auto`.
+ *
+ * @throws OpenAIInvalidDataException if the JSON field has an
+ * unexpected type (e.g. if the server responded with an
+ * unexpected value).
+ */
+ fun detail(): Optional = detail.getOptional("detail")
+
+ /**
+ * Returns the raw JSON value of [imageUrl].
+ *
+ * Unlike [imageUrl], this method doesn't throw if the JSON field
+ * has an unexpected type.
+ */
+ @JsonProperty("image_url")
+ @ExcludeMissing
+ fun _imageUrl(): JsonField = imageUrl
+
+ /**
+ * Returns the raw JSON value of [detail].
+ *
+ * Unlike [detail], this method doesn't throw if the JSON field has
+ * an unexpected type.
+ */
+ @JsonProperty("detail")
+ @ExcludeMissing
+ fun _detail(): JsonField = detail
+
+ @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
+ * [InputImage].
+ *
+ * The following fields are required:
+ * ```java
+ * .imageUrl()
+ * ```
+ */
+ @JvmStatic fun builder() = Builder()
+ }
+
+ /** A builder for [InputImage]. */
+ class Builder internal constructor() {
+
+ private var imageUrl: JsonField? = null
+ private var type: JsonValue = JsonValue.from("input_image")
+ private var detail: JsonField = JsonMissing.of()
+ private var additionalProperties:
+ MutableMap =
+ mutableMapOf()
+
+ @JvmSynthetic
+ internal fun from(inputImage: InputImage) = apply {
+ imageUrl = inputImage.imageUrl
+ type = inputImage.type
+ detail = inputImage.detail
+ additionalProperties =
+ inputImage.additionalProperties.toMutableMap()
+ }
+
+ /** The URL of the image input. */
+ fun imageUrl(imageUrl: String) =
+ imageUrl(JsonField.of(imageUrl))
+
+ /**
+ * Sets [Builder.imageUrl] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.imageUrl] with a well-typed
+ * [String] value instead. This method is primarily for setting
+ * the field to an undocumented or not yet supported value.
+ */
+ fun imageUrl(imageUrl: JsonField) = apply {
+ this.imageUrl = imageUrl
+ }
+
+ /**
+ * 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("input_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 }
+
+ /**
+ * The detail level of the image to be sent to the model. One of
+ * `high`, `low`, or `auto`. Defaults to `auto`.
+ */
+ fun detail(detail: String) = detail(JsonField.of(detail))
+
+ /**
+ * Sets [Builder.detail] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.detail] with a well-typed
+ * [String] value instead. This method is primarily for setting
+ * the field to an undocumented or not yet supported value.
+ */
+ fun detail(detail: JsonField) = apply {
+ this.detail = detail
+ }
+
+ 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 [InputImage].
+ *
+ * Further updates to this [Builder] will not mutate the
+ * returned instance.
+ *
+ * The following fields are required:
+ * ```java
+ * .imageUrl()
+ * ```
+ *
+ * @throws IllegalStateException if any required field is unset.
+ */
+ fun build(): InputImage =
+ InputImage(
+ checkRequired("imageUrl", imageUrl),
+ type,
+ detail,
+ additionalProperties.toMutableMap(),
+ )
+ }
+
+ private var validated: Boolean = false
+
+ fun validate(): InputImage = apply {
+ if (validated) {
+ return@apply
+ }
+
+ imageUrl()
+ _type().let {
+ if (it != JsonValue.from("input_image")) {
+ throw OpenAIInvalidDataException(
+ "'type' is invalid, received $it"
+ )
+ }
+ }
+ detail()
+ 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 (imageUrl.asKnown().isPresent) 1 else 0) +
+ type.let {
+ if (it == JsonValue.from("input_image")) 1 else 0
+ } +
+ (if (detail.asKnown().isPresent) 1 else 0)
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) {
+ return true
+ }
+
+ return other is InputImage &&
+ imageUrl == other.imageUrl &&
+ type == other.type &&
+ detail == other.detail &&
+ additionalProperties == other.additionalProperties
+ }
+
+ private val hashCode: Int by lazy {
+ Objects.hash(imageUrl, type, detail, additionalProperties)
+ }
+
+ override fun hashCode(): Int = hashCode
+
+ override fun toString() =
+ "InputImage{imageUrl=$imageUrl, type=$type, detail=$detail, additionalProperties=$additionalProperties}"
+ }
+ }
}
/**
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunCancelResponse.kt b/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunCancelResponse.kt
index f05d4645..a6af2f6b 100644
--- a/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunCancelResponse.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunCancelResponse.kt
@@ -26,6 +26,7 @@ import com.openai.core.checkRequired
import com.openai.core.getOrThrow
import com.openai.core.toImmutable
import com.openai.errors.OpenAIInvalidDataException
+import com.openai.models.EvalContentItem
import com.openai.models.ReasoningEffort
import com.openai.models.ResponseFormatJsonObject
import com.openai.models.ResponseFormatText
@@ -4230,7 +4231,9 @@ private constructor(
) : this(content, role, type, mutableMapOf())
/**
- * Inputs to the model - can contain template strings.
+ * Inputs to the model - can contain template strings. Supports text,
+ * output text, input images, and input audio, either as a single item
+ * or an array of items.
*
* @throws OpenAIInvalidDataException if the JSON field has an
* unexpected type or is unexpectedly missing or null (e.g. if the
@@ -4332,7 +4335,11 @@ private constructor(
evalItem.additionalProperties.toMutableMap()
}
- /** Inputs to the model - can contain template strings. */
+ /**
+ * Inputs to the model - can contain template strings. Supports
+ * text, output text, input images, and input audio, either as a
+ * single item or an array of items.
+ */
fun content(content: Content) = content(JsonField.of(content))
/**
@@ -4383,16 +4390,10 @@ private constructor(
/**
* Alias for calling [content] with
- * `Content.ofAnArrayOfInputTextInputImageAndInputAudio(anArrayOfInputTextInputImageAndInputAudio)`.
+ * `Content.ofGraderInputs(graderInputs)`.
*/
- fun contentOfAnArrayOfInputTextInputImageAndInputAudio(
- anArrayOfInputTextInputImageAndInputAudio: List
- ) =
- content(
- Content.ofAnArrayOfInputTextInputImageAndInputAudio(
- anArrayOfInputTextInputImageAndInputAudio
- )
- )
+ fun contentOfGraderInputs(graderInputs: List) =
+ content(Content.ofGraderInputs(graderInputs))
/**
* The role of the message input. One of `user`, `assistant`,
@@ -4500,7 +4501,11 @@ private constructor(
(role.asKnown().getOrNull()?.validity() ?: 0) +
(type.asKnown().getOrNull()?.validity() ?: 0)
- /** Inputs to the model - can contain template strings. */
+ /**
+ * Inputs to the model - can contain template strings. Supports text,
+ * output text, input images, and input audio, either as a single item
+ * or an array of items.
+ */
@JsonDeserialize(using = Content.Deserializer::class)
@JsonSerialize(using = Content.Serializer::class)
class Content
@@ -4510,9 +4515,7 @@ private constructor(
private val outputText: OutputText? = null,
private val inputImage: InputImage? = null,
private val responseInputAudio: ResponseInputAudio? = null,
- private val anArrayOfInputTextInputImageAndInputAudio:
- List? =
- null,
+ private val graderInputs: List? = null,
private val _json: JsonValue? = null,
) {
@@ -4527,7 +4530,7 @@ private constructor(
fun outputText(): Optional =
Optional.ofNullable(outputText)
- /** An image input to the model. */
+ /** An image input block used within EvalItem content arrays. */
fun inputImage(): Optional =
Optional.ofNullable(inputImage)
@@ -4537,11 +4540,10 @@ private constructor(
/**
* A list of inputs, each of which may be either an input text,
- * input image, or input audio object.
+ * output text, input image, or input audio object.
*/
- fun anArrayOfInputTextInputImageAndInputAudio():
- Optional> =
- Optional.ofNullable(anArrayOfInputTextInputImageAndInputAudio)
+ fun graderInputs(): Optional> =
+ Optional.ofNullable(graderInputs)
fun isTextInput(): Boolean = textInput != null
@@ -4553,8 +4555,7 @@ private constructor(
fun isResponseInputAudio(): Boolean = responseInputAudio != null
- fun isAnArrayOfInputTextInputImageAndInputAudio(): Boolean =
- anArrayOfInputTextInputImageAndInputAudio != null
+ fun isGraderInputs(): Boolean = graderInputs != null
/** A text input to the model. */
fun asTextInput(): String = textInput.getOrThrow("textInput")
@@ -4566,7 +4567,7 @@ private constructor(
/** A text output from the model. */
fun asOutputText(): OutputText = outputText.getOrThrow("outputText")
- /** An image input to the model. */
+ /** An image input block used within EvalItem content arrays. */
fun asInputImage(): InputImage = inputImage.getOrThrow("inputImage")
/** An audio input to the model. */
@@ -4575,12 +4576,10 @@ private constructor(
/**
* A list of inputs, each of which may be either an input text,
- * input image, or input audio object.
+ * output text, input image, or input audio object.
*/
- fun asAnArrayOfInputTextInputImageAndInputAudio(): List =
- anArrayOfInputTextInputImageAndInputAudio.getOrThrow(
- "anArrayOfInputTextInputImageAndInputAudio"
- )
+ fun asGraderInputs(): List =
+ graderInputs.getOrThrow("graderInputs")
fun _json(): Optional = Optional.ofNullable(_json)
@@ -4593,10 +4592,8 @@ private constructor(
inputImage != null -> visitor.visitInputImage(inputImage)
responseInputAudio != null ->
visitor.visitResponseInputAudio(responseInputAudio)
- anArrayOfInputTextInputImageAndInputAudio != null ->
- visitor.visitAnArrayOfInputTextInputImageAndInputAudio(
- anArrayOfInputTextInputImageAndInputAudio
- )
+ graderInputs != null ->
+ visitor.visitGraderInputs(graderInputs)
else -> visitor.unknown(_json)
}
@@ -4631,10 +4628,11 @@ private constructor(
responseInputAudio.validate()
}
- override fun visitAnArrayOfInputTextInputImageAndInputAudio(
- anArrayOfInputTextInputImageAndInputAudio:
- List
- ) {}
+ override fun visitGraderInputs(
+ graderInputs: List
+ ) {
+ graderInputs.forEach { it.validate() }
+ }
}
)
validated = true
@@ -4674,10 +4672,9 @@ private constructor(
responseInputAudio: ResponseInputAudio
) = responseInputAudio.validity()
- override fun visitAnArrayOfInputTextInputImageAndInputAudio(
- anArrayOfInputTextInputImageAndInputAudio:
- List
- ) = anArrayOfInputTextInputImageAndInputAudio.size
+ override fun visitGraderInputs(
+ graderInputs: List
+ ) = graderInputs.sumOf { it.validity().toInt() }
override fun unknown(json: JsonValue?) = 0
}
@@ -4694,8 +4691,7 @@ private constructor(
outputText == other.outputText &&
inputImage == other.inputImage &&
responseInputAudio == other.responseInputAudio &&
- anArrayOfInputTextInputImageAndInputAudio ==
- other.anArrayOfInputTextInputImageAndInputAudio
+ graderInputs == other.graderInputs
}
override fun hashCode(): Int =
@@ -4705,7 +4701,7 @@ private constructor(
outputText,
inputImage,
responseInputAudio,
- anArrayOfInputTextInputImageAndInputAudio,
+ graderInputs,
)
override fun toString(): String =
@@ -4717,8 +4713,8 @@ private constructor(
inputImage != null -> "Content{inputImage=$inputImage}"
responseInputAudio != null ->
"Content{responseInputAudio=$responseInputAudio}"
- anArrayOfInputTextInputImageAndInputAudio != null ->
- "Content{anArrayOfInputTextInputImageAndInputAudio=$anArrayOfInputTextInputImageAndInputAudio}"
+ graderInputs != null ->
+ "Content{graderInputs=$graderInputs}"
_json != null -> "Content{_unknown=$_json}"
else -> throw IllegalStateException("Invalid Content")
}
@@ -4740,7 +4736,7 @@ private constructor(
fun ofOutputText(outputText: OutputText) =
Content(outputText = outputText)
- /** An image input to the model. */
+ /** An image input block used within EvalItem content arrays. */
@JvmStatic
fun ofInputImage(inputImage: InputImage) =
Content(inputImage = inputImage)
@@ -4753,17 +4749,11 @@ private constructor(
/**
* A list of inputs, each of which may be either an input text,
- * input image, or input audio object.
+ * output text, input image, or input audio object.
*/
@JvmStatic
- fun ofAnArrayOfInputTextInputImageAndInputAudio(
- anArrayOfInputTextInputImageAndInputAudio: List
- ) =
- Content(
- anArrayOfInputTextInputImageAndInputAudio =
- anArrayOfInputTextInputImageAndInputAudio
- .toImmutable()
- )
+ fun ofGraderInputs(graderInputs: List) =
+ Content(graderInputs = graderInputs.toImmutable())
}
/**
@@ -4783,7 +4773,7 @@ private constructor(
/** A text output from the model. */
fun visitOutputText(outputText: OutputText): T
- /** An image input to the model. */
+ /** An image input block used within EvalItem content arrays. */
fun visitInputImage(inputImage: InputImage): T
/** An audio input to the model. */
@@ -4793,11 +4783,9 @@ private constructor(
/**
* A list of inputs, each of which may be either an input text,
- * input image, or input audio object.
+ * output text, input image, or input audio object.
*/
- fun visitAnArrayOfInputTextInputImageAndInputAudio(
- anArrayOfInputTextInputImageAndInputAudio: List
- ): T
+ fun visitGraderInputs(graderInputs: List): T
/**
* Maps an unknown variant of [Content] to a value of type [T].
@@ -4864,14 +4852,10 @@ private constructor(
},
tryDeserialize(
node,
- jacksonTypeRef>(),
+ jacksonTypeRef>(),
)
?.let {
- Content(
- anArrayOfInputTextInputImageAndInputAudio =
- it,
- _json = json,
- )
+ Content(graderInputs = it, _json = json)
},
)
.filterNotNull()
@@ -4913,11 +4897,8 @@ private constructor(
generator.writeObject(value.inputImage)
value.responseInputAudio != null ->
generator.writeObject(value.responseInputAudio)
- value.anArrayOfInputTextInputImageAndInputAudio !=
- null ->
- generator.writeObject(
- value.anArrayOfInputTextInputImageAndInputAudio
- )
+ value.graderInputs != null ->
+ generator.writeObject(value.graderInputs)
value._json != null ->
generator.writeObject(value._json)
else -> throw IllegalStateException("Invalid Content")
@@ -5162,7 +5143,7 @@ private constructor(
"OutputText{text=$text, type=$type, additionalProperties=$additionalProperties}"
}
- /** An image input to the model. */
+ /** An image input block used within EvalItem content arrays. */
class InputImage
@JsonCreator(mode = JsonCreator.Mode.DISABLED)
private constructor(
@@ -5447,6 +5428,942 @@ private constructor(
override fun toString() =
"InputImage{imageUrl=$imageUrl, type=$type, detail=$detail, additionalProperties=$additionalProperties}"
}
+
+ /**
+ * A single content item: input text, output text, input image, or
+ * input audio.
+ */
+ @JsonDeserialize(using = EvalContentItem.Deserializer::class)
+ @JsonSerialize(using = EvalContentItem.Serializer::class)
+ class EvalContentItem
+ private constructor(
+ private val textInput: String? = null,
+ private val responseInputText: ResponseInputText? = null,
+ private val outputText: OutputText? = null,
+ private val inputImage: InputImage? = null,
+ private val responseInputAudio: ResponseInputAudio? = null,
+ private val _json: JsonValue? = null,
+ ) {
+
+ /** A text input to the model. */
+ fun textInput(): Optional =
+ Optional.ofNullable(textInput)
+
+ /** A text input to the model. */
+ fun responseInputText(): Optional =
+ Optional.ofNullable(responseInputText)
+
+ /** A text output from the model. */
+ fun outputText(): Optional =
+ Optional.ofNullable(outputText)
+
+ /** An image input block used within EvalItem content arrays. */
+ fun inputImage(): Optional =
+ Optional.ofNullable(inputImage)
+
+ /** An audio input to the model. */
+ fun responseInputAudio(): Optional =
+ Optional.ofNullable(responseInputAudio)
+
+ fun isTextInput(): Boolean = textInput != null
+
+ fun isResponseInputText(): Boolean = responseInputText != null
+
+ fun isOutputText(): Boolean = outputText != null
+
+ fun isInputImage(): Boolean = inputImage != null
+
+ fun isResponseInputAudio(): Boolean = responseInputAudio != null
+
+ /** A text input to the model. */
+ fun asTextInput(): String = textInput.getOrThrow("textInput")
+
+ /** A text input to the model. */
+ fun asResponseInputText(): ResponseInputText =
+ responseInputText.getOrThrow("responseInputText")
+
+ /** A text output from the model. */
+ fun asOutputText(): OutputText =
+ outputText.getOrThrow("outputText")
+
+ /** An image input block used within EvalItem content arrays. */
+ fun asInputImage(): InputImage =
+ inputImage.getOrThrow("inputImage")
+
+ /** An audio input to the model. */
+ fun asResponseInputAudio(): ResponseInputAudio =
+ responseInputAudio.getOrThrow("responseInputAudio")
+
+ fun _json(): Optional = Optional.ofNullable(_json)
+
+ fun accept(visitor: Visitor): T =
+ when {
+ textInput != null -> visitor.visitTextInput(textInput)
+ responseInputText != null ->
+ visitor.visitResponseInputText(responseInputText)
+ outputText != null ->
+ visitor.visitOutputText(outputText)
+ inputImage != null ->
+ visitor.visitInputImage(inputImage)
+ responseInputAudio != null ->
+ visitor.visitResponseInputAudio(responseInputAudio)
+ else -> visitor.unknown(_json)
+ }
+
+ private var validated: Boolean = false
+
+ fun validate(): EvalContentItem = apply {
+ if (validated) {
+ return@apply
+ }
+
+ accept(
+ object : Visitor {
+ override fun visitTextInput(textInput: String) {}
+
+ override fun visitResponseInputText(
+ responseInputText: ResponseInputText
+ ) {
+ responseInputText.validate()
+ }
+
+ override fun visitOutputText(
+ outputText: OutputText
+ ) {
+ outputText.validate()
+ }
+
+ override fun visitInputImage(
+ inputImage: InputImage
+ ) {
+ inputImage.validate()
+ }
+
+ override fun visitResponseInputAudio(
+ responseInputAudio: ResponseInputAudio
+ ) {
+ responseInputAudio.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 visitTextInput(textInput: String) = 1
+
+ override fun visitResponseInputText(
+ responseInputText: ResponseInputText
+ ) = responseInputText.validity()
+
+ override fun visitOutputText(
+ outputText: OutputText
+ ) = outputText.validity()
+
+ override fun visitInputImage(
+ inputImage: InputImage
+ ) = inputImage.validity()
+
+ override fun visitResponseInputAudio(
+ responseInputAudio: ResponseInputAudio
+ ) = responseInputAudio.validity()
+
+ override fun unknown(json: JsonValue?) = 0
+ }
+ )
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) {
+ return true
+ }
+
+ return other is EvalContentItem &&
+ textInput == other.textInput &&
+ responseInputText == other.responseInputText &&
+ outputText == other.outputText &&
+ inputImage == other.inputImage &&
+ responseInputAudio == other.responseInputAudio
+ }
+
+ override fun hashCode(): Int =
+ Objects.hash(
+ textInput,
+ responseInputText,
+ outputText,
+ inputImage,
+ responseInputAudio,
+ )
+
+ override fun toString(): String =
+ when {
+ textInput != null ->
+ "EvalContentItem{textInput=$textInput}"
+ responseInputText != null ->
+ "EvalContentItem{responseInputText=$responseInputText}"
+ outputText != null ->
+ "EvalContentItem{outputText=$outputText}"
+ inputImage != null ->
+ "EvalContentItem{inputImage=$inputImage}"
+ responseInputAudio != null ->
+ "EvalContentItem{responseInputAudio=$responseInputAudio}"
+ _json != null -> "EvalContentItem{_unknown=$_json}"
+ else ->
+ throw IllegalStateException(
+ "Invalid EvalContentItem"
+ )
+ }
+
+ companion object {
+
+ /** A text input to the model. */
+ @JvmStatic
+ fun ofTextInput(textInput: String) =
+ EvalContentItem(textInput = textInput)
+
+ /** A text input to the model. */
+ @JvmStatic
+ fun ofResponseInputText(
+ responseInputText: ResponseInputText
+ ) = EvalContentItem(responseInputText = responseInputText)
+
+ /** A text output from the model. */
+ @JvmStatic
+ fun ofOutputText(outputText: OutputText) =
+ EvalContentItem(outputText = outputText)
+
+ /**
+ * An image input block used within EvalItem content arrays.
+ */
+ @JvmStatic
+ fun ofInputImage(inputImage: InputImage) =
+ EvalContentItem(inputImage = inputImage)
+
+ /** An audio input to the model. */
+ @JvmStatic
+ fun ofResponseInputAudio(
+ responseInputAudio: ResponseInputAudio
+ ) = EvalContentItem(responseInputAudio = responseInputAudio)
+ }
+
+ /**
+ * An interface that defines how to map each variant of
+ * [EvalContentItem] to a value of type [T].
+ */
+ interface Visitor {
+
+ /** A text input to the model. */
+ fun visitTextInput(textInput: String): T
+
+ /** A text input to the model. */
+ fun visitResponseInputText(
+ responseInputText: ResponseInputText
+ ): T
+
+ /** A text output from the model. */
+ fun visitOutputText(outputText: OutputText): T
+
+ /**
+ * An image input block used within EvalItem content arrays.
+ */
+ fun visitInputImage(inputImage: InputImage): T
+
+ /** An audio input to the model. */
+ fun visitResponseInputAudio(
+ responseInputAudio: ResponseInputAudio
+ ): T
+
+ /**
+ * Maps an unknown variant of [EvalContentItem] to a value
+ * of type [T].
+ *
+ * An instance of [EvalContentItem] 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 EvalContentItem: $json"
+ )
+ }
+ }
+
+ internal class Deserializer :
+ BaseDeserializer(EvalContentItem::class) {
+
+ override fun ObjectCodec.deserialize(
+ node: JsonNode
+ ): EvalContentItem {
+ val json = JsonValue.fromJsonNode(node)
+
+ val bestMatches =
+ sequenceOf(
+ tryDeserialize(
+ node,
+ jacksonTypeRef(),
+ )
+ ?.let {
+ EvalContentItem(
+ responseInputText = it,
+ _json = json,
+ )
+ },
+ tryDeserialize(
+ node,
+ jacksonTypeRef(),
+ )
+ ?.let {
+ EvalContentItem(
+ outputText = it,
+ _json = json,
+ )
+ },
+ tryDeserialize(
+ node,
+ jacksonTypeRef(),
+ )
+ ?.let {
+ EvalContentItem(
+ inputImage = it,
+ _json = json,
+ )
+ },
+ tryDeserialize(
+ node,
+ jacksonTypeRef(),
+ )
+ ?.let {
+ EvalContentItem(
+ responseInputAudio = it,
+ _json = json,
+ )
+ },
+ tryDeserialize(
+ node,
+ jacksonTypeRef(),
+ )
+ ?.let {
+ EvalContentItem(
+ textInput = it,
+ _json = json,
+ )
+ },
+ )
+ .filterNotNull()
+ .allMaxBy { it.validity() }
+ .toList()
+ return when (bestMatches.size) {
+ // This can happen if what we're deserializing is
+ // completely incompatible with all the possible
+ // variants (e.g. deserializing from array).
+ 0 -> EvalContentItem(_json = json)
+ 1 -> bestMatches.single()
+ // If there's more than one match with the highest
+ // validity, then use the first completely valid
+ // match, or simply the first match if none are
+ // completely valid.
+ else ->
+ bestMatches.firstOrNull { it.isValid() }
+ ?: bestMatches.first()
+ }
+ }
+ }
+
+ internal class Serializer :
+ BaseSerializer(EvalContentItem::class) {
+
+ override fun serialize(
+ value: EvalContentItem,
+ generator: JsonGenerator,
+ provider: SerializerProvider,
+ ) {
+ when {
+ value.textInput != null ->
+ generator.writeObject(value.textInput)
+ value.responseInputText != null ->
+ generator.writeObject(value.responseInputText)
+ value.outputText != null ->
+ generator.writeObject(value.outputText)
+ value.inputImage != null ->
+ generator.writeObject(value.inputImage)
+ value.responseInputAudio != null ->
+ generator.writeObject(value.responseInputAudio)
+ value._json != null ->
+ generator.writeObject(value._json)
+ else ->
+ throw IllegalStateException(
+ "Invalid EvalContentItem"
+ )
+ }
+ }
+ }
+
+ /** A text output from the model. */
+ class OutputText
+ @JsonCreator(mode = JsonCreator.Mode.DISABLED)
+ private constructor(
+ private val text: JsonField,
+ private val type: JsonValue,
+ private val additionalProperties:
+ MutableMap,
+ ) {
+
+ @JsonCreator
+ private constructor(
+ @JsonProperty("text")
+ @ExcludeMissing
+ text: JsonField = JsonMissing.of(),
+ @JsonProperty("type")
+ @ExcludeMissing
+ type: JsonValue = JsonMissing.of(),
+ ) : this(text, type, mutableMapOf())
+
+ /**
+ * The text output 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).
+ */
+ fun text(): String = text.getRequired("text")
+
+ /**
+ * The type of the output text. Always `output_text`.
+ *
+ * Expected to always return the following:
+ * ```java
+ * JsonValue.from("output_text")
+ * ```
+ *
+ * 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 [text].
+ *
+ * Unlike [text], this method doesn't throw if the JSON
+ * field has an unexpected type.
+ */
+ @JsonProperty("text")
+ @ExcludeMissing
+ fun _text(): JsonField = text
+
+ @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 [OutputText].
+ *
+ * The following fields are required:
+ * ```java
+ * .text()
+ * ```
+ */
+ @JvmStatic fun builder() = Builder()
+ }
+
+ /** A builder for [OutputText]. */
+ class Builder internal constructor() {
+
+ private var text: JsonField? = null
+ private var type: JsonValue =
+ JsonValue.from("output_text")
+ private var additionalProperties:
+ MutableMap =
+ mutableMapOf()
+
+ @JvmSynthetic
+ internal fun from(outputText: OutputText) = apply {
+ text = outputText.text
+ type = outputText.type
+ additionalProperties =
+ outputText.additionalProperties.toMutableMap()
+ }
+
+ /** The text output from the model. */
+ 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
+ }
+
+ /**
+ * 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("output_text")
+ * ```
+ *
+ * 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 [OutputText].
+ *
+ * Further updates to this [Builder] will not mutate the
+ * returned instance.
+ *
+ * The following fields are required:
+ * ```java
+ * .text()
+ * ```
+ *
+ * @throws IllegalStateException if any required field
+ * is unset.
+ */
+ fun build(): OutputText =
+ OutputText(
+ checkRequired("text", text),
+ type,
+ additionalProperties.toMutableMap(),
+ )
+ }
+
+ private var validated: Boolean = false
+
+ fun validate(): OutputText = apply {
+ if (validated) {
+ return@apply
+ }
+
+ text()
+ _type().let {
+ if (it != JsonValue.from("output_text")) {
+ 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 (text.asKnown().isPresent) 1 else 0) +
+ type.let {
+ if (it == JsonValue.from("output_text")) 1
+ else 0
+ }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) {
+ return true
+ }
+
+ return other is OutputText &&
+ text == other.text &&
+ type == other.type &&
+ additionalProperties == other.additionalProperties
+ }
+
+ private val hashCode: Int by lazy {
+ Objects.hash(text, type, additionalProperties)
+ }
+
+ override fun hashCode(): Int = hashCode
+
+ override fun toString() =
+ "OutputText{text=$text, type=$type, additionalProperties=$additionalProperties}"
+ }
+
+ /** An image input block used within EvalItem content arrays. */
+ class InputImage
+ @JsonCreator(mode = JsonCreator.Mode.DISABLED)
+ private constructor(
+ private val imageUrl: JsonField,
+ private val type: JsonValue,
+ private val detail: JsonField,
+ private val additionalProperties:
+ MutableMap,
+ ) {
+
+ @JsonCreator
+ private constructor(
+ @JsonProperty("image_url")
+ @ExcludeMissing
+ imageUrl: JsonField = JsonMissing.of(),
+ @JsonProperty("type")
+ @ExcludeMissing
+ type: JsonValue = JsonMissing.of(),
+ @JsonProperty("detail")
+ @ExcludeMissing
+ detail: JsonField = JsonMissing.of(),
+ ) : this(imageUrl, type, detail, mutableMapOf())
+
+ /**
+ * The URL of the image input.
+ *
+ * @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 imageUrl(): String = imageUrl.getRequired("image_url")
+
+ /**
+ * The type of the image input. Always `input_image`.
+ *
+ * Expected to always return the following:
+ * ```java
+ * JsonValue.from("input_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
+
+ /**
+ * The detail level of the image to be sent to the model.
+ * One of `high`, `low`, or `auto`. Defaults to `auto`.
+ *
+ * @throws OpenAIInvalidDataException if the JSON field has
+ * an unexpected type (e.g. if the server responded with
+ * an unexpected value).
+ */
+ fun detail(): Optional =
+ detail.getOptional("detail")
+
+ /**
+ * Returns the raw JSON value of [imageUrl].
+ *
+ * Unlike [imageUrl], this method doesn't throw if the JSON
+ * field has an unexpected type.
+ */
+ @JsonProperty("image_url")
+ @ExcludeMissing
+ fun _imageUrl(): JsonField = imageUrl
+
+ /**
+ * Returns the raw JSON value of [detail].
+ *
+ * Unlike [detail], this method doesn't throw if the JSON
+ * field has an unexpected type.
+ */
+ @JsonProperty("detail")
+ @ExcludeMissing
+ fun _detail(): JsonField = detail
+
+ @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 [InputImage].
+ *
+ * The following fields are required:
+ * ```java
+ * .imageUrl()
+ * ```
+ */
+ @JvmStatic fun builder() = Builder()
+ }
+
+ /** A builder for [InputImage]. */
+ class Builder internal constructor() {
+
+ private var imageUrl: JsonField? = null
+ private var type: JsonValue =
+ JsonValue.from("input_image")
+ private var detail: JsonField = JsonMissing.of()
+ private var additionalProperties:
+ MutableMap =
+ mutableMapOf()
+
+ @JvmSynthetic
+ internal fun from(inputImage: InputImage) = apply {
+ imageUrl = inputImage.imageUrl
+ type = inputImage.type
+ detail = inputImage.detail
+ additionalProperties =
+ inputImage.additionalProperties.toMutableMap()
+ }
+
+ /** The URL of the image input. */
+ fun imageUrl(imageUrl: String) =
+ imageUrl(JsonField.of(imageUrl))
+
+ /**
+ * Sets [Builder.imageUrl] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.imageUrl] with a
+ * well-typed [String] value instead. This method is
+ * primarily for setting the field to an undocumented or
+ * not yet supported value.
+ */
+ fun imageUrl(imageUrl: JsonField) = apply {
+ this.imageUrl = imageUrl
+ }
+
+ /**
+ * 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("input_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 }
+
+ /**
+ * The detail level of the image to be sent to the
+ * model. One of `high`, `low`, or `auto`. Defaults to
+ * `auto`.
+ */
+ fun detail(detail: String) =
+ detail(JsonField.of(detail))
+
+ /**
+ * Sets [Builder.detail] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.detail] with a
+ * well-typed [String] value instead. This method is
+ * primarily for setting the field to an undocumented or
+ * not yet supported value.
+ */
+ fun detail(detail: JsonField) = apply {
+ this.detail = detail
+ }
+
+ 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 [InputImage].
+ *
+ * Further updates to this [Builder] will not mutate the
+ * returned instance.
+ *
+ * The following fields are required:
+ * ```java
+ * .imageUrl()
+ * ```
+ *
+ * @throws IllegalStateException if any required field
+ * is unset.
+ */
+ fun build(): InputImage =
+ InputImage(
+ checkRequired("imageUrl", imageUrl),
+ type,
+ detail,
+ additionalProperties.toMutableMap(),
+ )
+ }
+
+ private var validated: Boolean = false
+
+ fun validate(): InputImage = apply {
+ if (validated) {
+ return@apply
+ }
+
+ imageUrl()
+ _type().let {
+ if (it != JsonValue.from("input_image")) {
+ throw OpenAIInvalidDataException(
+ "'type' is invalid, received $it"
+ )
+ }
+ }
+ detail()
+ 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 (imageUrl.asKnown().isPresent) 1 else 0) +
+ type.let {
+ if (it == JsonValue.from("input_image")) 1
+ else 0
+ } +
+ (if (detail.asKnown().isPresent) 1 else 0)
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) {
+ return true
+ }
+
+ return other is InputImage &&
+ imageUrl == other.imageUrl &&
+ type == other.type &&
+ detail == other.detail &&
+ additionalProperties == other.additionalProperties
+ }
+
+ private val hashCode: Int by lazy {
+ Objects.hash(
+ imageUrl,
+ type,
+ detail,
+ additionalProperties,
+ )
+ }
+
+ override fun hashCode(): Int = hashCode
+
+ override fun toString() =
+ "InputImage{imageUrl=$imageUrl, type=$type, detail=$detail, additionalProperties=$additionalProperties}"
+ }
+ }
}
/**
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunCreateParams.kt
index 263508bf..d0d62e4d 100644
--- a/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunCreateParams.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunCreateParams.kt
@@ -29,6 +29,7 @@ import com.openai.core.http.Headers
import com.openai.core.http.QueryParams
import com.openai.core.toImmutable
import com.openai.errors.OpenAIInvalidDataException
+import com.openai.models.EvalContentItem
import com.openai.models.ReasoningEffort
import com.openai.models.ResponseFormatJsonObject
import com.openai.models.ResponseFormatText
@@ -4115,7 +4116,9 @@ private constructor(
) : this(content, role, type, mutableMapOf())
/**
- * Inputs to the model - can contain template strings.
+ * Inputs to the model - can contain template strings. Supports text,
+ * output text, input images, and input audio, either as a single item
+ * or an array of items.
*
* @throws OpenAIInvalidDataException if the JSON field has an
* unexpected type or is unexpectedly missing or null (e.g. if the
@@ -4217,7 +4220,11 @@ private constructor(
evalItem.additionalProperties.toMutableMap()
}
- /** Inputs to the model - can contain template strings. */
+ /**
+ * Inputs to the model - can contain template strings. Supports
+ * text, output text, input images, and input audio, either as a
+ * single item or an array of items.
+ */
fun content(content: Content) = content(JsonField.of(content))
/**
@@ -4268,16 +4275,10 @@ private constructor(
/**
* Alias for calling [content] with
- * `Content.ofAnArrayOfInputTextInputImageAndInputAudio(anArrayOfInputTextInputImageAndInputAudio)`.
+ * `Content.ofGraderInputs(graderInputs)`.
*/
- fun contentOfAnArrayOfInputTextInputImageAndInputAudio(
- anArrayOfInputTextInputImageAndInputAudio: List
- ) =
- content(
- Content.ofAnArrayOfInputTextInputImageAndInputAudio(
- anArrayOfInputTextInputImageAndInputAudio
- )
- )
+ fun contentOfGraderInputs(graderInputs: List) =
+ content(Content.ofGraderInputs(graderInputs))
/**
* The role of the message input. One of `user`, `assistant`,
@@ -4385,7 +4386,11 @@ private constructor(
(role.asKnown().getOrNull()?.validity() ?: 0) +
(type.asKnown().getOrNull()?.validity() ?: 0)
- /** Inputs to the model - can contain template strings. */
+ /**
+ * Inputs to the model - can contain template strings. Supports text,
+ * output text, input images, and input audio, either as a single item
+ * or an array of items.
+ */
@JsonDeserialize(using = Content.Deserializer::class)
@JsonSerialize(using = Content.Serializer::class)
class Content
@@ -4395,9 +4400,7 @@ private constructor(
private val outputText: OutputText? = null,
private val inputImage: InputImage? = null,
private val responseInputAudio: ResponseInputAudio? = null,
- private val anArrayOfInputTextInputImageAndInputAudio:
- List? =
- null,
+ private val graderInputs: List? = null,
private val _json: JsonValue? = null,
) {
@@ -4412,7 +4415,7 @@ private constructor(
fun outputText(): Optional =
Optional.ofNullable(outputText)
- /** An image input to the model. */
+ /** An image input block used within EvalItem content arrays. */
fun inputImage(): Optional =
Optional.ofNullable(inputImage)
@@ -4422,11 +4425,10 @@ private constructor(
/**
* A list of inputs, each of which may be either an input text,
- * input image, or input audio object.
+ * output text, input image, or input audio object.
*/
- fun anArrayOfInputTextInputImageAndInputAudio():
- Optional> =
- Optional.ofNullable(anArrayOfInputTextInputImageAndInputAudio)
+ fun graderInputs(): Optional> =
+ Optional.ofNullable(graderInputs)
fun isTextInput(): Boolean = textInput != null
@@ -4438,8 +4440,7 @@ private constructor(
fun isResponseInputAudio(): Boolean = responseInputAudio != null
- fun isAnArrayOfInputTextInputImageAndInputAudio(): Boolean =
- anArrayOfInputTextInputImageAndInputAudio != null
+ fun isGraderInputs(): Boolean = graderInputs != null
/** A text input to the model. */
fun asTextInput(): String = textInput.getOrThrow("textInput")
@@ -4451,7 +4452,7 @@ private constructor(
/** A text output from the model. */
fun asOutputText(): OutputText = outputText.getOrThrow("outputText")
- /** An image input to the model. */
+ /** An image input block used within EvalItem content arrays. */
fun asInputImage(): InputImage = inputImage.getOrThrow("inputImage")
/** An audio input to the model. */
@@ -4460,12 +4461,10 @@ private constructor(
/**
* A list of inputs, each of which may be either an input text,
- * input image, or input audio object.
+ * output text, input image, or input audio object.
*/
- fun asAnArrayOfInputTextInputImageAndInputAudio(): List =
- anArrayOfInputTextInputImageAndInputAudio.getOrThrow(
- "anArrayOfInputTextInputImageAndInputAudio"
- )
+ fun asGraderInputs(): List =
+ graderInputs.getOrThrow("graderInputs")
fun _json(): Optional = Optional.ofNullable(_json)
@@ -4478,10 +4477,8 @@ private constructor(
inputImage != null -> visitor.visitInputImage(inputImage)
responseInputAudio != null ->
visitor.visitResponseInputAudio(responseInputAudio)
- anArrayOfInputTextInputImageAndInputAudio != null ->
- visitor.visitAnArrayOfInputTextInputImageAndInputAudio(
- anArrayOfInputTextInputImageAndInputAudio
- )
+ graderInputs != null ->
+ visitor.visitGraderInputs(graderInputs)
else -> visitor.unknown(_json)
}
@@ -4516,10 +4513,11 @@ private constructor(
responseInputAudio.validate()
}
- override fun visitAnArrayOfInputTextInputImageAndInputAudio(
- anArrayOfInputTextInputImageAndInputAudio:
- List
- ) {}
+ override fun visitGraderInputs(
+ graderInputs: List
+ ) {
+ graderInputs.forEach { it.validate() }
+ }
}
)
validated = true
@@ -4559,10 +4557,9 @@ private constructor(
responseInputAudio: ResponseInputAudio
) = responseInputAudio.validity()
- override fun visitAnArrayOfInputTextInputImageAndInputAudio(
- anArrayOfInputTextInputImageAndInputAudio:
- List
- ) = anArrayOfInputTextInputImageAndInputAudio.size
+ override fun visitGraderInputs(
+ graderInputs: List
+ ) = graderInputs.sumOf { it.validity().toInt() }
override fun unknown(json: JsonValue?) = 0
}
@@ -4579,8 +4576,7 @@ private constructor(
outputText == other.outputText &&
inputImage == other.inputImage &&
responseInputAudio == other.responseInputAudio &&
- anArrayOfInputTextInputImageAndInputAudio ==
- other.anArrayOfInputTextInputImageAndInputAudio
+ graderInputs == other.graderInputs
}
override fun hashCode(): Int =
@@ -4590,7 +4586,7 @@ private constructor(
outputText,
inputImage,
responseInputAudio,
- anArrayOfInputTextInputImageAndInputAudio,
+ graderInputs,
)
override fun toString(): String =
@@ -4602,8 +4598,8 @@ private constructor(
inputImage != null -> "Content{inputImage=$inputImage}"
responseInputAudio != null ->
"Content{responseInputAudio=$responseInputAudio}"
- anArrayOfInputTextInputImageAndInputAudio != null ->
- "Content{anArrayOfInputTextInputImageAndInputAudio=$anArrayOfInputTextInputImageAndInputAudio}"
+ graderInputs != null ->
+ "Content{graderInputs=$graderInputs}"
_json != null -> "Content{_unknown=$_json}"
else -> throw IllegalStateException("Invalid Content")
}
@@ -4625,7 +4621,7 @@ private constructor(
fun ofOutputText(outputText: OutputText) =
Content(outputText = outputText)
- /** An image input to the model. */
+ /** An image input block used within EvalItem content arrays. */
@JvmStatic
fun ofInputImage(inputImage: InputImage) =
Content(inputImage = inputImage)
@@ -4638,17 +4634,11 @@ private constructor(
/**
* A list of inputs, each of which may be either an input text,
- * input image, or input audio object.
+ * output text, input image, or input audio object.
*/
@JvmStatic
- fun ofAnArrayOfInputTextInputImageAndInputAudio(
- anArrayOfInputTextInputImageAndInputAudio: List
- ) =
- Content(
- anArrayOfInputTextInputImageAndInputAudio =
- anArrayOfInputTextInputImageAndInputAudio
- .toImmutable()
- )
+ fun ofGraderInputs(graderInputs: List) =
+ Content(graderInputs = graderInputs.toImmutable())
}
/**
@@ -4668,7 +4658,7 @@ private constructor(
/** A text output from the model. */
fun visitOutputText(outputText: OutputText): T
- /** An image input to the model. */
+ /** An image input block used within EvalItem content arrays. */
fun visitInputImage(inputImage: InputImage): T
/** An audio input to the model. */
@@ -4678,11 +4668,9 @@ private constructor(
/**
* A list of inputs, each of which may be either an input text,
- * input image, or input audio object.
+ * output text, input image, or input audio object.
*/
- fun visitAnArrayOfInputTextInputImageAndInputAudio(
- anArrayOfInputTextInputImageAndInputAudio: List
- ): T
+ fun visitGraderInputs(graderInputs: List): T
/**
* Maps an unknown variant of [Content] to a value of type [T].
@@ -4749,14 +4737,10 @@ private constructor(
},
tryDeserialize(
node,
- jacksonTypeRef>(),
+ jacksonTypeRef>(),
)
?.let {
- Content(
- anArrayOfInputTextInputImageAndInputAudio =
- it,
- _json = json,
- )
+ Content(graderInputs = it, _json = json)
},
)
.filterNotNull()
@@ -4798,11 +4782,8 @@ private constructor(
generator.writeObject(value.inputImage)
value.responseInputAudio != null ->
generator.writeObject(value.responseInputAudio)
- value.anArrayOfInputTextInputImageAndInputAudio !=
- null ->
- generator.writeObject(
- value.anArrayOfInputTextInputImageAndInputAudio
- )
+ value.graderInputs != null ->
+ generator.writeObject(value.graderInputs)
value._json != null ->
generator.writeObject(value._json)
else -> throw IllegalStateException("Invalid Content")
@@ -5047,7 +5028,7 @@ private constructor(
"OutputText{text=$text, type=$type, additionalProperties=$additionalProperties}"
}
- /** An image input to the model. */
+ /** An image input block used within EvalItem content arrays. */
class InputImage
@JsonCreator(mode = JsonCreator.Mode.DISABLED)
private constructor(
@@ -5332,6 +5313,942 @@ private constructor(
override fun toString() =
"InputImage{imageUrl=$imageUrl, type=$type, detail=$detail, additionalProperties=$additionalProperties}"
}
+
+ /**
+ * A single content item: input text, output text, input image, or
+ * input audio.
+ */
+ @JsonDeserialize(using = EvalContentItem.Deserializer::class)
+ @JsonSerialize(using = EvalContentItem.Serializer::class)
+ class EvalContentItem
+ private constructor(
+ private val textInput: String? = null,
+ private val responseInputText: ResponseInputText? = null,
+ private val outputText: OutputText? = null,
+ private val inputImage: InputImage? = null,
+ private val responseInputAudio: ResponseInputAudio? = null,
+ private val _json: JsonValue? = null,
+ ) {
+
+ /** A text input to the model. */
+ fun textInput(): Optional =
+ Optional.ofNullable(textInput)
+
+ /** A text input to the model. */
+ fun responseInputText(): Optional =
+ Optional.ofNullable(responseInputText)
+
+ /** A text output from the model. */
+ fun outputText(): Optional =
+ Optional.ofNullable(outputText)
+
+ /** An image input block used within EvalItem content arrays. */
+ fun inputImage(): Optional =
+ Optional.ofNullable(inputImage)
+
+ /** An audio input to the model. */
+ fun responseInputAudio(): Optional =
+ Optional.ofNullable(responseInputAudio)
+
+ fun isTextInput(): Boolean = textInput != null
+
+ fun isResponseInputText(): Boolean = responseInputText != null
+
+ fun isOutputText(): Boolean = outputText != null
+
+ fun isInputImage(): Boolean = inputImage != null
+
+ fun isResponseInputAudio(): Boolean = responseInputAudio != null
+
+ /** A text input to the model. */
+ fun asTextInput(): String = textInput.getOrThrow("textInput")
+
+ /** A text input to the model. */
+ fun asResponseInputText(): ResponseInputText =
+ responseInputText.getOrThrow("responseInputText")
+
+ /** A text output from the model. */
+ fun asOutputText(): OutputText =
+ outputText.getOrThrow("outputText")
+
+ /** An image input block used within EvalItem content arrays. */
+ fun asInputImage(): InputImage =
+ inputImage.getOrThrow("inputImage")
+
+ /** An audio input to the model. */
+ fun asResponseInputAudio(): ResponseInputAudio =
+ responseInputAudio.getOrThrow("responseInputAudio")
+
+ fun _json(): Optional = Optional.ofNullable(_json)
+
+ fun accept(visitor: Visitor): T =
+ when {
+ textInput != null -> visitor.visitTextInput(textInput)
+ responseInputText != null ->
+ visitor.visitResponseInputText(responseInputText)
+ outputText != null ->
+ visitor.visitOutputText(outputText)
+ inputImage != null ->
+ visitor.visitInputImage(inputImage)
+ responseInputAudio != null ->
+ visitor.visitResponseInputAudio(responseInputAudio)
+ else -> visitor.unknown(_json)
+ }
+
+ private var validated: Boolean = false
+
+ fun validate(): EvalContentItem = apply {
+ if (validated) {
+ return@apply
+ }
+
+ accept(
+ object : Visitor {
+ override fun visitTextInput(textInput: String) {}
+
+ override fun visitResponseInputText(
+ responseInputText: ResponseInputText
+ ) {
+ responseInputText.validate()
+ }
+
+ override fun visitOutputText(
+ outputText: OutputText
+ ) {
+ outputText.validate()
+ }
+
+ override fun visitInputImage(
+ inputImage: InputImage
+ ) {
+ inputImage.validate()
+ }
+
+ override fun visitResponseInputAudio(
+ responseInputAudio: ResponseInputAudio
+ ) {
+ responseInputAudio.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 visitTextInput(textInput: String) = 1
+
+ override fun visitResponseInputText(
+ responseInputText: ResponseInputText
+ ) = responseInputText.validity()
+
+ override fun visitOutputText(
+ outputText: OutputText
+ ) = outputText.validity()
+
+ override fun visitInputImage(
+ inputImage: InputImage
+ ) = inputImage.validity()
+
+ override fun visitResponseInputAudio(
+ responseInputAudio: ResponseInputAudio
+ ) = responseInputAudio.validity()
+
+ override fun unknown(json: JsonValue?) = 0
+ }
+ )
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) {
+ return true
+ }
+
+ return other is EvalContentItem &&
+ textInput == other.textInput &&
+ responseInputText == other.responseInputText &&
+ outputText == other.outputText &&
+ inputImage == other.inputImage &&
+ responseInputAudio == other.responseInputAudio
+ }
+
+ override fun hashCode(): Int =
+ Objects.hash(
+ textInput,
+ responseInputText,
+ outputText,
+ inputImage,
+ responseInputAudio,
+ )
+
+ override fun toString(): String =
+ when {
+ textInput != null ->
+ "EvalContentItem{textInput=$textInput}"
+ responseInputText != null ->
+ "EvalContentItem{responseInputText=$responseInputText}"
+ outputText != null ->
+ "EvalContentItem{outputText=$outputText}"
+ inputImage != null ->
+ "EvalContentItem{inputImage=$inputImage}"
+ responseInputAudio != null ->
+ "EvalContentItem{responseInputAudio=$responseInputAudio}"
+ _json != null -> "EvalContentItem{_unknown=$_json}"
+ else ->
+ throw IllegalStateException(
+ "Invalid EvalContentItem"
+ )
+ }
+
+ companion object {
+
+ /** A text input to the model. */
+ @JvmStatic
+ fun ofTextInput(textInput: String) =
+ EvalContentItem(textInput = textInput)
+
+ /** A text input to the model. */
+ @JvmStatic
+ fun ofResponseInputText(
+ responseInputText: ResponseInputText
+ ) = EvalContentItem(responseInputText = responseInputText)
+
+ /** A text output from the model. */
+ @JvmStatic
+ fun ofOutputText(outputText: OutputText) =
+ EvalContentItem(outputText = outputText)
+
+ /**
+ * An image input block used within EvalItem content arrays.
+ */
+ @JvmStatic
+ fun ofInputImage(inputImage: InputImage) =
+ EvalContentItem(inputImage = inputImage)
+
+ /** An audio input to the model. */
+ @JvmStatic
+ fun ofResponseInputAudio(
+ responseInputAudio: ResponseInputAudio
+ ) = EvalContentItem(responseInputAudio = responseInputAudio)
+ }
+
+ /**
+ * An interface that defines how to map each variant of
+ * [EvalContentItem] to a value of type [T].
+ */
+ interface Visitor {
+
+ /** A text input to the model. */
+ fun visitTextInput(textInput: String): T
+
+ /** A text input to the model. */
+ fun visitResponseInputText(
+ responseInputText: ResponseInputText
+ ): T
+
+ /** A text output from the model. */
+ fun visitOutputText(outputText: OutputText): T
+
+ /**
+ * An image input block used within EvalItem content arrays.
+ */
+ fun visitInputImage(inputImage: InputImage): T
+
+ /** An audio input to the model. */
+ fun visitResponseInputAudio(
+ responseInputAudio: ResponseInputAudio
+ ): T
+
+ /**
+ * Maps an unknown variant of [EvalContentItem] to a value
+ * of type [T].
+ *
+ * An instance of [EvalContentItem] 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 EvalContentItem: $json"
+ )
+ }
+ }
+
+ internal class Deserializer :
+ BaseDeserializer(EvalContentItem::class) {
+
+ override fun ObjectCodec.deserialize(
+ node: JsonNode
+ ): EvalContentItem {
+ val json = JsonValue.fromJsonNode(node)
+
+ val bestMatches =
+ sequenceOf(
+ tryDeserialize(
+ node,
+ jacksonTypeRef(),
+ )
+ ?.let {
+ EvalContentItem(
+ responseInputText = it,
+ _json = json,
+ )
+ },
+ tryDeserialize(
+ node,
+ jacksonTypeRef(),
+ )
+ ?.let {
+ EvalContentItem(
+ outputText = it,
+ _json = json,
+ )
+ },
+ tryDeserialize(
+ node,
+ jacksonTypeRef(),
+ )
+ ?.let {
+ EvalContentItem(
+ inputImage = it,
+ _json = json,
+ )
+ },
+ tryDeserialize(
+ node,
+ jacksonTypeRef(),
+ )
+ ?.let {
+ EvalContentItem(
+ responseInputAudio = it,
+ _json = json,
+ )
+ },
+ tryDeserialize(
+ node,
+ jacksonTypeRef(),
+ )
+ ?.let {
+ EvalContentItem(
+ textInput = it,
+ _json = json,
+ )
+ },
+ )
+ .filterNotNull()
+ .allMaxBy { it.validity() }
+ .toList()
+ return when (bestMatches.size) {
+ // This can happen if what we're deserializing is
+ // completely incompatible with all the possible
+ // variants (e.g. deserializing from array).
+ 0 -> EvalContentItem(_json = json)
+ 1 -> bestMatches.single()
+ // If there's more than one match with the highest
+ // validity, then use the first completely valid
+ // match, or simply the first match if none are
+ // completely valid.
+ else ->
+ bestMatches.firstOrNull { it.isValid() }
+ ?: bestMatches.first()
+ }
+ }
+ }
+
+ internal class Serializer :
+ BaseSerializer(EvalContentItem::class) {
+
+ override fun serialize(
+ value: EvalContentItem,
+ generator: JsonGenerator,
+ provider: SerializerProvider,
+ ) {
+ when {
+ value.textInput != null ->
+ generator.writeObject(value.textInput)
+ value.responseInputText != null ->
+ generator.writeObject(value.responseInputText)
+ value.outputText != null ->
+ generator.writeObject(value.outputText)
+ value.inputImage != null ->
+ generator.writeObject(value.inputImage)
+ value.responseInputAudio != null ->
+ generator.writeObject(value.responseInputAudio)
+ value._json != null ->
+ generator.writeObject(value._json)
+ else ->
+ throw IllegalStateException(
+ "Invalid EvalContentItem"
+ )
+ }
+ }
+ }
+
+ /** A text output from the model. */
+ class OutputText
+ @JsonCreator(mode = JsonCreator.Mode.DISABLED)
+ private constructor(
+ private val text: JsonField,
+ private val type: JsonValue,
+ private val additionalProperties:
+ MutableMap,
+ ) {
+
+ @JsonCreator
+ private constructor(
+ @JsonProperty("text")
+ @ExcludeMissing
+ text: JsonField = JsonMissing.of(),
+ @JsonProperty("type")
+ @ExcludeMissing
+ type: JsonValue = JsonMissing.of(),
+ ) : this(text, type, mutableMapOf())
+
+ /**
+ * The text output 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).
+ */
+ fun text(): String = text.getRequired("text")
+
+ /**
+ * The type of the output text. Always `output_text`.
+ *
+ * Expected to always return the following:
+ * ```java
+ * JsonValue.from("output_text")
+ * ```
+ *
+ * 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 [text].
+ *
+ * Unlike [text], this method doesn't throw if the JSON
+ * field has an unexpected type.
+ */
+ @JsonProperty("text")
+ @ExcludeMissing
+ fun _text(): JsonField = text
+
+ @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 [OutputText].
+ *
+ * The following fields are required:
+ * ```java
+ * .text()
+ * ```
+ */
+ @JvmStatic fun builder() = Builder()
+ }
+
+ /** A builder for [OutputText]. */
+ class Builder internal constructor() {
+
+ private var text: JsonField? = null
+ private var type: JsonValue =
+ JsonValue.from("output_text")
+ private var additionalProperties:
+ MutableMap =
+ mutableMapOf()
+
+ @JvmSynthetic
+ internal fun from(outputText: OutputText) = apply {
+ text = outputText.text
+ type = outputText.type
+ additionalProperties =
+ outputText.additionalProperties.toMutableMap()
+ }
+
+ /** The text output from the model. */
+ 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
+ }
+
+ /**
+ * 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("output_text")
+ * ```
+ *
+ * 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 [OutputText].
+ *
+ * Further updates to this [Builder] will not mutate the
+ * returned instance.
+ *
+ * The following fields are required:
+ * ```java
+ * .text()
+ * ```
+ *
+ * @throws IllegalStateException if any required field
+ * is unset.
+ */
+ fun build(): OutputText =
+ OutputText(
+ checkRequired("text", text),
+ type,
+ additionalProperties.toMutableMap(),
+ )
+ }
+
+ private var validated: Boolean = false
+
+ fun validate(): OutputText = apply {
+ if (validated) {
+ return@apply
+ }
+
+ text()
+ _type().let {
+ if (it != JsonValue.from("output_text")) {
+ 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 (text.asKnown().isPresent) 1 else 0) +
+ type.let {
+ if (it == JsonValue.from("output_text")) 1
+ else 0
+ }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) {
+ return true
+ }
+
+ return other is OutputText &&
+ text == other.text &&
+ type == other.type &&
+ additionalProperties == other.additionalProperties
+ }
+
+ private val hashCode: Int by lazy {
+ Objects.hash(text, type, additionalProperties)
+ }
+
+ override fun hashCode(): Int = hashCode
+
+ override fun toString() =
+ "OutputText{text=$text, type=$type, additionalProperties=$additionalProperties}"
+ }
+
+ /** An image input block used within EvalItem content arrays. */
+ class InputImage
+ @JsonCreator(mode = JsonCreator.Mode.DISABLED)
+ private constructor(
+ private val imageUrl: JsonField,
+ private val type: JsonValue,
+ private val detail: JsonField