diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 2b28d6ec..6d78745c 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.8.1"
+ ".": "0.9.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index 18552296..86f76d76 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,2 +1,2 @@
-configured_endpoints: 24
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai-a39aca84ed97ebafb707ebd5221e2787c5a42ff3d98f2ffaea8a0dcd84cbcbcb.yml
+configured_endpoints: 60
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai-02200a58ed631064b6419711da99fefd6e97bdbbeb577a80a1a6e0c8dbcb18f5.yml
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0fd17823..7df282aa 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,34 @@
# Changelog
+## 0.9.0 (2025-01-03)
+
+Full Changelog: [v0.8.1...v0.9.0](https://github.com/openai/openai-java/compare/v0.8.1...v0.9.0)
+
+### ⚠ BREAKING CHANGES
+
+* **client:** switch query params objects to use `QueryParams` ([#64](https://github.com/openai/openai-java/issues/64))
+
+### Features
+
+* **client:** add beta endpoints ([#79](https://github.com/openai/openai-java/issues/79)) ([8584a20](https://github.com/openai/openai-java/commit/8584a2029ec5402b205ce485e96702da0a692b76))
+* **client:** put body field in params, add more convenience methods, and add missing docs ([#77](https://github.com/openai/openai-java/issues/77)) ([0c74350](https://github.com/openai/openai-java/commit/0c74350f0e5d1f0a30ae9b27c50a306ca081b1a7))
+
+
+### Chores
+
+* bump license year ([#74](https://github.com/openai/openai-java/issues/74)) ([769175d](https://github.com/openai/openai-java/commit/769175d3c42b6679e8ea91847e1fba32ab76d9a6))
+
+
+### Documentation
+
+* add some missing javadocs ([#78](https://github.com/openai/openai-java/issues/78)) ([d153ef9](https://github.com/openai/openai-java/commit/d153ef99dff3a201bf5674ee4154f3a3d276f608))
+
+
+### Refactors
+
+* **client:** switch query params objects to use `QueryParams` ([#64](https://github.com/openai/openai-java/issues/64)) ([4e9c3eb](https://github.com/openai/openai-java/commit/4e9c3eb9351f308ed3d842bd4aa2d860c23d568e))
+* **internal:** use constructor to deserialize json ([#66](https://github.com/openai/openai-java/issues/66)) ([27389cd](https://github.com/openai/openai-java/commit/27389cd377ce9a109a4aa25f78f70c36ca62de14))
+
## 0.8.1 (2024-12-21)
Full Changelog: [v0.8.0...v0.8.1](https://github.com/openai/openai-java/compare/v0.8.0...v0.8.1)
diff --git a/LICENSE b/LICENSE
index 621a6bec..f011417a 100644
--- a/LICENSE
+++ b/LICENSE
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright 2024 OpenAI
+ Copyright 2025 OpenAI
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/README.md b/README.md
index d563e776..32d66e2e 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@
-[](https://central.sonatype.com/artifact/com.openai/openai-java/0.8.1)
+[](https://central.sonatype.com/artifact/com.openai/openai-java/0.9.0)
@@ -32,7 +32,7 @@ The REST API documentation can be found on [platform.openai.com](https://platfo
```kotlin
-implementation("com.openai:openai-java:0.8.1")
+implementation("com.openai:openai-java:0.9.0")
```
#### Maven
@@ -41,7 +41,7 @@ implementation("com.openai:openai-java:0.8.1")
com.openai
openai-java
- 0.8.1
+ 0.9.0
```
diff --git a/build.gradle.kts b/build.gradle.kts
index 54d9accf..4e56d011 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -4,7 +4,7 @@ plugins {
allprojects {
group = "com.openai"
- version = "0.8.1" // x-release-please-version
+ version = "0.9.0" // x-release-please-version
}
diff --git a/openai-java-client-okhttp/src/main/kotlin/com/openai/client/okhttp/OpenAIOkHttpClient.kt b/openai-java-client-okhttp/src/main/kotlin/com/openai/client/okhttp/OpenAIOkHttpClient.kt
index ecb4e82f..0a01dc68 100644
--- a/openai-java-client-okhttp/src/main/kotlin/com/openai/client/okhttp/OpenAIOkHttpClient.kt
+++ b/openai-java-client-okhttp/src/main/kotlin/com/openai/client/okhttp/OpenAIOkHttpClient.kt
@@ -138,9 +138,9 @@ class OpenAIOkHttpClient private constructor() {
clientOptions.azureServiceVersion(azureServiceVersion)
}
- fun organization(organization: String?) = apply { clientOptions.organization(organization) }
+ fun organization(organization: String) = apply { clientOptions.organization(organization) }
- fun project(project: String?) = apply { clientOptions.project(project) }
+ fun project(project: String) = apply { clientOptions.project(project) }
fun fromEnv() = apply { clientOptions.fromEnv() }
diff --git a/openai-java-client-okhttp/src/main/kotlin/com/openai/client/okhttp/OpenAIOkHttpClientAsync.kt b/openai-java-client-okhttp/src/main/kotlin/com/openai/client/okhttp/OpenAIOkHttpClientAsync.kt
index cf4711aa..e88af696 100644
--- a/openai-java-client-okhttp/src/main/kotlin/com/openai/client/okhttp/OpenAIOkHttpClientAsync.kt
+++ b/openai-java-client-okhttp/src/main/kotlin/com/openai/client/okhttp/OpenAIOkHttpClientAsync.kt
@@ -138,9 +138,9 @@ class OpenAIOkHttpClientAsync private constructor() {
clientOptions.azureServiceVersion(azureServiceVersion)
}
- fun organization(organization: String?) = apply { clientOptions.organization(organization) }
+ fun organization(organization: String) = apply { clientOptions.organization(organization) }
- fun project(project: String?) = apply { clientOptions.project(project) }
+ fun project(project: String) = apply { clientOptions.project(project) }
fun fromEnv() = apply { clientOptions.fromEnv() }
diff --git a/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClient.kt b/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClient.kt
index 1dce1fed..d3ca56e6 100644
--- a/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClient.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClient.kt
@@ -3,6 +3,7 @@
package com.openai.client
import com.openai.services.blocking.BatchService
+import com.openai.services.blocking.BetaService
import com.openai.services.blocking.ChatService
import com.openai.services.blocking.CompletionService
import com.openai.services.blocking.EmbeddingService
@@ -33,6 +34,8 @@ interface OpenAIClient {
fun fineTuning(): FineTuningService
+ fun beta(): BetaService
+
fun batches(): BatchService
fun uploads(): UploadService
diff --git a/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientAsync.kt b/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientAsync.kt
index 88af1944..4d02824b 100644
--- a/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientAsync.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientAsync.kt
@@ -3,6 +3,7 @@
package com.openai.client
import com.openai.services.async.BatchServiceAsync
+import com.openai.services.async.BetaServiceAsync
import com.openai.services.async.ChatServiceAsync
import com.openai.services.async.CompletionServiceAsync
import com.openai.services.async.EmbeddingServiceAsync
@@ -33,6 +34,8 @@ interface OpenAIClientAsync {
fun fineTuning(): FineTuningServiceAsync
+ fun beta(): BetaServiceAsync
+
fun batches(): BatchServiceAsync
fun uploads(): UploadServiceAsync
diff --git a/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientAsyncImpl.kt
index 9a14f773..9a8ecd11 100644
--- a/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientAsyncImpl.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientAsyncImpl.kt
@@ -6,6 +6,8 @@ import com.openai.core.ClientOptions
import com.openai.core.getPackageVersion
import com.openai.services.async.BatchServiceAsync
import com.openai.services.async.BatchServiceAsyncImpl
+import com.openai.services.async.BetaServiceAsync
+import com.openai.services.async.BetaServiceAsyncImpl
import com.openai.services.async.ChatServiceAsync
import com.openai.services.async.ChatServiceAsyncImpl
import com.openai.services.async.CompletionServiceAsync
@@ -69,6 +71,8 @@ constructor(
FineTuningServiceAsyncImpl(clientOptionsWithUserAgent)
}
+ private val beta: BetaServiceAsync by lazy { BetaServiceAsyncImpl(clientOptionsWithUserAgent) }
+
private val batches: BatchServiceAsync by lazy {
BatchServiceAsyncImpl(clientOptionsWithUserAgent)
}
@@ -95,6 +99,8 @@ constructor(
override fun fineTuning(): FineTuningServiceAsync = fineTuning
+ override fun beta(): BetaServiceAsync = beta
+
override fun batches(): BatchServiceAsync = batches
override fun uploads(): UploadServiceAsync = uploads
diff --git a/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientImpl.kt b/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientImpl.kt
index 8fd7ffe0..2870b2e0 100644
--- a/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientImpl.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientImpl.kt
@@ -6,6 +6,8 @@ import com.openai.core.ClientOptions
import com.openai.core.getPackageVersion
import com.openai.services.blocking.BatchService
import com.openai.services.blocking.BatchServiceImpl
+import com.openai.services.blocking.BetaService
+import com.openai.services.blocking.BetaServiceImpl
import com.openai.services.blocking.ChatService
import com.openai.services.blocking.ChatServiceImpl
import com.openai.services.blocking.CompletionService
@@ -65,6 +67,8 @@ constructor(
FineTuningServiceImpl(clientOptionsWithUserAgent)
}
+ private val beta: BetaService by lazy { BetaServiceImpl(clientOptionsWithUserAgent) }
+
private val batches: BatchService by lazy { BatchServiceImpl(clientOptionsWithUserAgent) }
private val uploads: UploadService by lazy { UploadServiceImpl(clientOptionsWithUserAgent) }
@@ -87,6 +91,8 @@ constructor(
override fun fineTuning(): FineTuningService = fineTuning
+ override fun beta(): BetaService = beta
+
override fun batches(): BatchService = batches
override fun uploads(): UploadService = uploads
diff --git a/openai-java-core/src/main/kotlin/com/openai/core/ClientOptions.kt b/openai-java-core/src/main/kotlin/com/openai/core/ClientOptions.kt
index 6eee95f6..aa08c1c7 100644
--- a/openai-java-core/src/main/kotlin/com/openai/core/ClientOptions.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/core/ClientOptions.kt
@@ -187,9 +187,9 @@ private constructor(
this.azureServiceVersion = azureServiceVersion
}
- fun organization(organization: String?) = apply { this.organization = organization }
+ fun organization(organization: String) = apply { this.organization = organization }
- fun project(project: String?) = apply { this.project = project }
+ fun project(project: String) = apply { this.project = project }
fun fromEnv() = apply {
val openAIKey = System.getenv("OPENAI_API_KEY")
diff --git a/openai-java-core/src/main/kotlin/com/openai/core/Utils.kt b/openai-java-core/src/main/kotlin/com/openai/core/Utils.kt
index 6601f8ef..e2cfee07 100644
--- a/openai-java-core/src/main/kotlin/com/openai/core/Utils.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/core/Utils.kt
@@ -16,7 +16,9 @@ internal fun List.toImmutable(): List =
@JvmSynthetic
internal fun Map.toImmutable(): Map =
- if (isEmpty()) Collections.emptyMap() else Collections.unmodifiableMap(toMap())
+ if (isEmpty()) immutableEmptyMap() else Collections.unmodifiableMap(toMap())
+
+@JvmSynthetic internal fun immutableEmptyMap(): Map = Collections.emptyMap()
@JvmSynthetic
internal fun , V> SortedMap.toImmutable(): SortedMap =
diff --git a/openai-java-core/src/main/kotlin/com/openai/errors/OpenAIError.kt b/openai-java-core/src/main/kotlin/com/openai/errors/OpenAIError.kt
index ca3ce740..e4cbac10 100644
--- a/openai-java-core/src/main/kotlin/com/openai/errors/OpenAIError.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/errors/OpenAIError.kt
@@ -4,19 +4,23 @@ package com.openai.errors
import com.fasterxml.jackson.annotation.JsonAnyGetter
import com.fasterxml.jackson.annotation.JsonAnySetter
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize
+import com.fasterxml.jackson.annotation.JsonCreator
+import com.openai.core.ExcludeMissing
import com.openai.core.JsonValue
import com.openai.core.NoAutoDetect
+import com.openai.core.immutableEmptyMap
import com.openai.core.toImmutable
import java.util.Objects
-@JsonDeserialize(builder = OpenAIError.Builder::class)
@NoAutoDetect
class OpenAIError
+@JsonCreator
private constructor(
@JsonAnyGetter
+ @ExcludeMissing
+ @JsonAnySetter
@get:JvmName("additionalProperties")
- val additionalProperties: Map,
+ val additionalProperties: Map = immutableEmptyMap(),
) {
fun toBuilder() = Builder().from(this)
@@ -40,7 +44,6 @@ private constructor(
putAllAdditionalProperties(additionalProperties)
}
- @JsonAnySetter
fun putAdditionalProperty(key: String, value: JsonValue) = apply {
additionalProperties.put(key, value)
}
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/Annotation.kt b/openai-java-core/src/main/kotlin/com/openai/models/Annotation.kt
new file mode 100644
index 00000000..fba511f1
--- /dev/null
+++ b/openai-java-core/src/main/kotlin/com/openai/models/Annotation.kt
@@ -0,0 +1,181 @@
+// File generated from our OpenAPI spec by Stainless.
+
+package com.openai.models
+
+import com.fasterxml.jackson.core.JsonGenerator
+import com.fasterxml.jackson.core.ObjectCodec
+import com.fasterxml.jackson.databind.JsonNode
+import com.fasterxml.jackson.databind.SerializerProvider
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize
+import com.fasterxml.jackson.databind.annotation.JsonSerialize
+import com.fasterxml.jackson.module.kotlin.jacksonTypeRef
+import com.openai.core.BaseDeserializer
+import com.openai.core.BaseSerializer
+import com.openai.core.JsonValue
+import com.openai.core.getOrThrow
+import com.openai.errors.OpenAIInvalidDataException
+import java.util.Objects
+import java.util.Optional
+import kotlin.jvm.optionals.getOrNull
+
+/**
+ * A citation within the message that points to a specific quote from a specific File associated
+ * with the assistant or the message. Generated when the assistant uses the "file_search" tool to
+ * search files.
+ */
+@JsonDeserialize(using = Annotation.Deserializer::class)
+@JsonSerialize(using = Annotation.Serializer::class)
+class Annotation
+private constructor(
+ private val fileCitationAnnotation: FileCitationAnnotation? = null,
+ private val filePathAnnotation: FilePathAnnotation? = null,
+ private val _json: JsonValue? = null,
+) {
+
+ private var validated: Boolean = false
+
+ /**
+ * A citation within the message that points to a specific quote from a specific File associated
+ * with the assistant or the message. Generated when the assistant uses the "file_search" tool
+ * to search files.
+ */
+ fun fileCitationAnnotation(): Optional =
+ Optional.ofNullable(fileCitationAnnotation)
+ /**
+ * A URL for the file that's generated when the assistant used the `code_interpreter` tool to
+ * generate a file.
+ */
+ fun filePathAnnotation(): Optional = Optional.ofNullable(filePathAnnotation)
+
+ fun isFileCitationAnnotation(): Boolean = fileCitationAnnotation != null
+
+ fun isFilePathAnnotation(): Boolean = filePathAnnotation != null
+
+ /**
+ * A citation within the message that points to a specific quote from a specific File associated
+ * with the assistant or the message. Generated when the assistant uses the "file_search" tool
+ * to search files.
+ */
+ fun asFileCitationAnnotation(): FileCitationAnnotation =
+ fileCitationAnnotation.getOrThrow("fileCitationAnnotation")
+ /**
+ * A URL for the file that's generated when the assistant used the `code_interpreter` tool to
+ * generate a file.
+ */
+ fun asFilePathAnnotation(): FilePathAnnotation =
+ filePathAnnotation.getOrThrow("filePathAnnotation")
+
+ fun _json(): Optional = Optional.ofNullable(_json)
+
+ fun accept(visitor: Visitor): T {
+ return when {
+ fileCitationAnnotation != null ->
+ visitor.visitFileCitationAnnotation(fileCitationAnnotation)
+ filePathAnnotation != null -> visitor.visitFilePathAnnotation(filePathAnnotation)
+ else -> visitor.unknown(_json)
+ }
+ }
+
+ fun validate(): Annotation = apply {
+ if (!validated) {
+ if (fileCitationAnnotation == null && filePathAnnotation == null) {
+ throw OpenAIInvalidDataException("Unknown Annotation: $_json")
+ }
+ fileCitationAnnotation?.validate()
+ filePathAnnotation?.validate()
+ validated = true
+ }
+ }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) {
+ return true
+ }
+
+ return /* spotless:off */ other is Annotation && fileCitationAnnotation == other.fileCitationAnnotation && filePathAnnotation == other.filePathAnnotation /* spotless:on */
+ }
+
+ override fun hashCode(): Int = /* spotless:off */ Objects.hash(fileCitationAnnotation, filePathAnnotation) /* spotless:on */
+
+ override fun toString(): String =
+ when {
+ fileCitationAnnotation != null ->
+ "Annotation{fileCitationAnnotation=$fileCitationAnnotation}"
+ filePathAnnotation != null -> "Annotation{filePathAnnotation=$filePathAnnotation}"
+ _json != null -> "Annotation{_unknown=$_json}"
+ else -> throw IllegalStateException("Invalid Annotation")
+ }
+
+ companion object {
+
+ /**
+ * A citation within the message that points to a specific quote from a specific File
+ * associated with the assistant or the message. Generated when the assistant uses the
+ * "file_search" tool to search files.
+ */
+ @JvmStatic
+ fun ofFileCitationAnnotation(fileCitationAnnotation: FileCitationAnnotation) =
+ Annotation(fileCitationAnnotation = fileCitationAnnotation)
+
+ /**
+ * A URL for the file that's generated when the assistant used the `code_interpreter` tool
+ * to generate a file.
+ */
+ @JvmStatic
+ fun ofFilePathAnnotation(filePathAnnotation: FilePathAnnotation) =
+ Annotation(filePathAnnotation = filePathAnnotation)
+ }
+
+ interface Visitor {
+
+ fun visitFileCitationAnnotation(fileCitationAnnotation: FileCitationAnnotation): T
+
+ fun visitFilePathAnnotation(filePathAnnotation: FilePathAnnotation): T
+
+ fun unknown(json: JsonValue?): T {
+ throw OpenAIInvalidDataException("Unknown Annotation: $json")
+ }
+ }
+
+ class Deserializer : BaseDeserializer(Annotation::class) {
+
+ override fun ObjectCodec.deserialize(node: JsonNode): Annotation {
+ val json = JsonValue.fromJsonNode(node)
+ val type = json.asObject().getOrNull()?.get("type")?.asString()?.getOrNull()
+
+ when (type) {
+ "file_citation" -> {
+ tryDeserialize(node, jacksonTypeRef()) { it.validate() }
+ ?.let {
+ return Annotation(fileCitationAnnotation = it, _json = json)
+ }
+ }
+ "file_path" -> {
+ tryDeserialize(node, jacksonTypeRef()) { it.validate() }
+ ?.let {
+ return Annotation(filePathAnnotation = it, _json = json)
+ }
+ }
+ }
+
+ return Annotation(_json = json)
+ }
+ }
+
+ class Serializer : BaseSerializer(Annotation::class) {
+
+ override fun serialize(
+ value: Annotation,
+ generator: JsonGenerator,
+ provider: SerializerProvider
+ ) {
+ when {
+ value.fileCitationAnnotation != null ->
+ generator.writeObject(value.fileCitationAnnotation)
+ value.filePathAnnotation != null -> generator.writeObject(value.filePathAnnotation)
+ value._json != null -> generator.writeObject(value._json)
+ else -> throw IllegalStateException("Invalid Annotation")
+ }
+ }
+ }
+}
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/AnnotationDelta.kt b/openai-java-core/src/main/kotlin/com/openai/models/AnnotationDelta.kt
new file mode 100644
index 00000000..71c89ad4
--- /dev/null
+++ b/openai-java-core/src/main/kotlin/com/openai/models/AnnotationDelta.kt
@@ -0,0 +1,192 @@
+// File generated from our OpenAPI spec by Stainless.
+
+package com.openai.models
+
+import com.fasterxml.jackson.core.JsonGenerator
+import com.fasterxml.jackson.core.ObjectCodec
+import com.fasterxml.jackson.databind.JsonNode
+import com.fasterxml.jackson.databind.SerializerProvider
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize
+import com.fasterxml.jackson.databind.annotation.JsonSerialize
+import com.fasterxml.jackson.module.kotlin.jacksonTypeRef
+import com.openai.core.BaseDeserializer
+import com.openai.core.BaseSerializer
+import com.openai.core.JsonValue
+import com.openai.core.getOrThrow
+import com.openai.errors.OpenAIInvalidDataException
+import java.util.Objects
+import java.util.Optional
+import kotlin.jvm.optionals.getOrNull
+
+/**
+ * A citation within the message that points to a specific quote from a specific File associated
+ * with the assistant or the message. Generated when the assistant uses the "file_search" tool to
+ * search files.
+ */
+@JsonDeserialize(using = AnnotationDelta.Deserializer::class)
+@JsonSerialize(using = AnnotationDelta.Serializer::class)
+class AnnotationDelta
+private constructor(
+ private val fileCitationDeltaAnnotation: FileCitationDeltaAnnotation? = null,
+ private val filePathDeltaAnnotation: FilePathDeltaAnnotation? = null,
+ private val _json: JsonValue? = null,
+) {
+
+ private var validated: Boolean = false
+
+ /**
+ * A citation within the message that points to a specific quote from a specific File associated
+ * with the assistant or the message. Generated when the assistant uses the "file_search" tool
+ * to search files.
+ */
+ fun fileCitationDeltaAnnotation(): Optional =
+ Optional.ofNullable(fileCitationDeltaAnnotation)
+ /**
+ * A URL for the file that's generated when the assistant used the `code_interpreter` tool to
+ * generate a file.
+ */
+ fun filePathDeltaAnnotation(): Optional =
+ Optional.ofNullable(filePathDeltaAnnotation)
+
+ fun isFileCitationDeltaAnnotation(): Boolean = fileCitationDeltaAnnotation != null
+
+ fun isFilePathDeltaAnnotation(): Boolean = filePathDeltaAnnotation != null
+
+ /**
+ * A citation within the message that points to a specific quote from a specific File associated
+ * with the assistant or the message. Generated when the assistant uses the "file_search" tool
+ * to search files.
+ */
+ fun asFileCitationDeltaAnnotation(): FileCitationDeltaAnnotation =
+ fileCitationDeltaAnnotation.getOrThrow("fileCitationDeltaAnnotation")
+ /**
+ * A URL for the file that's generated when the assistant used the `code_interpreter` tool to
+ * generate a file.
+ */
+ fun asFilePathDeltaAnnotation(): FilePathDeltaAnnotation =
+ filePathDeltaAnnotation.getOrThrow("filePathDeltaAnnotation")
+
+ fun _json(): Optional = Optional.ofNullable(_json)
+
+ fun accept(visitor: Visitor): T {
+ return when {
+ fileCitationDeltaAnnotation != null ->
+ visitor.visitFileCitationDeltaAnnotation(fileCitationDeltaAnnotation)
+ filePathDeltaAnnotation != null ->
+ visitor.visitFilePathDeltaAnnotation(filePathDeltaAnnotation)
+ else -> visitor.unknown(_json)
+ }
+ }
+
+ fun validate(): AnnotationDelta = apply {
+ if (!validated) {
+ if (fileCitationDeltaAnnotation == null && filePathDeltaAnnotation == null) {
+ throw OpenAIInvalidDataException("Unknown AnnotationDelta: $_json")
+ }
+ fileCitationDeltaAnnotation?.validate()
+ filePathDeltaAnnotation?.validate()
+ validated = true
+ }
+ }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) {
+ return true
+ }
+
+ return /* spotless:off */ other is AnnotationDelta && fileCitationDeltaAnnotation == other.fileCitationDeltaAnnotation && filePathDeltaAnnotation == other.filePathDeltaAnnotation /* spotless:on */
+ }
+
+ override fun hashCode(): Int = /* spotless:off */ Objects.hash(fileCitationDeltaAnnotation, filePathDeltaAnnotation) /* spotless:on */
+
+ override fun toString(): String =
+ when {
+ fileCitationDeltaAnnotation != null ->
+ "AnnotationDelta{fileCitationDeltaAnnotation=$fileCitationDeltaAnnotation}"
+ filePathDeltaAnnotation != null ->
+ "AnnotationDelta{filePathDeltaAnnotation=$filePathDeltaAnnotation}"
+ _json != null -> "AnnotationDelta{_unknown=$_json}"
+ else -> throw IllegalStateException("Invalid AnnotationDelta")
+ }
+
+ companion object {
+
+ /**
+ * A citation within the message that points to a specific quote from a specific File
+ * associated with the assistant or the message. Generated when the assistant uses the
+ * "file_search" tool to search files.
+ */
+ @JvmStatic
+ fun ofFileCitationDeltaAnnotation(
+ fileCitationDeltaAnnotation: FileCitationDeltaAnnotation
+ ) = AnnotationDelta(fileCitationDeltaAnnotation = fileCitationDeltaAnnotation)
+
+ /**
+ * A URL for the file that's generated when the assistant used the `code_interpreter` tool
+ * to generate a file.
+ */
+ @JvmStatic
+ fun ofFilePathDeltaAnnotation(filePathDeltaAnnotation: FilePathDeltaAnnotation) =
+ AnnotationDelta(filePathDeltaAnnotation = filePathDeltaAnnotation)
+ }
+
+ interface Visitor {
+
+ fun visitFileCitationDeltaAnnotation(
+ fileCitationDeltaAnnotation: FileCitationDeltaAnnotation
+ ): T
+
+ fun visitFilePathDeltaAnnotation(filePathDeltaAnnotation: FilePathDeltaAnnotation): T
+
+ fun unknown(json: JsonValue?): T {
+ throw OpenAIInvalidDataException("Unknown AnnotationDelta: $json")
+ }
+ }
+
+ class Deserializer : BaseDeserializer(AnnotationDelta::class) {
+
+ override fun ObjectCodec.deserialize(node: JsonNode): AnnotationDelta {
+ val json = JsonValue.fromJsonNode(node)
+ val type = json.asObject().getOrNull()?.get("type")?.asString()?.getOrNull()
+
+ when (type) {
+ "file_citation" -> {
+ tryDeserialize(node, jacksonTypeRef()) {
+ it.validate()
+ }
+ ?.let {
+ return AnnotationDelta(fileCitationDeltaAnnotation = it, _json = json)
+ }
+ }
+ "file_path" -> {
+ tryDeserialize(node, jacksonTypeRef()) {
+ it.validate()
+ }
+ ?.let {
+ return AnnotationDelta(filePathDeltaAnnotation = it, _json = json)
+ }
+ }
+ }
+
+ return AnnotationDelta(_json = json)
+ }
+ }
+
+ class Serializer : BaseSerializer(AnnotationDelta::class) {
+
+ override fun serialize(
+ value: AnnotationDelta,
+ generator: JsonGenerator,
+ provider: SerializerProvider
+ ) {
+ when {
+ value.fileCitationDeltaAnnotation != null ->
+ generator.writeObject(value.fileCitationDeltaAnnotation)
+ value.filePathDeltaAnnotation != null ->
+ generator.writeObject(value.filePathDeltaAnnotation)
+ value._json != null -> generator.writeObject(value._json)
+ else -> throw IllegalStateException("Invalid AnnotationDelta")
+ }
+ }
+ }
+}
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/Assistant.kt b/openai-java-core/src/main/kotlin/com/openai/models/Assistant.kt
new file mode 100644
index 00000000..061e331f
--- /dev/null
+++ b/openai-java-core/src/main/kotlin/com/openai/models/Assistant.kt
@@ -0,0 +1,935 @@
+// File generated from our OpenAPI spec by Stainless.
+
+package com.openai.models
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter
+import com.fasterxml.jackson.annotation.JsonAnySetter
+import com.fasterxml.jackson.annotation.JsonCreator
+import com.fasterxml.jackson.annotation.JsonProperty
+import com.openai.core.Enum
+import com.openai.core.ExcludeMissing
+import com.openai.core.JsonField
+import com.openai.core.JsonMissing
+import com.openai.core.JsonValue
+import com.openai.core.NoAutoDetect
+import com.openai.core.immutableEmptyMap
+import com.openai.core.toImmutable
+import com.openai.errors.OpenAIInvalidDataException
+import java.util.Objects
+import java.util.Optional
+
+/** Represents an `assistant` that can call the model and use tools. */
+@NoAutoDetect
+class Assistant
+@JsonCreator
+private constructor(
+ @JsonProperty("id") @ExcludeMissing private val id: JsonField = JsonMissing.of(),
+ @JsonProperty("object")
+ @ExcludeMissing
+ private val object_: JsonField