diff --git a/.github/workflows/create-releases.yml b/.github/workflows/create-releases.yml
index f7b805807..6f33bfbfd 100644
--- a/.github/workflows/create-releases.yml
+++ b/.github/workflows/create-releases.yml
@@ -73,7 +73,7 @@ jobs:
export -- GPG_SIGNING_KEY_ID
printenv -- GPG_SIGNING_KEY | gpg --batch --passphrase-fd 3 --import 3<<< "$GPG_SIGNING_PASSWORD"
GPG_SIGNING_KEY_ID="$(gpg --with-colons --list-keys | awk -F : -- '/^pub:/ { getline; print "0x" substr($10, length($10) - 7) }')"
- ./gradlew publishAndReleaseToMavenCentral -Dorg.gradle.jvmargs="-Xmx8g" --stacktrace -PmavenCentralUsername="$SONATYPE_USERNAME" -PmavenCentralPassword="$SONATYPE_PASSWORD" --no-configuration-cache
+ ./gradlew publishAndReleaseToMavenCentral --stacktrace -PmavenCentralUsername="$SONATYPE_USERNAME" -PmavenCentralPassword="$SONATYPE_PASSWORD" --no-configuration-cache
env:
SONATYPE_USERNAME: ${{ secrets.OPENAI_SONATYPE_USERNAME || secrets.SONATYPE_USERNAME }}
SONATYPE_PASSWORD: ${{ secrets.OPENAI_SONATYPE_PASSWORD || secrets.SONATYPE_PASSWORD }}
diff --git a/.github/workflows/publish-sonatype.yml b/.github/workflows/publish-sonatype.yml
index 55c74a194..74d7139c6 100644
--- a/.github/workflows/publish-sonatype.yml
+++ b/.github/workflows/publish-sonatype.yml
@@ -60,7 +60,7 @@ jobs:
export -- GPG_SIGNING_KEY_ID
printenv -- GPG_SIGNING_KEY | gpg --batch --passphrase-fd 3 --import 3<<< "$GPG_SIGNING_PASSWORD"
GPG_SIGNING_KEY_ID="$(gpg --with-colons --list-keys | awk -F : -- '/^pub:/ { getline; print "0x" substr($10, length($10) - 7) }')"
- ./gradlew publishAndReleaseToMavenCentral -Dorg.gradle.jvmargs="-Xmx8g" --stacktrace -PmavenCentralUsername="$SONATYPE_USERNAME" -PmavenCentralPassword="$SONATYPE_PASSWORD" --no-configuration-cache
+ ./gradlew publishAndReleaseToMavenCentral --stacktrace -PmavenCentralUsername="$SONATYPE_USERNAME" -PmavenCentralPassword="$SONATYPE_PASSWORD" --no-configuration-cache
env:
SONATYPE_USERNAME: ${{ secrets.OPENAI_SONATYPE_USERNAME || secrets.SONATYPE_USERNAME }}
SONATYPE_PASSWORD: ${{ secrets.OPENAI_SONATYPE_PASSWORD || secrets.SONATYPE_PASSWORD }}
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 9d7db69f9..1f73031b8 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "3.1.2"
+ ".": "3.2.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index d4994342f..f2d5304a5 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 111
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-7ef7a457c3bf05364e66e48c9ca34f31bfef1f6c9b7c15b1812346105e0abb16.yml
-openapi_spec_hash: a2b1f5d8fbb62175c93b0ebea9f10063
-config_hash: 4870312b04f48fd717ea4151053e7fb9
+configured_endpoints: 119
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-ddbdf9343316047e8a773c54fb24e4a8d225955e202a1888fde6f9c8898ebf98.yml
+openapi_spec_hash: 9802f6dd381558466c897f6e387e06ca
+config_hash: fe0ea26680ac2075a6cd66416aefe7db
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fd6798f1a..14b1a7abe 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,23 @@
# Changelog
+## 3.2.0 (2025-08-22)
+
+Full Changelog: [v3.1.2...v3.2.0](https://github.com/openai/openai-java/compare/v3.1.2...v3.2.0)
+
+### Features
+
+* **api:** Add connectors support for MCP tool ([ee175a9](https://github.com/openai/openai-java/commit/ee175a98a1ed4f1e939c301dd5bf62f10e367c6c))
+* **api:** adding support for /v1/conversations to the API ([9d088c5](https://github.com/openai/openai-java/commit/9d088c5d77c450a2e1371a8293e9c05ebf102937))
+
+
+### Chores
+
+* add missing delegate methods ([557e9ee](https://github.com/openai/openai-java/commit/557e9ee897e11c95788300922e8094383eb1dd97))
+* **ci:** reduce log noise ([9e91952](https://github.com/openai/openai-java/commit/9e9195269a225cdbaba81e2dd6ee26caba407d00))
+* **client:** refactor closing / shutdown ([94cdfcd](https://github.com/openai/openai-java/commit/94cdfcdf57225ee606acf51ffe3e0b6a4321f7e6))
+* **internal:** support running formatters directly ([6242da5](https://github.com/openai/openai-java/commit/6242da594134e736470c006bc1af6b38ce757705))
+* remove memory upper bound from publishing step ([fdc5fdd](https://github.com/openai/openai-java/commit/fdc5fdd3969d2ecc3d6df1546b34167b63074991))
+
## 3.1.2 (2025-08-20)
Full Changelog: [v3.1.1...v3.1.2](https://github.com/openai/openai-java/compare/v3.1.1...v3.1.2)
diff --git a/README.md b/README.md
index 4b10773ef..3c2ea9a32 100644
--- a/README.md
+++ b/README.md
@@ -2,8 +2,8 @@
-[](https://central.sonatype.com/artifact/com.openai/openai-java/3.1.2)
-[](https://javadoc.io/doc/com.openai/openai-java/3.1.2)
+[](https://central.sonatype.com/artifact/com.openai/openai-java/3.2.0)
+[](https://javadoc.io/doc/com.openai/openai-java/3.2.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/3.1.2).
+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/3.2.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:3.1.2")
+implementation("com.openai:openai-java:3.2.0")
```
### Maven
@@ -33,7 +33,7 @@ implementation("com.openai:openai-java:3.1.2")
com.openai
openai-java
- 3.1.2
+ 3.2.0
```
@@ -1330,7 +1330,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:3.1.2")
+implementation("com.openai:openai-java-spring-boot-starter:3.2.0")
```
#### Maven
@@ -1339,7 +1339,7 @@ implementation("com.openai:openai-java-spring-boot-starter:3.1.2")
com.openai
openai-java-spring-boot-starter
- 3.1.2
+ 3.2.0
```
diff --git a/build.gradle.kts b/build.gradle.kts
index 7108208f7..435360279 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -8,7 +8,7 @@ repositories {
allprojects {
group = "com.openai"
- version = "3.1.2" // x-release-please-version
+ version = "3.2.0" // x-release-please-version
}
subprojects {
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 61e6fcd13..353f94f1c 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
@@ -128,6 +128,8 @@ class OpenAIOkHttpClient private constructor() {
* The executor to use for running [AsyncStreamResponse.Handler] callbacks.
*
* Defaults to a dedicated cached thread pool.
+ *
+ * This class takes ownership of the executor and shuts it down, if possible, when closed.
*/
fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply {
clientOptions.streamHandlerExecutor(streamHandlerExecutor)
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 c840742ec..9707fffb3 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
@@ -128,6 +128,8 @@ class OpenAIOkHttpClientAsync private constructor() {
* The executor to use for running [AsyncStreamResponse.Handler] callbacks.
*
* Defaults to a dedicated cached thread pool.
+ *
+ * This class takes ownership of the executor and shuts it down, if possible, when closed.
*/
fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply {
clientOptions.streamHandlerExecutor(streamHandlerExecutor)
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 692262752..5b6e67724 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
@@ -9,6 +9,7 @@ import com.openai.services.blocking.BetaService
import com.openai.services.blocking.ChatService
import com.openai.services.blocking.CompletionService
import com.openai.services.blocking.ContainerService
+import com.openai.services.blocking.ConversationService
import com.openai.services.blocking.EmbeddingService
import com.openai.services.blocking.EvalService
import com.openai.services.blocking.FileService
@@ -91,6 +92,8 @@ interface OpenAIClient {
fun responses(): ResponseService
+ fun conversations(): ConversationService
+
fun evals(): EvalService
fun containers(): ContainerService
@@ -150,6 +153,8 @@ interface OpenAIClient {
fun responses(): ResponseService.WithRawResponse
+ fun conversations(): ConversationService.WithRawResponse
+
fun evals(): EvalService.WithRawResponse
fun containers(): ContainerService.WithRawResponse
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 a0369ca4a..00c1d5d59 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
@@ -9,6 +9,7 @@ import com.openai.services.async.BetaServiceAsync
import com.openai.services.async.ChatServiceAsync
import com.openai.services.async.CompletionServiceAsync
import com.openai.services.async.ContainerServiceAsync
+import com.openai.services.async.ConversationServiceAsync
import com.openai.services.async.EmbeddingServiceAsync
import com.openai.services.async.EvalServiceAsync
import com.openai.services.async.FileServiceAsync
@@ -91,6 +92,8 @@ interface OpenAIClientAsync {
fun responses(): ResponseServiceAsync
+ fun conversations(): ConversationServiceAsync
+
fun evals(): EvalServiceAsync
fun containers(): ContainerServiceAsync
@@ -152,6 +155,8 @@ interface OpenAIClientAsync {
fun responses(): ResponseServiceAsync.WithRawResponse
+ fun conversations(): ConversationServiceAsync.WithRawResponse
+
fun evals(): EvalServiceAsync.WithRawResponse
fun containers(): ContainerServiceAsync.WithRawResponse
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 73edf7d11..8dca941d0 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
@@ -16,6 +16,8 @@ import com.openai.services.async.CompletionServiceAsync
import com.openai.services.async.CompletionServiceAsyncImpl
import com.openai.services.async.ContainerServiceAsync
import com.openai.services.async.ContainerServiceAsyncImpl
+import com.openai.services.async.ConversationServiceAsync
+import com.openai.services.async.ConversationServiceAsyncImpl
import com.openai.services.async.EmbeddingServiceAsync
import com.openai.services.async.EmbeddingServiceAsyncImpl
import com.openai.services.async.EvalServiceAsync
@@ -117,6 +119,10 @@ class OpenAIClientAsyncImpl(private val clientOptions: ClientOptions) : OpenAICl
ResponseServiceAsyncImpl(clientOptionsWithUserAgent)
}
+ private val conversations: ConversationServiceAsync by lazy {
+ ConversationServiceAsyncImpl(clientOptionsWithUserAgent)
+ }
+
private val evals: EvalServiceAsync by lazy { EvalServiceAsyncImpl(clientOptionsWithUserAgent) }
private val containers: ContainerServiceAsync by lazy {
@@ -162,11 +168,13 @@ class OpenAIClientAsyncImpl(private val clientOptions: ClientOptions) : OpenAICl
override fun responses(): ResponseServiceAsync = responses
+ override fun conversations(): ConversationServiceAsync = conversations
+
override fun evals(): EvalServiceAsync = evals
override fun containers(): ContainerServiceAsync = containers
- override fun close() = clientOptions.httpClient.close()
+ override fun close() = clientOptions.close()
class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) :
OpenAIClientAsync.WithRawResponse {
@@ -235,6 +243,10 @@ class OpenAIClientAsyncImpl(private val clientOptions: ClientOptions) : OpenAICl
ResponseServiceAsyncImpl.WithRawResponseImpl(clientOptions)
}
+ private val conversations: ConversationServiceAsync.WithRawResponse by lazy {
+ ConversationServiceAsyncImpl.WithRawResponseImpl(clientOptions)
+ }
+
private val evals: EvalServiceAsync.WithRawResponse by lazy {
EvalServiceAsyncImpl.WithRawResponseImpl(clientOptions)
}
@@ -282,6 +294,8 @@ class OpenAIClientAsyncImpl(private val clientOptions: ClientOptions) : OpenAICl
override fun responses(): ResponseServiceAsync.WithRawResponse = responses
+ override fun conversations(): ConversationServiceAsync.WithRawResponse = conversations
+
override fun evals(): EvalServiceAsync.WithRawResponse = evals
override fun containers(): ContainerServiceAsync.WithRawResponse = containers
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 c54e85de5..c7d4d9420 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
@@ -16,6 +16,8 @@ import com.openai.services.blocking.CompletionService
import com.openai.services.blocking.CompletionServiceImpl
import com.openai.services.blocking.ContainerService
import com.openai.services.blocking.ContainerServiceImpl
+import com.openai.services.blocking.ConversationService
+import com.openai.services.blocking.ConversationServiceImpl
import com.openai.services.blocking.EmbeddingService
import com.openai.services.blocking.EmbeddingServiceImpl
import com.openai.services.blocking.EvalService
@@ -103,6 +105,10 @@ class OpenAIClientImpl(private val clientOptions: ClientOptions) : OpenAIClient
ResponseServiceImpl(clientOptionsWithUserAgent)
}
+ private val conversations: ConversationService by lazy {
+ ConversationServiceImpl(clientOptionsWithUserAgent)
+ }
+
private val evals: EvalService by lazy { EvalServiceImpl(clientOptionsWithUserAgent) }
private val containers: ContainerService by lazy {
@@ -148,11 +154,13 @@ class OpenAIClientImpl(private val clientOptions: ClientOptions) : OpenAIClient
override fun responses(): ResponseService = responses
+ override fun conversations(): ConversationService = conversations
+
override fun evals(): EvalService = evals
override fun containers(): ContainerService = containers
- override fun close() = clientOptions.httpClient.close()
+ override fun close() = clientOptions.close()
class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) :
OpenAIClient.WithRawResponse {
@@ -221,6 +229,10 @@ class OpenAIClientImpl(private val clientOptions: ClientOptions) : OpenAIClient
ResponseServiceImpl.WithRawResponseImpl(clientOptions)
}
+ private val conversations: ConversationService.WithRawResponse by lazy {
+ ConversationServiceImpl.WithRawResponseImpl(clientOptions)
+ }
+
private val evals: EvalService.WithRawResponse by lazy {
EvalServiceImpl.WithRawResponseImpl(clientOptions)
}
@@ -268,6 +280,8 @@ class OpenAIClientImpl(private val clientOptions: ClientOptions) : OpenAIClient
override fun responses(): ResponseService.WithRawResponse = responses
+ override fun conversations(): ConversationService.WithRawResponse = conversations
+
override fun evals(): EvalService.WithRawResponse = evals
override fun containers(): ContainerService.WithRawResponse = containers
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 e7e4f4221..515eb4f49 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
@@ -19,6 +19,7 @@ import java.time.Clock
import java.time.Duration
import java.util.Optional
import java.util.concurrent.Executor
+import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import java.util.concurrent.ThreadFactory
import java.util.concurrent.atomic.AtomicLong
@@ -32,6 +33,8 @@ private constructor(
* The HTTP client to use in the SDK.
*
* Use the one published in `openai-java-client-okhttp` or implement your own.
+ *
+ * This class takes ownership of the client and closes it when closed.
*/
@get:JvmName("httpClient") val httpClient: HttpClient,
/**
@@ -53,6 +56,8 @@ private constructor(
* The executor to use for running [AsyncStreamResponse.Handler] callbacks.
*
* Defaults to a dedicated cached thread pool.
+ *
+ * This class takes ownership of the executor and shuts it down, if possible, when closed.
*/
@get:JvmName("streamHandlerExecutor") val streamHandlerExecutor: Executor,
/**
@@ -196,6 +201,8 @@ private constructor(
* The HTTP client to use in the SDK.
*
* Use the one published in `openai-java-client-okhttp` or implement your own.
+ *
+ * This class takes ownership of the client and closes it when closed.
*/
fun httpClient(httpClient: HttpClient) = apply {
this.httpClient = PhantomReachableClosingHttpClient(httpClient)
@@ -224,9 +231,14 @@ private constructor(
* The executor to use for running [AsyncStreamResponse.Handler] callbacks.
*
* Defaults to a dedicated cached thread pool.
+ *
+ * This class takes ownership of the executor and shuts it down, if possible, when closed.
*/
fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply {
- this.streamHandlerExecutor = streamHandlerExecutor
+ this.streamHandlerExecutor =
+ if (streamHandlerExecutor is ExecutorService)
+ PhantomReachableExecutorService(streamHandlerExecutor)
+ else streamHandlerExecutor
}
/**
@@ -554,4 +566,19 @@ private constructor(
)
}
}
+
+ /**
+ * Closes these client options, relinquishing any underlying resources.
+ *
+ * This is purposefully not inherited from [AutoCloseable] because the client options are
+ * long-lived and usually should not be synchronously closed via try-with-resources.
+ *
+ * It's also usually not necessary to call this method at all. the default client automatically
+ * releases threads and connections if they remain idle, but if you are writing an application
+ * that needs to aggressively release unused resources, then you may call this method.
+ */
+ fun close() {
+ httpClient.close()
+ (streamHandlerExecutor as? ExecutorService)?.shutdown()
+ }
}
diff --git a/openai-java-core/src/main/kotlin/com/openai/core/PhantomReachableExecutorService.kt b/openai-java-core/src/main/kotlin/com/openai/core/PhantomReachableExecutorService.kt
new file mode 100644
index 000000000..250071c78
--- /dev/null
+++ b/openai-java-core/src/main/kotlin/com/openai/core/PhantomReachableExecutorService.kt
@@ -0,0 +1,58 @@
+package com.openai.core
+
+import java.util.concurrent.Callable
+import java.util.concurrent.ExecutorService
+import java.util.concurrent.Future
+import java.util.concurrent.TimeUnit
+
+/**
+ * A delegating wrapper around an [ExecutorService] that shuts it down once it's only phantom
+ * reachable.
+ *
+ * This class ensures the [ExecutorService] is shut down even if the user forgets to do it.
+ */
+internal class PhantomReachableExecutorService(private val executorService: ExecutorService) :
+ ExecutorService {
+ init {
+ closeWhenPhantomReachable(this) { executorService.shutdown() }
+ }
+
+ override fun execute(command: Runnable) = executorService.execute(command)
+
+ override fun shutdown() = executorService.shutdown()
+
+ override fun shutdownNow(): MutableList = executorService.shutdownNow()
+
+ override fun isShutdown(): Boolean = executorService.isShutdown
+
+ override fun isTerminated(): Boolean = executorService.isTerminated
+
+ override fun awaitTermination(timeout: Long, unit: TimeUnit): Boolean =
+ executorService.awaitTermination(timeout, unit)
+
+ override fun submit(task: Callable): Future = executorService.submit(task)
+
+ override fun submit(task: Runnable, result: T): Future =
+ executorService.submit(task, result)
+
+ override fun submit(task: Runnable): Future<*> = executorService.submit(task)
+
+ override fun invokeAll(
+ tasks: MutableCollection>
+ ): MutableList> = executorService.invokeAll(tasks)
+
+ override fun invokeAll(
+ tasks: MutableCollection>,
+ timeout: Long,
+ unit: TimeUnit,
+ ): MutableList> = executorService.invokeAll(tasks, timeout, unit)
+
+ override fun invokeAny(tasks: MutableCollection>): T =
+ executorService.invokeAny(tasks)
+
+ override fun invokeAny(
+ tasks: MutableCollection>,
+ timeout: Long,
+ unit: TimeUnit,
+ ): T = executorService.invokeAny(tasks, timeout, unit)
+}
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/conversations/ComputerScreenshotContent.kt b/openai-java-core/src/main/kotlin/com/openai/models/conversations/ComputerScreenshotContent.kt
new file mode 100644
index 000000000..39efe0bb0
--- /dev/null
+++ b/openai-java-core/src/main/kotlin/com/openai/models/conversations/ComputerScreenshotContent.kt
@@ -0,0 +1,258 @@
+// File generated from our OpenAPI spec by Stainless.
+
+package com.openai.models.conversations
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter
+import com.fasterxml.jackson.annotation.JsonAnySetter
+import com.fasterxml.jackson.annotation.JsonCreator
+import com.fasterxml.jackson.annotation.JsonProperty
+import com.openai.core.ExcludeMissing
+import com.openai.core.JsonField
+import com.openai.core.JsonMissing
+import com.openai.core.JsonValue
+import com.openai.core.checkRequired
+import com.openai.errors.OpenAIInvalidDataException
+import java.util.Collections
+import java.util.Objects
+import java.util.Optional
+import kotlin.jvm.optionals.getOrNull
+
+class ComputerScreenshotContent
+private constructor(
+ private val fileId: JsonField,
+ private val imageUrl: JsonField,
+ private val type: JsonValue,
+ private val additionalProperties: MutableMap,
+) {
+
+ @JsonCreator
+ private constructor(
+ @JsonProperty("file_id") @ExcludeMissing fileId: JsonField = JsonMissing.of(),
+ @JsonProperty("image_url") @ExcludeMissing imageUrl: JsonField = JsonMissing.of(),
+ @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(),
+ ) : this(fileId, imageUrl, type, mutableMapOf())
+
+ /**
+ * The identifier of an uploaded file that contains the screenshot.
+ *
+ * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the
+ * server responded with an unexpected value).
+ */
+ fun fileId(): Optional = fileId.getOptional("file_id")
+
+ /**
+ * The URL of the screenshot image.
+ *
+ * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the
+ * server responded with an unexpected value).
+ */
+ fun imageUrl(): Optional = imageUrl.getOptional("image_url")
+
+ /**
+ * Specifies the event type. For a computer screenshot, this property is always set to
+ * `computer_screenshot`.
+ *
+ * Expected to always return the following:
+ * ```java
+ * JsonValue.from("computer_screenshot")
+ * ```
+ *
+ * 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 [fileId].
+ *
+ * Unlike [fileId], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("file_id") @ExcludeMissing fun _fileId(): JsonField = fileId
+
+ /**
+ * 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
+
+ @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 [ComputerScreenshotContent].
+ *
+ * The following fields are required:
+ * ```java
+ * .fileId()
+ * .imageUrl()
+ * ```
+ */
+ @JvmStatic fun builder() = Builder()
+ }
+
+ /** A builder for [ComputerScreenshotContent]. */
+ class Builder internal constructor() {
+
+ private var fileId: JsonField? = null
+ private var imageUrl: JsonField? = null
+ private var type: JsonValue = JsonValue.from("computer_screenshot")
+ private var additionalProperties: MutableMap = mutableMapOf()
+
+ @JvmSynthetic
+ internal fun from(computerScreenshotContent: ComputerScreenshotContent) = apply {
+ fileId = computerScreenshotContent.fileId
+ imageUrl = computerScreenshotContent.imageUrl
+ type = computerScreenshotContent.type
+ additionalProperties = computerScreenshotContent.additionalProperties.toMutableMap()
+ }
+
+ /** The identifier of an uploaded file that contains the screenshot. */
+ fun fileId(fileId: String?) = fileId(JsonField.ofNullable(fileId))
+
+ /** Alias for calling [Builder.fileId] with `fileId.orElse(null)`. */
+ fun fileId(fileId: Optional) = fileId(fileId.getOrNull())
+
+ /**
+ * Sets [Builder.fileId] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.fileId] with a well-typed [String] value instead. This
+ * method is primarily for setting the field to an undocumented or not yet supported value.
+ */
+ fun fileId(fileId: JsonField) = apply { this.fileId = fileId }
+
+ /** The URL of the screenshot image. */
+ fun imageUrl(imageUrl: String?) = imageUrl(JsonField.ofNullable(imageUrl))
+
+ /** Alias for calling [Builder.imageUrl] with `imageUrl.orElse(null)`. */
+ fun imageUrl(imageUrl: Optional) = imageUrl(imageUrl.getOrNull())
+
+ /**
+ * 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("computer_screenshot")
+ * ```
+ *
+ * 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 [ComputerScreenshotContent].
+ *
+ * Further updates to this [Builder] will not mutate the returned instance.
+ *
+ * The following fields are required:
+ * ```java
+ * .fileId()
+ * .imageUrl()
+ * ```
+ *
+ * @throws IllegalStateException if any required field is unset.
+ */
+ fun build(): ComputerScreenshotContent =
+ ComputerScreenshotContent(
+ checkRequired("fileId", fileId),
+ checkRequired("imageUrl", imageUrl),
+ type,
+ additionalProperties.toMutableMap(),
+ )
+ }
+
+ private var validated: Boolean = false
+
+ fun validate(): ComputerScreenshotContent = apply {
+ if (validated) {
+ return@apply
+ }
+
+ fileId()
+ imageUrl()
+ _type().let {
+ if (it != JsonValue.from("computer_screenshot")) {
+ 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 (fileId.asKnown().isPresent) 1 else 0) +
+ (if (imageUrl.asKnown().isPresent) 1 else 0) +
+ type.let { if (it == JsonValue.from("computer_screenshot")) 1 else 0 }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) {
+ return true
+ }
+
+ return other is ComputerScreenshotContent &&
+ fileId == other.fileId &&
+ imageUrl == other.imageUrl &&
+ type == other.type &&
+ additionalProperties == other.additionalProperties
+ }
+
+ private val hashCode: Int by lazy { Objects.hash(fileId, imageUrl, type, additionalProperties) }
+
+ override fun hashCode(): Int = hashCode
+
+ override fun toString() =
+ "ComputerScreenshotContent{fileId=$fileId, imageUrl=$imageUrl, type=$type, additionalProperties=$additionalProperties}"
+}
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/conversations/ContainerFileCitationBody.kt b/openai-java-core/src/main/kotlin/com/openai/models/conversations/ContainerFileCitationBody.kt
new file mode 100644
index 000000000..67c0ff2d5
--- /dev/null
+++ b/openai-java-core/src/main/kotlin/com/openai/models/conversations/ContainerFileCitationBody.kt
@@ -0,0 +1,372 @@
+// File generated from our OpenAPI spec by Stainless.
+
+package com.openai.models.conversations
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter
+import com.fasterxml.jackson.annotation.JsonAnySetter
+import com.fasterxml.jackson.annotation.JsonCreator
+import com.fasterxml.jackson.annotation.JsonProperty
+import com.openai.core.ExcludeMissing
+import com.openai.core.JsonField
+import com.openai.core.JsonMissing
+import com.openai.core.JsonValue
+import com.openai.core.checkRequired
+import com.openai.errors.OpenAIInvalidDataException
+import java.util.Collections
+import java.util.Objects
+
+class ContainerFileCitationBody
+private constructor(
+ private val containerId: JsonField,
+ private val endIndex: JsonField,
+ private val fileId: JsonField,
+ private val filename: JsonField,
+ private val startIndex: JsonField,
+ private val type: JsonValue,
+ private val additionalProperties: MutableMap,
+) {
+
+ @JsonCreator
+ private constructor(
+ @JsonProperty("container_id")
+ @ExcludeMissing
+ containerId: JsonField = JsonMissing.of(),
+ @JsonProperty("end_index") @ExcludeMissing endIndex: JsonField = JsonMissing.of(),
+ @JsonProperty("file_id") @ExcludeMissing fileId: JsonField = JsonMissing.of(),
+ @JsonProperty("filename") @ExcludeMissing filename: JsonField = JsonMissing.of(),
+ @JsonProperty("start_index") @ExcludeMissing startIndex: JsonField = JsonMissing.of(),
+ @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(),
+ ) : this(containerId, endIndex, fileId, filename, startIndex, type, mutableMapOf())
+
+ /**
+ * The ID of the container file.
+ *
+ * @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 containerId(): String = containerId.getRequired("container_id")
+
+ /**
+ * The index of the last character of the container file citation in the message.
+ *
+ * @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 endIndex(): Long = endIndex.getRequired("end_index")
+
+ /**
+ * The ID of the file.
+ *
+ * @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 fileId(): String = fileId.getRequired("file_id")
+
+ /**
+ * The filename of the container file cited.
+ *
+ * @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 filename(): String = filename.getRequired("filename")
+
+ /**
+ * The index of the first character of the container file citation in the message.
+ *
+ * @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 startIndex(): Long = startIndex.getRequired("start_index")
+
+ /**
+ * The type of the container file citation. Always `container_file_citation`.
+ *
+ * Expected to always return the following:
+ * ```java
+ * JsonValue.from("container_file_citation")
+ * ```
+ *
+ * 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 [containerId].
+ *
+ * Unlike [containerId], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("container_id")
+ @ExcludeMissing
+ fun _containerId(): JsonField = containerId
+
+ /**
+ * Returns the raw JSON value of [endIndex].
+ *
+ * Unlike [endIndex], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("end_index") @ExcludeMissing fun _endIndex(): JsonField = endIndex
+
+ /**
+ * Returns the raw JSON value of [fileId].
+ *
+ * Unlike [fileId], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("file_id") @ExcludeMissing fun _fileId(): JsonField = fileId
+
+ /**
+ * Returns the raw JSON value of [filename].
+ *
+ * Unlike [filename], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("filename") @ExcludeMissing fun _filename(): JsonField = filename
+
+ /**
+ * Returns the raw JSON value of [startIndex].
+ *
+ * Unlike [startIndex], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("start_index") @ExcludeMissing fun _startIndex(): JsonField = startIndex
+
+ @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 [ContainerFileCitationBody].
+ *
+ * The following fields are required:
+ * ```java
+ * .containerId()
+ * .endIndex()
+ * .fileId()
+ * .filename()
+ * .startIndex()
+ * ```
+ */
+ @JvmStatic fun builder() = Builder()
+ }
+
+ /** A builder for [ContainerFileCitationBody]. */
+ class Builder internal constructor() {
+
+ private var containerId: JsonField? = null
+ private var endIndex: JsonField? = null
+ private var fileId: JsonField? = null
+ private var filename: JsonField? = null
+ private var startIndex: JsonField? = null
+ private var type: JsonValue = JsonValue.from("container_file_citation")
+ private var additionalProperties: MutableMap = mutableMapOf()
+
+ @JvmSynthetic
+ internal fun from(containerFileCitationBody: ContainerFileCitationBody) = apply {
+ containerId = containerFileCitationBody.containerId
+ endIndex = containerFileCitationBody.endIndex
+ fileId = containerFileCitationBody.fileId
+ filename = containerFileCitationBody.filename
+ startIndex = containerFileCitationBody.startIndex
+ type = containerFileCitationBody.type
+ additionalProperties = containerFileCitationBody.additionalProperties.toMutableMap()
+ }
+
+ /** The ID of the container file. */
+ fun containerId(containerId: String) = containerId(JsonField.of(containerId))
+
+ /**
+ * Sets [Builder.containerId] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.containerId] with a well-typed [String] value instead.
+ * This method is primarily for setting the field to an undocumented or not yet supported
+ * value.
+ */
+ fun containerId(containerId: JsonField) = apply { this.containerId = containerId }
+
+ /** The index of the last character of the container file citation in the message. */
+ fun endIndex(endIndex: Long) = endIndex(JsonField.of(endIndex))
+
+ /**
+ * Sets [Builder.endIndex] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.endIndex] with a well-typed [Long] value instead. This
+ * method is primarily for setting the field to an undocumented or not yet supported value.
+ */
+ fun endIndex(endIndex: JsonField) = apply { this.endIndex = endIndex }
+
+ /** The ID of the file. */
+ fun fileId(fileId: String) = fileId(JsonField.of(fileId))
+
+ /**
+ * Sets [Builder.fileId] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.fileId] with a well-typed [String] value instead. This
+ * method is primarily for setting the field to an undocumented or not yet supported value.
+ */
+ fun fileId(fileId: JsonField) = apply { this.fileId = fileId }
+
+ /** The filename of the container file cited. */
+ fun filename(filename: String) = filename(JsonField.of(filename))
+
+ /**
+ * Sets [Builder.filename] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.filename] with a well-typed [String] value instead. This
+ * method is primarily for setting the field to an undocumented or not yet supported value.
+ */
+ fun filename(filename: JsonField) = apply { this.filename = filename }
+
+ /** The index of the first character of the container file citation in the message. */
+ fun startIndex(startIndex: Long) = startIndex(JsonField.of(startIndex))
+
+ /**
+ * Sets [Builder.startIndex] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.startIndex] with a well-typed [Long] value instead. This
+ * method is primarily for setting the field to an undocumented or not yet supported value.
+ */
+ fun startIndex(startIndex: JsonField) = apply { this.startIndex = startIndex }
+
+ /**
+ * 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("container_file_citation")
+ * ```
+ *
+ * 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 [ContainerFileCitationBody].
+ *
+ * Further updates to this [Builder] will not mutate the returned instance.
+ *
+ * The following fields are required:
+ * ```java
+ * .containerId()
+ * .endIndex()
+ * .fileId()
+ * .filename()
+ * .startIndex()
+ * ```
+ *
+ * @throws IllegalStateException if any required field is unset.
+ */
+ fun build(): ContainerFileCitationBody =
+ ContainerFileCitationBody(
+ checkRequired("containerId", containerId),
+ checkRequired("endIndex", endIndex),
+ checkRequired("fileId", fileId),
+ checkRequired("filename", filename),
+ checkRequired("startIndex", startIndex),
+ type,
+ additionalProperties.toMutableMap(),
+ )
+ }
+
+ private var validated: Boolean = false
+
+ fun validate(): ContainerFileCitationBody = apply {
+ if (validated) {
+ return@apply
+ }
+
+ containerId()
+ endIndex()
+ fileId()
+ filename()
+ startIndex()
+ _type().let {
+ if (it != JsonValue.from("container_file_citation")) {
+ 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 (containerId.asKnown().isPresent) 1 else 0) +
+ (if (endIndex.asKnown().isPresent) 1 else 0) +
+ (if (fileId.asKnown().isPresent) 1 else 0) +
+ (if (filename.asKnown().isPresent) 1 else 0) +
+ (if (startIndex.asKnown().isPresent) 1 else 0) +
+ type.let { if (it == JsonValue.from("container_file_citation")) 1 else 0 }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) {
+ return true
+ }
+
+ return other is ContainerFileCitationBody &&
+ containerId == other.containerId &&
+ endIndex == other.endIndex &&
+ fileId == other.fileId &&
+ filename == other.filename &&
+ startIndex == other.startIndex &&
+ type == other.type &&
+ additionalProperties == other.additionalProperties
+ }
+
+ private val hashCode: Int by lazy {
+ Objects.hash(
+ containerId,
+ endIndex,
+ fileId,
+ filename,
+ startIndex,
+ type,
+ additionalProperties,
+ )
+ }
+
+ override fun hashCode(): Int = hashCode
+
+ override fun toString() =
+ "ContainerFileCitationBody{containerId=$containerId, endIndex=$endIndex, fileId=$fileId, filename=$filename, startIndex=$startIndex, type=$type, additionalProperties=$additionalProperties}"
+}
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/conversations/Conversation.kt b/openai-java-core/src/main/kotlin/com/openai/models/conversations/Conversation.kt
new file mode 100644
index 000000000..56a086785
--- /dev/null
+++ b/openai-java-core/src/main/kotlin/com/openai/models/conversations/Conversation.kt
@@ -0,0 +1,277 @@
+// File generated from our OpenAPI spec by Stainless.
+
+package com.openai.models.conversations
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter
+import com.fasterxml.jackson.annotation.JsonAnySetter
+import com.fasterxml.jackson.annotation.JsonCreator
+import com.fasterxml.jackson.annotation.JsonProperty
+import com.openai.core.ExcludeMissing
+import com.openai.core.JsonField
+import com.openai.core.JsonMissing
+import com.openai.core.JsonValue
+import com.openai.core.checkRequired
+import com.openai.errors.OpenAIInvalidDataException
+import java.util.Collections
+import java.util.Objects
+
+class Conversation
+private constructor(
+ private val id: JsonField,
+ private val createdAt: JsonField,
+ private val metadata: JsonValue,
+ private val object_: JsonValue,
+ private val additionalProperties: MutableMap,
+) {
+
+ @JsonCreator
+ private constructor(
+ @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(),
+ @JsonProperty("created_at") @ExcludeMissing createdAt: JsonField = JsonMissing.of(),
+ @JsonProperty("metadata") @ExcludeMissing metadata: JsonValue = JsonMissing.of(),
+ @JsonProperty("object") @ExcludeMissing object_: JsonValue = JsonMissing.of(),
+ ) : this(id, createdAt, metadata, object_, mutableMapOf())
+
+ /**
+ * The unique ID of the conversation.
+ *
+ * @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 id(): String = id.getRequired("id")
+
+ /**
+ * The time at which the conversation was created, measured in seconds since the Unix epoch.
+ *
+ * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is
+ * unexpectedly missing or null (e.g. if the server responded with an unexpected value).
+ */
+ fun createdAt(): Long = createdAt.getRequired("created_at")
+
+ /**
+ * Set of 16 key-value pairs that can be attached to an object. This can be useful for storing
+ * additional information about the object in a structured format, and querying for objects via
+ * API or the dashboard. Keys are strings with a maximum length of 64 characters. Values are
+ * strings with a maximum length of 512 characters.
+ */
+ @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonValue = metadata
+
+ /**
+ * The object type, which is always `conversation`.
+ *
+ * Expected to always return the following:
+ * ```java
+ * JsonValue.from("conversation")
+ * ```
+ *
+ * However, this method can be useful for debugging and logging (e.g. if the server responded
+ * with an unexpected value).
+ */
+ @JsonProperty("object") @ExcludeMissing fun _object_(): JsonValue = object_
+
+ /**
+ * Returns the raw JSON value of [id].
+ *
+ * Unlike [id], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id
+
+ /**
+ * Returns the raw JSON value of [createdAt].
+ *
+ * Unlike [createdAt], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("created_at") @ExcludeMissing fun _createdAt(): JsonField = createdAt
+
+ @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 [Conversation].
+ *
+ * The following fields are required:
+ * ```java
+ * .id()
+ * .createdAt()
+ * .metadata()
+ * ```
+ */
+ @JvmStatic fun builder() = Builder()
+ }
+
+ /** A builder for [Conversation]. */
+ class Builder internal constructor() {
+
+ private var id: JsonField? = null
+ private var createdAt: JsonField? = null
+ private var metadata: JsonValue? = null
+ private var object_: JsonValue = JsonValue.from("conversation")
+ private var additionalProperties: MutableMap = mutableMapOf()
+
+ @JvmSynthetic
+ internal fun from(conversation: Conversation) = apply {
+ id = conversation.id
+ createdAt = conversation.createdAt
+ metadata = conversation.metadata
+ object_ = conversation.object_
+ additionalProperties = conversation.additionalProperties.toMutableMap()
+ }
+
+ /** The unique ID of the conversation. */
+ fun id(id: String) = id(JsonField.of(id))
+
+ /**
+ * Sets [Builder.id] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.id] with a well-typed [String] value instead. This
+ * method is primarily for setting the field to an undocumented or not yet supported value.
+ */
+ fun id(id: JsonField) = apply { this.id = id }
+
+ /**
+ * The time at which the conversation was created, measured in seconds since the Unix epoch.
+ */
+ fun createdAt(createdAt: Long) = createdAt(JsonField.of(createdAt))
+
+ /**
+ * Sets [Builder.createdAt] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.createdAt] with a well-typed [Long] value instead. This
+ * method is primarily for setting the field to an undocumented or not yet supported value.
+ */
+ fun createdAt(createdAt: JsonField) = apply { this.createdAt = createdAt }
+
+ /**
+ * Set of 16 key-value pairs that can be attached to an object. This can be useful for
+ * storing additional information about the object in a structured format, and querying for
+ * objects via API or the dashboard. Keys are strings with a maximum length of 64
+ * characters. Values are strings with a maximum length of 512 characters.
+ */
+ fun metadata(metadata: JsonValue) = apply { this.metadata = metadata }
+
+ /**
+ * 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("conversation")
+ * ```
+ *
+ * This method is primarily for setting the field to an undocumented or not yet supported
+ * value.
+ */
+ fun object_(object_: JsonValue) = apply { this.object_ = object_ }
+
+ 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 [Conversation].
+ *
+ * Further updates to this [Builder] will not mutate the returned instance.
+ *
+ * The following fields are required:
+ * ```java
+ * .id()
+ * .createdAt()
+ * .metadata()
+ * ```
+ *
+ * @throws IllegalStateException if any required field is unset.
+ */
+ fun build(): Conversation =
+ Conversation(
+ checkRequired("id", id),
+ checkRequired("createdAt", createdAt),
+ checkRequired("metadata", metadata),
+ object_,
+ additionalProperties.toMutableMap(),
+ )
+ }
+
+ private var validated: Boolean = false
+
+ fun validate(): Conversation = apply {
+ if (validated) {
+ return@apply
+ }
+
+ id()
+ createdAt()
+ _object_().let {
+ if (it != JsonValue.from("conversation")) {
+ throw OpenAIInvalidDataException("'object_' 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 (id.asKnown().isPresent) 1 else 0) +
+ (if (createdAt.asKnown().isPresent) 1 else 0) +
+ object_.let { if (it == JsonValue.from("conversation")) 1 else 0 }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) {
+ return true
+ }
+
+ return other is Conversation &&
+ id == other.id &&
+ createdAt == other.createdAt &&
+ metadata == other.metadata &&
+ object_ == other.object_ &&
+ additionalProperties == other.additionalProperties
+ }
+
+ private val hashCode: Int by lazy {
+ Objects.hash(id, createdAt, metadata, object_, additionalProperties)
+ }
+
+ override fun hashCode(): Int = hashCode
+
+ override fun toString() =
+ "Conversation{id=$id, createdAt=$createdAt, metadata=$metadata, object_=$object_, additionalProperties=$additionalProperties}"
+}
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/conversations/ConversationCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/conversations/ConversationCreateParams.kt
new file mode 100644
index 000000000..bb85e5860
--- /dev/null
+++ b/openai-java-core/src/main/kotlin/com/openai/models/conversations/ConversationCreateParams.kt
@@ -0,0 +1,921 @@
+// File generated from our OpenAPI spec by Stainless.
+
+package com.openai.models.conversations
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter
+import com.fasterxml.jackson.annotation.JsonAnySetter
+import com.fasterxml.jackson.annotation.JsonCreator
+import com.fasterxml.jackson.annotation.JsonProperty
+import com.openai.core.ExcludeMissing
+import com.openai.core.JsonField
+import com.openai.core.JsonMissing
+import com.openai.core.JsonValue
+import com.openai.core.Params
+import com.openai.core.checkKnown
+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.responses.EasyInputMessage
+import com.openai.models.responses.ResponseCodeInterpreterToolCall
+import com.openai.models.responses.ResponseComputerToolCall
+import com.openai.models.responses.ResponseCustomToolCall
+import com.openai.models.responses.ResponseCustomToolCallOutput
+import com.openai.models.responses.ResponseFileSearchToolCall
+import com.openai.models.responses.ResponseFunctionToolCall
+import com.openai.models.responses.ResponseFunctionWebSearch
+import com.openai.models.responses.ResponseInputItem
+import com.openai.models.responses.ResponseOutputMessage
+import com.openai.models.responses.ResponseReasoningItem
+import java.util.Collections
+import java.util.Objects
+import java.util.Optional
+import kotlin.jvm.optionals.getOrNull
+
+/** Create a conversation with the given ID. */
+class ConversationCreateParams
+private constructor(
+ private val body: Body,
+ private val additionalHeaders: Headers,
+ private val additionalQueryParams: QueryParams,
+) : Params {
+
+ /**
+ * Initial items to include in the conversation context. You may add up to 20 items at a time.
+ *
+ * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the
+ * server responded with an unexpected value).
+ */
+ fun items(): Optional> = body.items()
+
+ /**
+ * Set of 16 key-value pairs that can be attached to an object. Useful for storing additional
+ * information about the object in a structured format.
+ *
+ * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the
+ * server responded with an unexpected value).
+ */
+ fun metadata(): Optional = body.metadata()
+
+ /**
+ * Returns the raw JSON value of [items].
+ *
+ * Unlike [items], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ fun _items(): JsonField> = body._items()
+
+ /**
+ * Returns the raw JSON value of [metadata].
+ *
+ * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ fun _metadata(): JsonField = body._metadata()
+
+ fun _additionalBodyProperties(): Map = body._additionalProperties()
+
+ /** Additional headers to send with the request. */
+ fun _additionalHeaders(): Headers = additionalHeaders
+
+ /** Additional query param to send with the request. */
+ fun _additionalQueryParams(): QueryParams = additionalQueryParams
+
+ fun toBuilder() = Builder().from(this)
+
+ companion object {
+
+ @JvmStatic fun none(): ConversationCreateParams = builder().build()
+
+ /** Returns a mutable builder for constructing an instance of [ConversationCreateParams]. */
+ @JvmStatic fun builder() = Builder()
+ }
+
+ /** A builder for [ConversationCreateParams]. */
+ class Builder internal constructor() {
+
+ private var body: Body.Builder = Body.builder()
+ private var additionalHeaders: Headers.Builder = Headers.builder()
+ private var additionalQueryParams: QueryParams.Builder = QueryParams.builder()
+
+ @JvmSynthetic
+ internal fun from(conversationCreateParams: ConversationCreateParams) = apply {
+ body = conversationCreateParams.body.toBuilder()
+ additionalHeaders = conversationCreateParams.additionalHeaders.toBuilder()
+ additionalQueryParams = conversationCreateParams.additionalQueryParams.toBuilder()
+ }
+
+ /**
+ * Sets the entire request body.
+ *
+ * This is generally only useful if you are already constructing the body separately.
+ * Otherwise, it's more convenient to use the top-level setters instead:
+ * - [items]
+ * - [metadata]
+ */
+ fun body(body: Body) = apply { this.body = body.toBuilder() }
+
+ /**
+ * Initial items to include in the conversation context. You may add up to 20 items at a
+ * time.
+ */
+ fun items(items: List?) = apply { body.items(items) }
+
+ /** Alias for calling [Builder.items] with `items.orElse(null)`. */
+ fun items(items: Optional>) = items(items.getOrNull())
+
+ /**
+ * Sets [Builder.items] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.items] with a well-typed `List` value
+ * instead. This method is primarily for setting the field to an undocumented or not yet
+ * supported value.
+ */
+ fun items(items: JsonField>) = apply { body.items(items) }
+
+ /**
+ * Adds a single [ResponseInputItem] to [items].
+ *
+ * @throws IllegalStateException if the field was previously set to a non-list.
+ */
+ fun addItem(item: ResponseInputItem) = apply { body.addItem(item) }
+
+ /**
+ * Alias for calling [addItem] with
+ * `ResponseInputItem.ofEasyInputMessage(easyInputMessage)`.
+ */
+ fun addItem(easyInputMessage: EasyInputMessage) = apply { body.addItem(easyInputMessage) }
+
+ /** Alias for calling [addItem] with `ResponseInputItem.ofMessage(message)`. */
+ fun addItem(message: ResponseInputItem.Message) = apply { body.addItem(message) }
+
+ /**
+ * Alias for calling [addItem] with
+ * `ResponseInputItem.ofResponseOutputMessage(responseOutputMessage)`.
+ */
+ fun addItem(responseOutputMessage: ResponseOutputMessage) = apply {
+ body.addItem(responseOutputMessage)
+ }
+
+ /**
+ * Alias for calling [addItem] with `ResponseInputItem.ofFileSearchCall(fileSearchCall)`.
+ */
+ fun addItem(fileSearchCall: ResponseFileSearchToolCall) = apply {
+ body.addItem(fileSearchCall)
+ }
+
+ /** Alias for calling [addItem] with `ResponseInputItem.ofComputerCall(computerCall)`. */
+ fun addItem(computerCall: ResponseComputerToolCall) = apply { body.addItem(computerCall) }
+
+ /**
+ * Alias for calling [addItem] with
+ * `ResponseInputItem.ofComputerCallOutput(computerCallOutput)`.
+ */
+ fun addItem(computerCallOutput: ResponseInputItem.ComputerCallOutput) = apply {
+ body.addItem(computerCallOutput)
+ }
+
+ /** Alias for calling [addItem] with `ResponseInputItem.ofWebSearchCall(webSearchCall)`. */
+ fun addItem(webSearchCall: ResponseFunctionWebSearch) = apply {
+ body.addItem(webSearchCall)
+ }
+
+ /** Alias for calling [addItem] with `ResponseInputItem.ofFunctionCall(functionCall)`. */
+ fun addItem(functionCall: ResponseFunctionToolCall) = apply { body.addItem(functionCall) }
+
+ /**
+ * Alias for calling [addItem] with
+ * `ResponseInputItem.ofFunctionCallOutput(functionCallOutput)`.
+ */
+ fun addItem(functionCallOutput: ResponseInputItem.FunctionCallOutput) = apply {
+ body.addItem(functionCallOutput)
+ }
+
+ /** Alias for calling [addItem] with `ResponseInputItem.ofReasoning(reasoning)`. */
+ fun addItem(reasoning: ResponseReasoningItem) = apply { body.addItem(reasoning) }
+
+ /**
+ * Alias for calling [addItem] with
+ * `ResponseInputItem.ofImageGenerationCall(imageGenerationCall)`.
+ */
+ fun addItem(imageGenerationCall: ResponseInputItem.ImageGenerationCall) = apply {
+ body.addItem(imageGenerationCall)
+ }
+
+ /**
+ * Alias for calling [addItem] with
+ * `ResponseInputItem.ofCodeInterpreterCall(codeInterpreterCall)`.
+ */
+ fun addItem(codeInterpreterCall: ResponseCodeInterpreterToolCall) = apply {
+ body.addItem(codeInterpreterCall)
+ }
+
+ /**
+ * Alias for calling [addItem] with `ResponseInputItem.ofLocalShellCall(localShellCall)`.
+ */
+ fun addItem(localShellCall: ResponseInputItem.LocalShellCall) = apply {
+ body.addItem(localShellCall)
+ }
+
+ /**
+ * Alias for calling [addItem] with
+ * `ResponseInputItem.ofLocalShellCallOutput(localShellCallOutput)`.
+ */
+ fun addItem(localShellCallOutput: ResponseInputItem.LocalShellCallOutput) = apply {
+ body.addItem(localShellCallOutput)
+ }
+
+ /** Alias for calling [addItem] with `ResponseInputItem.ofMcpListTools(mcpListTools)`. */
+ fun addItem(mcpListTools: ResponseInputItem.McpListTools) = apply {
+ body.addItem(mcpListTools)
+ }
+
+ /**
+ * Alias for calling [addItem] with
+ * `ResponseInputItem.ofMcpApprovalRequest(mcpApprovalRequest)`.
+ */
+ fun addItem(mcpApprovalRequest: ResponseInputItem.McpApprovalRequest) = apply {
+ body.addItem(mcpApprovalRequest)
+ }
+
+ /**
+ * Alias for calling [addItem] with
+ * `ResponseInputItem.ofMcpApprovalResponse(mcpApprovalResponse)`.
+ */
+ fun addItem(mcpApprovalResponse: ResponseInputItem.McpApprovalResponse) = apply {
+ body.addItem(mcpApprovalResponse)
+ }
+
+ /** Alias for calling [addItem] with `ResponseInputItem.ofMcpCall(mcpCall)`. */
+ fun addItem(mcpCall: ResponseInputItem.McpCall) = apply { body.addItem(mcpCall) }
+
+ /**
+ * Alias for calling [addItem] with
+ * `ResponseInputItem.ofCustomToolCallOutput(customToolCallOutput)`.
+ */
+ fun addItem(customToolCallOutput: ResponseCustomToolCallOutput) = apply {
+ body.addItem(customToolCallOutput)
+ }
+
+ /**
+ * Alias for calling [addItem] with `ResponseInputItem.ofCustomToolCall(customToolCall)`.
+ */
+ fun addItem(customToolCall: ResponseCustomToolCall) = apply { body.addItem(customToolCall) }
+
+ /** Alias for calling [addItem] with `ResponseInputItem.ofItemReference(itemReference)`. */
+ fun addItem(itemReference: ResponseInputItem.ItemReference) = apply {
+ body.addItem(itemReference)
+ }
+
+ /**
+ * Alias for calling [addItem] with the following:
+ * ```java
+ * ResponseInputItem.ItemReference.builder()
+ * .type(ResponseInputItem.ItemReference.Type.ITEM_REFERENCE)
+ * .id(id)
+ * .build()
+ * ```
+ */
+ fun addItemReferenceItem(id: String) = apply { body.addItemReferenceItem(id) }
+
+ /**
+ * Set of 16 key-value pairs that can be attached to an object. Useful for storing
+ * additional information about the object in a structured format.
+ */
+ fun metadata(metadata: Metadata?) = apply { body.metadata(metadata) }
+
+ /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */
+ fun metadata(metadata: Optional) = metadata(metadata.getOrNull())
+
+ /**
+ * Sets [Builder.metadata] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.metadata] with a well-typed [Metadata] value instead.
+ * This method is primarily for setting the field to an undocumented or not yet supported
+ * value.
+ */
+ fun metadata(metadata: JsonField) = apply { body.metadata(metadata) }
+
+ fun additionalBodyProperties(additionalBodyProperties: Map) = apply {
+ body.additionalProperties(additionalBodyProperties)
+ }
+
+ fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply {
+ body.putAdditionalProperty(key, value)
+ }
+
+ fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) =
+ apply {
+ body.putAllAdditionalProperties(additionalBodyProperties)
+ }
+
+ fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) }
+
+ fun removeAllAdditionalBodyProperties(keys: Set) = apply {
+ body.removeAllAdditionalProperties(keys)
+ }
+
+ fun additionalHeaders(additionalHeaders: Headers) = apply {
+ this.additionalHeaders.clear()
+ putAllAdditionalHeaders(additionalHeaders)
+ }
+
+ fun additionalHeaders(additionalHeaders: Map>) = apply {
+ this.additionalHeaders.clear()
+ putAllAdditionalHeaders(additionalHeaders)
+ }
+
+ fun putAdditionalHeader(name: String, value: String) = apply {
+ additionalHeaders.put(name, value)
+ }
+
+ fun putAdditionalHeaders(name: String, values: Iterable) = apply {
+ additionalHeaders.put(name, values)
+ }
+
+ fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply {
+ this.additionalHeaders.putAll(additionalHeaders)
+ }
+
+ fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply {
+ this.additionalHeaders.putAll(additionalHeaders)
+ }
+
+ fun replaceAdditionalHeaders(name: String, value: String) = apply {
+ additionalHeaders.replace(name, value)
+ }
+
+ fun replaceAdditionalHeaders(name: String, values: Iterable) = apply {
+ additionalHeaders.replace(name, values)
+ }
+
+ fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply {
+ this.additionalHeaders.replaceAll(additionalHeaders)
+ }
+
+ fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply {
+ this.additionalHeaders.replaceAll(additionalHeaders)
+ }
+
+ fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) }
+
+ fun removeAllAdditionalHeaders(names: Set) = apply {
+ additionalHeaders.removeAll(names)
+ }
+
+ fun additionalQueryParams(additionalQueryParams: QueryParams) = apply {
+ this.additionalQueryParams.clear()
+ putAllAdditionalQueryParams(additionalQueryParams)
+ }
+
+ fun additionalQueryParams(additionalQueryParams: Map>) = apply {
+ this.additionalQueryParams.clear()
+ putAllAdditionalQueryParams(additionalQueryParams)
+ }
+
+ fun putAdditionalQueryParam(key: String, value: String) = apply {
+ additionalQueryParams.put(key, value)
+ }
+
+ fun putAdditionalQueryParams(key: String, values: Iterable) = apply {
+ additionalQueryParams.put(key, values)
+ }
+
+ fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply {
+ this.additionalQueryParams.putAll(additionalQueryParams)
+ }
+
+ fun putAllAdditionalQueryParams(additionalQueryParams: Map>) =
+ apply {
+ this.additionalQueryParams.putAll(additionalQueryParams)
+ }
+
+ fun replaceAdditionalQueryParams(key: String, value: String) = apply {
+ additionalQueryParams.replace(key, value)
+ }
+
+ fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply {
+ additionalQueryParams.replace(key, values)
+ }
+
+ fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply {
+ this.additionalQueryParams.replaceAll(additionalQueryParams)
+ }
+
+ fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) =
+ apply {
+ this.additionalQueryParams.replaceAll(additionalQueryParams)
+ }
+
+ fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) }
+
+ fun removeAllAdditionalQueryParams(keys: Set) = apply {
+ additionalQueryParams.removeAll(keys)
+ }
+
+ /**
+ * Returns an immutable instance of [ConversationCreateParams].
+ *
+ * Further updates to this [Builder] will not mutate the returned instance.
+ */
+ fun build(): ConversationCreateParams =
+ ConversationCreateParams(
+ body.build(),
+ additionalHeaders.build(),
+ additionalQueryParams.build(),
+ )
+ }
+
+ fun _body(): Body = body
+
+ override fun _headers(): Headers = additionalHeaders
+
+ override fun _queryParams(): QueryParams = additionalQueryParams
+
+ /** Create a conversation */
+ class Body
+ private constructor(
+ private val items: JsonField>,
+ private val metadata: JsonField,
+ private val additionalProperties: MutableMap,
+ ) {
+
+ @JsonCreator
+ private constructor(
+ @JsonProperty("items")
+ @ExcludeMissing
+ items: JsonField> = JsonMissing.of(),
+ @JsonProperty("metadata")
+ @ExcludeMissing
+ metadata: JsonField = JsonMissing.of(),
+ ) : this(items, metadata, mutableMapOf())
+
+ /**
+ * Initial items to include in the conversation context. You may add up to 20 items at a
+ * time.
+ *
+ * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the
+ * server responded with an unexpected value).
+ */
+ fun items(): Optional> = items.getOptional("items")
+
+ /**
+ * Set of 16 key-value pairs that can be attached to an object. Useful for storing
+ * additional information about the object in a structured format.
+ *
+ * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the
+ * server responded with an unexpected value).
+ */
+ fun metadata(): Optional = metadata.getOptional("metadata")
+
+ /**
+ * Returns the raw JSON value of [items].
+ *
+ * Unlike [items], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("items")
+ @ExcludeMissing
+ fun _items(): JsonField> = items
+
+ /**
+ * Returns the raw JSON value of [metadata].
+ *
+ * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata
+
+ @JsonAnySetter
+ private fun putAdditionalProperty(key: String, value: JsonValue) {
+ additionalProperties.put(key, value)
+ }
+
+ @JsonAnyGetter
+ @ExcludeMissing
+ fun _additionalProperties(): Map =
+ Collections.unmodifiableMap(additionalProperties)
+
+ fun toBuilder() = Builder().from(this)
+
+ companion object {
+
+ /** Returns a mutable builder for constructing an instance of [Body]. */
+ @JvmStatic fun builder() = Builder()
+ }
+
+ /** A builder for [Body]. */
+ class Builder internal constructor() {
+
+ private var items: JsonField>? = null
+ private var metadata: JsonField = JsonMissing.of()
+ private var additionalProperties: MutableMap = mutableMapOf()
+
+ @JvmSynthetic
+ internal fun from(body: Body) = apply {
+ items = body.items.map { it.toMutableList() }
+ metadata = body.metadata
+ additionalProperties = body.additionalProperties.toMutableMap()
+ }
+
+ /**
+ * Initial items to include in the conversation context. You may add up to 20 items at a
+ * time.
+ */
+ fun items(items: List?) = items(JsonField.ofNullable(items))
+
+ /** Alias for calling [Builder.items] with `items.orElse(null)`. */
+ fun items(items: Optional>) = items(items.getOrNull())
+
+ /**
+ * Sets [Builder.items] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.items] with a well-typed `List`
+ * value instead. This method is primarily for setting the field to an undocumented or
+ * not yet supported value.
+ */
+ fun items(items: JsonField>) = apply {
+ this.items = items.map { it.toMutableList() }
+ }
+
+ /**
+ * Adds a single [ResponseInputItem] to [items].
+ *
+ * @throws IllegalStateException if the field was previously set to a non-list.
+ */
+ fun addItem(item: ResponseInputItem) = apply {
+ items =
+ (items ?: JsonField.of(mutableListOf())).also {
+ checkKnown("items", it).add(item)
+ }
+ }
+
+ /**
+ * Alias for calling [addItem] with
+ * `ResponseInputItem.ofEasyInputMessage(easyInputMessage)`.
+ */
+ fun addItem(easyInputMessage: EasyInputMessage) =
+ addItem(ResponseInputItem.ofEasyInputMessage(easyInputMessage))
+
+ /** Alias for calling [addItem] with `ResponseInputItem.ofMessage(message)`. */
+ fun addItem(message: ResponseInputItem.Message) =
+ addItem(ResponseInputItem.ofMessage(message))
+
+ /**
+ * Alias for calling [addItem] with
+ * `ResponseInputItem.ofResponseOutputMessage(responseOutputMessage)`.
+ */
+ fun addItem(responseOutputMessage: ResponseOutputMessage) =
+ addItem(ResponseInputItem.ofResponseOutputMessage(responseOutputMessage))
+
+ /**
+ * Alias for calling [addItem] with
+ * `ResponseInputItem.ofFileSearchCall(fileSearchCall)`.
+ */
+ fun addItem(fileSearchCall: ResponseFileSearchToolCall) =
+ addItem(ResponseInputItem.ofFileSearchCall(fileSearchCall))
+
+ /**
+ * Alias for calling [addItem] with `ResponseInputItem.ofComputerCall(computerCall)`.
+ */
+ fun addItem(computerCall: ResponseComputerToolCall) =
+ addItem(ResponseInputItem.ofComputerCall(computerCall))
+
+ /**
+ * Alias for calling [addItem] with
+ * `ResponseInputItem.ofComputerCallOutput(computerCallOutput)`.
+ */
+ fun addItem(computerCallOutput: ResponseInputItem.ComputerCallOutput) =
+ addItem(ResponseInputItem.ofComputerCallOutput(computerCallOutput))
+
+ /**
+ * Alias for calling [addItem] with `ResponseInputItem.ofWebSearchCall(webSearchCall)`.
+ */
+ fun addItem(webSearchCall: ResponseFunctionWebSearch) =
+ addItem(ResponseInputItem.ofWebSearchCall(webSearchCall))
+
+ /**
+ * Alias for calling [addItem] with `ResponseInputItem.ofFunctionCall(functionCall)`.
+ */
+ fun addItem(functionCall: ResponseFunctionToolCall) =
+ addItem(ResponseInputItem.ofFunctionCall(functionCall))
+
+ /**
+ * Alias for calling [addItem] with
+ * `ResponseInputItem.ofFunctionCallOutput(functionCallOutput)`.
+ */
+ fun addItem(functionCallOutput: ResponseInputItem.FunctionCallOutput) =
+ addItem(ResponseInputItem.ofFunctionCallOutput(functionCallOutput))
+
+ /** Alias for calling [addItem] with `ResponseInputItem.ofReasoning(reasoning)`. */
+ fun addItem(reasoning: ResponseReasoningItem) =
+ addItem(ResponseInputItem.ofReasoning(reasoning))
+
+ /**
+ * Alias for calling [addItem] with
+ * `ResponseInputItem.ofImageGenerationCall(imageGenerationCall)`.
+ */
+ fun addItem(imageGenerationCall: ResponseInputItem.ImageGenerationCall) =
+ addItem(ResponseInputItem.ofImageGenerationCall(imageGenerationCall))
+
+ /**
+ * Alias for calling [addItem] with
+ * `ResponseInputItem.ofCodeInterpreterCall(codeInterpreterCall)`.
+ */
+ fun addItem(codeInterpreterCall: ResponseCodeInterpreterToolCall) =
+ addItem(ResponseInputItem.ofCodeInterpreterCall(codeInterpreterCall))
+
+ /**
+ * Alias for calling [addItem] with
+ * `ResponseInputItem.ofLocalShellCall(localShellCall)`.
+ */
+ fun addItem(localShellCall: ResponseInputItem.LocalShellCall) =
+ addItem(ResponseInputItem.ofLocalShellCall(localShellCall))
+
+ /**
+ * Alias for calling [addItem] with
+ * `ResponseInputItem.ofLocalShellCallOutput(localShellCallOutput)`.
+ */
+ fun addItem(localShellCallOutput: ResponseInputItem.LocalShellCallOutput) =
+ addItem(ResponseInputItem.ofLocalShellCallOutput(localShellCallOutput))
+
+ /**
+ * Alias for calling [addItem] with `ResponseInputItem.ofMcpListTools(mcpListTools)`.
+ */
+ fun addItem(mcpListTools: ResponseInputItem.McpListTools) =
+ addItem(ResponseInputItem.ofMcpListTools(mcpListTools))
+
+ /**
+ * Alias for calling [addItem] with
+ * `ResponseInputItem.ofMcpApprovalRequest(mcpApprovalRequest)`.
+ */
+ fun addItem(mcpApprovalRequest: ResponseInputItem.McpApprovalRequest) =
+ addItem(ResponseInputItem.ofMcpApprovalRequest(mcpApprovalRequest))
+
+ /**
+ * Alias for calling [addItem] with
+ * `ResponseInputItem.ofMcpApprovalResponse(mcpApprovalResponse)`.
+ */
+ fun addItem(mcpApprovalResponse: ResponseInputItem.McpApprovalResponse) =
+ addItem(ResponseInputItem.ofMcpApprovalResponse(mcpApprovalResponse))
+
+ /** Alias for calling [addItem] with `ResponseInputItem.ofMcpCall(mcpCall)`. */
+ fun addItem(mcpCall: ResponseInputItem.McpCall) =
+ addItem(ResponseInputItem.ofMcpCall(mcpCall))
+
+ /**
+ * Alias for calling [addItem] with
+ * `ResponseInputItem.ofCustomToolCallOutput(customToolCallOutput)`.
+ */
+ fun addItem(customToolCallOutput: ResponseCustomToolCallOutput) =
+ addItem(ResponseInputItem.ofCustomToolCallOutput(customToolCallOutput))
+
+ /**
+ * Alias for calling [addItem] with
+ * `ResponseInputItem.ofCustomToolCall(customToolCall)`.
+ */
+ fun addItem(customToolCall: ResponseCustomToolCall) =
+ addItem(ResponseInputItem.ofCustomToolCall(customToolCall))
+
+ /**
+ * Alias for calling [addItem] with `ResponseInputItem.ofItemReference(itemReference)`.
+ */
+ fun addItem(itemReference: ResponseInputItem.ItemReference) =
+ addItem(ResponseInputItem.ofItemReference(itemReference))
+
+ /**
+ * Alias for calling [addItem] with the following:
+ * ```java
+ * ResponseInputItem.ItemReference.builder()
+ * .type(ResponseInputItem.ItemReference.Type.ITEM_REFERENCE)
+ * .id(id)
+ * .build()
+ * ```
+ */
+ fun addItemReferenceItem(id: String) =
+ addItem(
+ ResponseInputItem.ItemReference.builder()
+ .type(ResponseInputItem.ItemReference.Type.ITEM_REFERENCE)
+ .id(id)
+ .build()
+ )
+
+ /**
+ * Set of 16 key-value pairs that can be attached to an object. Useful for storing
+ * additional information about the object in a structured format.
+ */
+ fun metadata(metadata: Metadata?) = metadata(JsonField.ofNullable(metadata))
+
+ /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */
+ fun metadata(metadata: Optional) = metadata(metadata.getOrNull())
+
+ /**
+ * Sets [Builder.metadata] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.metadata] with a well-typed [Metadata] value
+ * instead. This method is primarily for setting the field to an undocumented or not yet
+ * supported value.
+ */
+ fun metadata(metadata: JsonField) = apply { this.metadata = metadata }
+
+ fun additionalProperties(additionalProperties: Map) = apply {
+ this.additionalProperties.clear()
+ putAllAdditionalProperties(additionalProperties)
+ }
+
+ fun putAdditionalProperty(key: String, value: JsonValue) = apply {
+ additionalProperties.put(key, value)
+ }
+
+ fun putAllAdditionalProperties(additionalProperties: Map) = apply {
+ this.additionalProperties.putAll(additionalProperties)
+ }
+
+ fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) }
+
+ fun removeAllAdditionalProperties(keys: Set) = apply {
+ keys.forEach(::removeAdditionalProperty)
+ }
+
+ /**
+ * Returns an immutable instance of [Body].
+ *
+ * Further updates to this [Builder] will not mutate the returned instance.
+ */
+ fun build(): Body =
+ Body(
+ (items ?: JsonMissing.of()).map { it.toImmutable() },
+ metadata,
+ additionalProperties.toMutableMap(),
+ )
+ }
+
+ private var validated: Boolean = false
+
+ fun validate(): Body = apply {
+ if (validated) {
+ return@apply
+ }
+
+ items().ifPresent { it.forEach { it.validate() } }
+ metadata().ifPresent { it.validate() }
+ validated = true
+ }
+
+ fun isValid(): Boolean =
+ try {
+ validate()
+ true
+ } catch (e: OpenAIInvalidDataException) {
+ false
+ }
+
+ /**
+ * Returns a score indicating how many valid values are contained in this object
+ * recursively.
+ *
+ * Used for best match union deserialization.
+ */
+ @JvmSynthetic
+ internal fun validity(): Int =
+ (items.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) +
+ (metadata.asKnown().getOrNull()?.validity() ?: 0)
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) {
+ return true
+ }
+
+ return other is Body &&
+ items == other.items &&
+ metadata == other.metadata &&
+ additionalProperties == other.additionalProperties
+ }
+
+ private val hashCode: Int by lazy { Objects.hash(items, metadata, additionalProperties) }
+
+ override fun hashCode(): Int = hashCode
+
+ override fun toString() =
+ "Body{items=$items, metadata=$metadata, additionalProperties=$additionalProperties}"
+ }
+
+ /**
+ * Set of 16 key-value pairs that can be attached to an object. This can be useful for storing
+ * additional information about the object in a structured format, and querying for objects via
+ * API or the dashboard.
+ *
+ * Keys are strings with a maximum length of 64 characters. Values are strings with a maximum
+ * length of 512 characters.
+ */
+ class Metadata
+ @JsonCreator
+ private constructor(
+ @com.fasterxml.jackson.annotation.JsonValue
+ private val additionalProperties: Map
+ ) {
+
+ @JsonAnyGetter
+ @ExcludeMissing
+ fun _additionalProperties(): Map = additionalProperties
+
+ fun toBuilder() = Builder().from(this)
+
+ companion object {
+
+ /** Returns a mutable builder for constructing an instance of [Metadata]. */
+ @JvmStatic fun builder() = Builder()
+ }
+
+ /** A builder for [Metadata]. */
+ class Builder internal constructor() {
+
+ private var additionalProperties: MutableMap = mutableMapOf()
+
+ @JvmSynthetic
+ internal fun from(metadata: Metadata) = apply {
+ additionalProperties = metadata.additionalProperties.toMutableMap()
+ }
+
+ 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 [Metadata].
+ *
+ * Further updates to this [Builder] will not mutate the returned instance.
+ */
+ fun build(): Metadata = Metadata(additionalProperties.toImmutable())
+ }
+
+ private var validated: Boolean = false
+
+ fun validate(): Metadata = apply {
+ if (validated) {
+ return@apply
+ }
+
+ 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 =
+ additionalProperties.count { (_, value) -> !value.isNull() && !value.isMissing() }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) {
+ return true
+ }
+
+ return other is Metadata && additionalProperties == other.additionalProperties
+ }
+
+ private val hashCode: Int by lazy { Objects.hash(additionalProperties) }
+
+ override fun hashCode(): Int = hashCode
+
+ override fun toString() = "Metadata{additionalProperties=$additionalProperties}"
+ }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) {
+ return true
+ }
+
+ return other is ConversationCreateParams &&
+ body == other.body &&
+ additionalHeaders == other.additionalHeaders &&
+ additionalQueryParams == other.additionalQueryParams
+ }
+
+ override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams)
+
+ override fun toString() =
+ "ConversationCreateParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}"
+}
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/conversations/ConversationDeleteParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/conversations/ConversationDeleteParams.kt
new file mode 100644
index 000000000..37d8342ac
--- /dev/null
+++ b/openai-java-core/src/main/kotlin/com/openai/models/conversations/ConversationDeleteParams.kt
@@ -0,0 +1,236 @@
+// File generated from our OpenAPI spec by Stainless.
+
+package com.openai.models.conversations
+
+import com.openai.core.JsonValue
+import com.openai.core.Params
+import com.openai.core.http.Headers
+import com.openai.core.http.QueryParams
+import com.openai.core.toImmutable
+import java.util.Objects
+import java.util.Optional
+import kotlin.jvm.optionals.getOrNull
+
+/** Delete a conversation with the given ID. */
+class ConversationDeleteParams
+private constructor(
+ private val conversationId: String?,
+ private val additionalHeaders: Headers,
+ private val additionalQueryParams: QueryParams,
+ private val additionalBodyProperties: Map,
+) : Params {
+
+ fun conversationId(): Optional = Optional.ofNullable(conversationId)
+
+ /** Additional body properties to send with the request. */
+ fun _additionalBodyProperties(): Map = additionalBodyProperties
+
+ /** Additional headers to send with the request. */
+ fun _additionalHeaders(): Headers = additionalHeaders
+
+ /** Additional query param to send with the request. */
+ fun _additionalQueryParams(): QueryParams = additionalQueryParams
+
+ fun toBuilder() = Builder().from(this)
+
+ companion object {
+
+ @JvmStatic fun none(): ConversationDeleteParams = builder().build()
+
+ /** Returns a mutable builder for constructing an instance of [ConversationDeleteParams]. */
+ @JvmStatic fun builder() = Builder()
+ }
+
+ /** A builder for [ConversationDeleteParams]. */
+ class Builder internal constructor() {
+
+ private var conversationId: String? = null
+ private var additionalHeaders: Headers.Builder = Headers.builder()
+ private var additionalQueryParams: QueryParams.Builder = QueryParams.builder()
+ private var additionalBodyProperties: MutableMap = mutableMapOf()
+
+ @JvmSynthetic
+ internal fun from(conversationDeleteParams: ConversationDeleteParams) = apply {
+ conversationId = conversationDeleteParams.conversationId
+ additionalHeaders = conversationDeleteParams.additionalHeaders.toBuilder()
+ additionalQueryParams = conversationDeleteParams.additionalQueryParams.toBuilder()
+ additionalBodyProperties =
+ conversationDeleteParams.additionalBodyProperties.toMutableMap()
+ }
+
+ fun conversationId(conversationId: String?) = apply { this.conversationId = conversationId }
+
+ /** Alias for calling [Builder.conversationId] with `conversationId.orElse(null)`. */
+ fun conversationId(conversationId: Optional) =
+ conversationId(conversationId.getOrNull())
+
+ fun additionalHeaders(additionalHeaders: Headers) = apply {
+ this.additionalHeaders.clear()
+ putAllAdditionalHeaders(additionalHeaders)
+ }
+
+ fun additionalHeaders(additionalHeaders: Map>) = apply {
+ this.additionalHeaders.clear()
+ putAllAdditionalHeaders(additionalHeaders)
+ }
+
+ fun putAdditionalHeader(name: String, value: String) = apply {
+ additionalHeaders.put(name, value)
+ }
+
+ fun putAdditionalHeaders(name: String, values: Iterable) = apply {
+ additionalHeaders.put(name, values)
+ }
+
+ fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply {
+ this.additionalHeaders.putAll(additionalHeaders)
+ }
+
+ fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply {
+ this.additionalHeaders.putAll(additionalHeaders)
+ }
+
+ fun replaceAdditionalHeaders(name: String, value: String) = apply {
+ additionalHeaders.replace(name, value)
+ }
+
+ fun replaceAdditionalHeaders(name: String, values: Iterable) = apply {
+ additionalHeaders.replace(name, values)
+ }
+
+ fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply {
+ this.additionalHeaders.replaceAll(additionalHeaders)
+ }
+
+ fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply {
+ this.additionalHeaders.replaceAll(additionalHeaders)
+ }
+
+ fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) }
+
+ fun removeAllAdditionalHeaders(names: Set) = apply {
+ additionalHeaders.removeAll(names)
+ }
+
+ fun additionalQueryParams(additionalQueryParams: QueryParams) = apply {
+ this.additionalQueryParams.clear()
+ putAllAdditionalQueryParams(additionalQueryParams)
+ }
+
+ fun additionalQueryParams(additionalQueryParams: Map>) = apply {
+ this.additionalQueryParams.clear()
+ putAllAdditionalQueryParams(additionalQueryParams)
+ }
+
+ fun putAdditionalQueryParam(key: String, value: String) = apply {
+ additionalQueryParams.put(key, value)
+ }
+
+ fun putAdditionalQueryParams(key: String, values: Iterable) = apply {
+ additionalQueryParams.put(key, values)
+ }
+
+ fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply {
+ this.additionalQueryParams.putAll(additionalQueryParams)
+ }
+
+ fun putAllAdditionalQueryParams(additionalQueryParams: Map>) =
+ apply {
+ this.additionalQueryParams.putAll(additionalQueryParams)
+ }
+
+ fun replaceAdditionalQueryParams(key: String, value: String) = apply {
+ additionalQueryParams.replace(key, value)
+ }
+
+ fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply {
+ additionalQueryParams.replace(key, values)
+ }
+
+ fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply {
+ this.additionalQueryParams.replaceAll(additionalQueryParams)
+ }
+
+ fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) =
+ apply {
+ this.additionalQueryParams.replaceAll(additionalQueryParams)
+ }
+
+ fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) }
+
+ fun removeAllAdditionalQueryParams(keys: Set) = apply {
+ additionalQueryParams.removeAll(keys)
+ }
+
+ fun additionalBodyProperties(additionalBodyProperties: Map) = apply {
+ this.additionalBodyProperties.clear()
+ putAllAdditionalBodyProperties(additionalBodyProperties)
+ }
+
+ fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply {
+ additionalBodyProperties.put(key, value)
+ }
+
+ fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) =
+ apply {
+ this.additionalBodyProperties.putAll(additionalBodyProperties)
+ }
+
+ fun removeAdditionalBodyProperty(key: String) = apply {
+ additionalBodyProperties.remove(key)
+ }
+
+ fun removeAllAdditionalBodyProperties(keys: Set) = apply {
+ keys.forEach(::removeAdditionalBodyProperty)
+ }
+
+ /**
+ * Returns an immutable instance of [ConversationDeleteParams].
+ *
+ * Further updates to this [Builder] will not mutate the returned instance.
+ */
+ fun build(): ConversationDeleteParams =
+ ConversationDeleteParams(
+ conversationId,
+ additionalHeaders.build(),
+ additionalQueryParams.build(),
+ additionalBodyProperties.toImmutable(),
+ )
+ }
+
+ fun _body(): Optional