diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index b25856537..c1a7e63f6 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "2.16.0"
+ ".": "2.17.0"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3e2dab59e..26c1f7504 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,19 @@
# Changelog
+## 2.17.0 (2025-07-21)
+
+Full Changelog: [v2.16.0...v2.17.0](https://github.com/openai/openai-java/compare/v2.16.0...v2.17.0)
+
+### Features
+
+* **client:** add https config options ([3f74519](https://github.com/openai/openai-java/commit/3f745195fa5d72ee72653adbd8087915c0db2fa5))
+* **client:** allow setting additional multipart body props ([220503e](https://github.com/openai/openai-java/commit/220503efc745bd1c74c02f1d4d6d3305198bf942))
+
+
+### Chores
+
+* **internal:** refactor delegating from client to options ([e89596d](https://github.com/openai/openai-java/commit/e89596d624fd77fdef750fb65a9ca5c6497e76cb))
+
## 2.16.0 (2025-07-17)
Full Changelog: [v2.15.0...v2.16.0](https://github.com/openai/openai-java/compare/v2.15.0...v2.16.0)
diff --git a/README.md b/README.md
index 4cfacb475..3a908e5e6 100644
--- a/README.md
+++ b/README.md
@@ -2,8 +2,8 @@
-[](https://central.sonatype.com/artifact/com.openai/openai-java/2.16.0)
-[](https://javadoc.io/doc/com.openai/openai-java/2.16.0)
+[](https://central.sonatype.com/artifact/com.openai/openai-java/2.17.0)
+[](https://javadoc.io/doc/com.openai/openai-java/2.17.0)
@@ -11,7 +11,7 @@ The OpenAI Java SDK provides convenient access to the [OpenAI REST API](https://
-The REST API documentation can be found on [platform.openai.com](https://platform.openai.com/docs). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.openai/openai-java/2.16.0).
+The REST API documentation can be found on [platform.openai.com](https://platform.openai.com/docs). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.openai/openai-java/2.17.0).
@@ -22,7 +22,7 @@ The REST API documentation can be found on [platform.openai.com](https://platfor
### Gradle
```kotlin
-implementation("com.openai:openai-java:2.16.0")
+implementation("com.openai:openai-java:2.17.0")
```
### Maven
@@ -31,7 +31,7 @@ implementation("com.openai:openai-java:2.16.0")
com.openai
openai-java
- 2.16.0
+ 2.17.0
```
@@ -1398,6 +1398,27 @@ OpenAIClient client = OpenAIOkHttpClient.builder()
.build();
```
+### HTTPS
+
+> [!NOTE]
+> Most applications should not call these methods, and instead use the system defaults. The defaults include
+> special optimizations that can be lost if the implementations are modified.
+
+To configure how HTTPS connections are secured, configure the client using the `sslSocketFactory`, `trustManager`, and `hostnameVerifier` methods:
+
+```java
+import com.openai.client.OpenAIClient;
+import com.openai.client.okhttp.OpenAIOkHttpClient;
+
+OpenAIClient client = OpenAIOkHttpClient.builder()
+ .fromEnv()
+ // If `sslSocketFactory` is set, then `trustManager` must be set, and vice versa.
+ .sslSocketFactory(yourSSLSocketFactory)
+ .trustManager(yourTrustManager)
+ .hostnameVerifier(yourHostnameVerifier)
+ .build();
+```
+
### Custom HTTP client
The SDK consists of three artifacts:
diff --git a/build.gradle.kts b/build.gradle.kts
index 2fe350c2b..b08877411 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -8,7 +8,7 @@ repositories {
allprojects {
group = "com.openai"
- version = "2.16.0" // x-release-please-version
+ version = "2.17.0" // x-release-please-version
}
subprojects {
diff --git a/openai-java-client-okhttp/src/main/kotlin/com/openai/client/okhttp/OkHttpClient.kt b/openai-java-client-okhttp/src/main/kotlin/com/openai/client/okhttp/OkHttpClient.kt
index 5bc954183..e4f63c286 100644
--- a/openai-java-client-okhttp/src/main/kotlin/com/openai/client/okhttp/OkHttpClient.kt
+++ b/openai-java-client-okhttp/src/main/kotlin/com/openai/client/okhttp/OkHttpClient.kt
@@ -14,6 +14,9 @@ import java.io.InputStream
import java.net.Proxy
import java.time.Duration
import java.util.concurrent.CompletableFuture
+import javax.net.ssl.HostnameVerifier
+import javax.net.ssl.SSLSocketFactory
+import javax.net.ssl.X509TrustManager
import okhttp3.Call
import okhttp3.Callback
import okhttp3.HttpUrl.Companion.toHttpUrl
@@ -189,6 +192,9 @@ class OkHttpClient private constructor(private val okHttpClient: okhttp3.OkHttpC
private var timeout: Timeout = Timeout.default()
private var proxy: Proxy? = null
+ private var sslSocketFactory: SSLSocketFactory? = null
+ private var trustManager: X509TrustManager? = null
+ private var hostnameVerifier: HostnameVerifier? = null
fun timeout(timeout: Timeout) = apply { this.timeout = timeout }
@@ -196,6 +202,18 @@ class OkHttpClient private constructor(private val okHttpClient: okhttp3.OkHttpC
fun proxy(proxy: Proxy?) = apply { this.proxy = proxy }
+ fun sslSocketFactory(sslSocketFactory: SSLSocketFactory?) = apply {
+ this.sslSocketFactory = sslSocketFactory
+ }
+
+ fun trustManager(trustManager: X509TrustManager?) = apply {
+ this.trustManager = trustManager
+ }
+
+ fun hostnameVerifier(hostnameVerifier: HostnameVerifier?) = apply {
+ this.hostnameVerifier = hostnameVerifier
+ }
+
fun build(): OkHttpClient =
OkHttpClient(
okhttp3.OkHttpClient.Builder()
@@ -204,6 +222,19 @@ class OkHttpClient private constructor(private val okHttpClient: okhttp3.OkHttpC
.writeTimeout(timeout.write())
.callTimeout(timeout.request())
.proxy(proxy)
+ .apply {
+ val sslSocketFactory = sslSocketFactory
+ val trustManager = trustManager
+ if (sslSocketFactory != null && trustManager != null) {
+ sslSocketFactory(sslSocketFactory, trustManager)
+ } else {
+ check((sslSocketFactory != null) == (trustManager != null)) {
+ "Both or none of `sslSocketFactory` and `trustManager` must be set, but only one was set"
+ }
+ }
+
+ hostnameVerifier?.let(::hostnameVerifier)
+ }
.build()
.apply {
// We usually make all our requests to the same host so it makes sense to
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 6d34a73ce..95041beee 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
@@ -10,12 +10,16 @@ import com.openai.core.ClientOptions
import com.openai.core.Timeout
import com.openai.core.http.Headers
import com.openai.core.http.QueryParams
+import com.openai.core.jsonMapper
import com.openai.credential.Credential
import java.net.Proxy
import java.time.Clock
import java.time.Duration
import java.util.Optional
import java.util.concurrent.Executor
+import javax.net.ssl.HostnameVerifier
+import javax.net.ssl.SSLSocketFactory
+import javax.net.ssl.X509TrustManager
import kotlin.jvm.optionals.getOrNull
class OpenAIOkHttpClient private constructor() {
@@ -32,10 +36,63 @@ class OpenAIOkHttpClient private constructor() {
class Builder internal constructor() {
private var clientOptions: ClientOptions.Builder = ClientOptions.builder()
- private var timeout: Timeout = Timeout.default()
private var proxy: Proxy? = null
+ private var sslSocketFactory: SSLSocketFactory? = null
+ private var trustManager: X509TrustManager? = null
+ private var hostnameVerifier: HostnameVerifier? = null
- fun baseUrl(baseUrl: String) = apply { clientOptions.baseUrl(baseUrl) }
+ fun proxy(proxy: Proxy?) = apply { this.proxy = proxy }
+
+ /** Alias for calling [Builder.proxy] with `proxy.orElse(null)`. */
+ fun proxy(proxy: Optional) = proxy(proxy.getOrNull())
+
+ /**
+ * The socket factory used to secure HTTPS connections.
+ *
+ * If this is set, then [trustManager] must also be set.
+ *
+ * If unset, then the system default is used. Most applications should not call this method,
+ * and instead use the system default. The default include special optimizations that can be
+ * lost if the implementation is modified.
+ */
+ fun sslSocketFactory(sslSocketFactory: SSLSocketFactory?) = apply {
+ this.sslSocketFactory = sslSocketFactory
+ }
+
+ /** Alias for calling [Builder.sslSocketFactory] with `sslSocketFactory.orElse(null)`. */
+ fun sslSocketFactory(sslSocketFactory: Optional) =
+ sslSocketFactory(sslSocketFactory.getOrNull())
+
+ /**
+ * The trust manager used to secure HTTPS connections.
+ *
+ * If this is set, then [sslSocketFactory] must also be set.
+ *
+ * If unset, then the system default is used. Most applications should not call this method,
+ * and instead use the system default. The default include special optimizations that can be
+ * lost if the implementation is modified.
+ */
+ fun trustManager(trustManager: X509TrustManager?) = apply {
+ this.trustManager = trustManager
+ }
+
+ /** Alias for calling [Builder.trustManager] with `trustManager.orElse(null)`. */
+ fun trustManager(trustManager: Optional) =
+ trustManager(trustManager.getOrNull())
+
+ /**
+ * The verifier used to confirm that response certificates apply to requested hostnames for
+ * HTTPS connections.
+ *
+ * If unset, then a default hostname verifier is used.
+ */
+ fun hostnameVerifier(hostnameVerifier: HostnameVerifier?) = apply {
+ this.hostnameVerifier = hostnameVerifier
+ }
+
+ /** Alias for calling [Builder.hostnameVerifier] with `hostnameVerifier.orElse(null)`. */
+ fun hostnameVerifier(hostnameVerifier: Optional) =
+ hostnameVerifier(hostnameVerifier.getOrNull())
/**
* Whether to throw an exception if any of the Jackson versions detected at runtime are
@@ -56,6 +113,54 @@ class OpenAIOkHttpClient private constructor() {
fun clock(clock: Clock) = apply { clientOptions.clock(clock) }
+ fun baseUrl(baseUrl: String?) = apply { clientOptions.baseUrl(baseUrl) }
+
+ /** Alias for calling [Builder.baseUrl] with `baseUrl.orElse(null)`. */
+ fun baseUrl(baseUrl: Optional) = baseUrl(baseUrl.getOrNull())
+
+ fun responseValidation(responseValidation: Boolean) = apply {
+ clientOptions.responseValidation(responseValidation)
+ }
+
+ fun timeout(timeout: Timeout) = apply { clientOptions.timeout(timeout) }
+
+ /**
+ * Sets the maximum time allowed for a complete HTTP call, not including retries.
+ *
+ * See [Timeout.request] for more details.
+ *
+ * For fine-grained control, pass a [Timeout] object.
+ */
+ fun timeout(timeout: Duration) = apply { clientOptions.timeout(timeout) }
+
+ fun maxRetries(maxRetries: Int) = apply { clientOptions.maxRetries(maxRetries) }
+
+ fun apiKey(apiKey: String) = apply { clientOptions.apiKey(apiKey) }
+
+ fun credential(credential: Credential) = apply { clientOptions.credential(credential) }
+
+ fun azureServiceVersion(azureServiceVersion: AzureOpenAIServiceVersion) = apply {
+ clientOptions.azureServiceVersion(azureServiceVersion)
+ }
+
+ fun organization(organization: String?) = apply { clientOptions.organization(organization) }
+
+ /** Alias for calling [Builder.organization] with `organization.orElse(null)`. */
+ fun organization(organization: Optional) = organization(organization.getOrNull())
+
+ fun project(project: String?) = apply { clientOptions.project(project) }
+
+ /** Alias for calling [Builder.project] with `project.orElse(null)`. */
+ fun project(project: Optional) = project(project.getOrNull())
+
+ fun webhookSecret(webhookSecret: String?) = apply {
+ clientOptions.webhookSecret(webhookSecret)
+ }
+
+ /** Alias for calling [Builder.webhookSecret] with `webhookSecret.orElse(null)`. */
+ fun webhookSecret(webhookSecret: Optional) =
+ webhookSecret(webhookSecret.getOrNull())
+
fun headers(headers: Headers) = apply { clientOptions.headers(headers) }
fun headers(headers: Map>) = apply {
@@ -136,54 +241,6 @@ class OpenAIOkHttpClient private constructor() {
clientOptions.removeAllQueryParams(keys)
}
- fun timeout(timeout: Timeout) = apply {
- clientOptions.timeout(timeout)
- this.timeout = timeout
- }
-
- /**
- * Sets the maximum time allowed for a complete HTTP call, not including retries.
- *
- * See [Timeout.request] for more details.
- *
- * For fine-grained control, pass a [Timeout] object.
- */
- fun timeout(timeout: Duration) = timeout(Timeout.builder().request(timeout).build())
-
- fun maxRetries(maxRetries: Int) = apply { clientOptions.maxRetries(maxRetries) }
-
- fun proxy(proxy: Proxy) = apply { this.proxy = proxy }
-
- fun responseValidation(responseValidation: Boolean) = apply {
- clientOptions.responseValidation(responseValidation)
- }
-
- fun apiKey(apiKey: String) = apply { clientOptions.apiKey(apiKey) }
-
- fun credential(credential: Credential) = apply { clientOptions.credential(credential) }
-
- fun azureServiceVersion(azureServiceVersion: AzureOpenAIServiceVersion) = apply {
- clientOptions.azureServiceVersion(azureServiceVersion)
- }
-
- fun organization(organization: String?) = apply { clientOptions.organization(organization) }
-
- /** Alias for calling [Builder.organization] with `organization.orElse(null)`. */
- fun organization(organization: Optional) = organization(organization.getOrNull())
-
- fun project(project: String?) = apply { clientOptions.project(project) }
-
- /** Alias for calling [Builder.project] with `project.orElse(null)`. */
- fun project(project: Optional) = project(project.getOrNull())
-
- fun webhookSecret(webhookSecret: String?) = apply {
- clientOptions.webhookSecret(webhookSecret)
- }
-
- /** Alias for calling [Builder.webhookSecret] with `webhookSecret.orElse(null)`. */
- fun webhookSecret(webhookSecret: Optional) =
- webhookSecret(webhookSecret.getOrNull())
-
fun fromEnv() = apply { clientOptions.fromEnv() }
/**
@@ -194,7 +251,15 @@ class OpenAIOkHttpClient private constructor() {
fun build(): OpenAIClient =
OpenAIClientImpl(
clientOptions
- .httpClient(OkHttpClient.builder().timeout(timeout).proxy(proxy).build())
+ .httpClient(
+ OkHttpClient.builder()
+ .timeout(clientOptions.timeout())
+ .proxy(proxy)
+ .sslSocketFactory(sslSocketFactory)
+ .trustManager(trustManager)
+ .hostnameVerifier(hostnameVerifier)
+ .build()
+ )
.build()
)
}
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 ad00f0d90..06f5af79b 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
@@ -10,12 +10,16 @@ import com.openai.core.ClientOptions
import com.openai.core.Timeout
import com.openai.core.http.Headers
import com.openai.core.http.QueryParams
+import com.openai.core.jsonMapper
import com.openai.credential.Credential
import java.net.Proxy
import java.time.Clock
import java.time.Duration
import java.util.Optional
import java.util.concurrent.Executor
+import javax.net.ssl.HostnameVerifier
+import javax.net.ssl.SSLSocketFactory
+import javax.net.ssl.X509TrustManager
import kotlin.jvm.optionals.getOrNull
class OpenAIOkHttpClientAsync private constructor() {
@@ -32,10 +36,63 @@ class OpenAIOkHttpClientAsync private constructor() {
class Builder internal constructor() {
private var clientOptions: ClientOptions.Builder = ClientOptions.builder()
- private var timeout: Timeout = Timeout.default()
private var proxy: Proxy? = null
+ private var sslSocketFactory: SSLSocketFactory? = null
+ private var trustManager: X509TrustManager? = null
+ private var hostnameVerifier: HostnameVerifier? = null
- fun baseUrl(baseUrl: String) = apply { clientOptions.baseUrl(baseUrl) }
+ fun proxy(proxy: Proxy?) = apply { this.proxy = proxy }
+
+ /** Alias for calling [Builder.proxy] with `proxy.orElse(null)`. */
+ fun proxy(proxy: Optional) = proxy(proxy.getOrNull())
+
+ /**
+ * The socket factory used to secure HTTPS connections.
+ *
+ * If this is set, then [trustManager] must also be set.
+ *
+ * If unset, then the system default is used. Most applications should not call this method,
+ * and instead use the system default. The default include special optimizations that can be
+ * lost if the implementation is modified.
+ */
+ fun sslSocketFactory(sslSocketFactory: SSLSocketFactory?) = apply {
+ this.sslSocketFactory = sslSocketFactory
+ }
+
+ /** Alias for calling [Builder.sslSocketFactory] with `sslSocketFactory.orElse(null)`. */
+ fun sslSocketFactory(sslSocketFactory: Optional) =
+ sslSocketFactory(sslSocketFactory.getOrNull())
+
+ /**
+ * The trust manager used to secure HTTPS connections.
+ *
+ * If this is set, then [sslSocketFactory] must also be set.
+ *
+ * If unset, then the system default is used. Most applications should not call this method,
+ * and instead use the system default. The default include special optimizations that can be
+ * lost if the implementation is modified.
+ */
+ fun trustManager(trustManager: X509TrustManager?) = apply {
+ this.trustManager = trustManager
+ }
+
+ /** Alias for calling [Builder.trustManager] with `trustManager.orElse(null)`. */
+ fun trustManager(trustManager: Optional) =
+ trustManager(trustManager.getOrNull())
+
+ /**
+ * The verifier used to confirm that response certificates apply to requested hostnames for
+ * HTTPS connections.
+ *
+ * If unset, then a default hostname verifier is used.
+ */
+ fun hostnameVerifier(hostnameVerifier: HostnameVerifier?) = apply {
+ this.hostnameVerifier = hostnameVerifier
+ }
+
+ /** Alias for calling [Builder.hostnameVerifier] with `hostnameVerifier.orElse(null)`. */
+ fun hostnameVerifier(hostnameVerifier: Optional) =
+ hostnameVerifier(hostnameVerifier.getOrNull())
/**
* Whether to throw an exception if any of the Jackson versions detected at runtime are
@@ -56,6 +113,54 @@ class OpenAIOkHttpClientAsync private constructor() {
fun clock(clock: Clock) = apply { clientOptions.clock(clock) }
+ fun baseUrl(baseUrl: String?) = apply { clientOptions.baseUrl(baseUrl) }
+
+ /** Alias for calling [Builder.baseUrl] with `baseUrl.orElse(null)`. */
+ fun baseUrl(baseUrl: Optional) = baseUrl(baseUrl.getOrNull())
+
+ fun responseValidation(responseValidation: Boolean) = apply {
+ clientOptions.responseValidation(responseValidation)
+ }
+
+ fun timeout(timeout: Timeout) = apply { clientOptions.timeout(timeout) }
+
+ /**
+ * Sets the maximum time allowed for a complete HTTP call, not including retries.
+ *
+ * See [Timeout.request] for more details.
+ *
+ * For fine-grained control, pass a [Timeout] object.
+ */
+ fun timeout(timeout: Duration) = apply { clientOptions.timeout(timeout) }
+
+ fun maxRetries(maxRetries: Int) = apply { clientOptions.maxRetries(maxRetries) }
+
+ fun apiKey(apiKey: String) = apply { clientOptions.apiKey(apiKey) }
+
+ fun credential(credential: Credential) = apply { clientOptions.credential(credential) }
+
+ fun azureServiceVersion(azureServiceVersion: AzureOpenAIServiceVersion) = apply {
+ clientOptions.azureServiceVersion(azureServiceVersion)
+ }
+
+ fun organization(organization: String?) = apply { clientOptions.organization(organization) }
+
+ /** Alias for calling [Builder.organization] with `organization.orElse(null)`. */
+ fun organization(organization: Optional) = organization(organization.getOrNull())
+
+ fun project(project: String?) = apply { clientOptions.project(project) }
+
+ /** Alias for calling [Builder.project] with `project.orElse(null)`. */
+ fun project(project: Optional) = project(project.getOrNull())
+
+ fun webhookSecret(webhookSecret: String?) = apply {
+ clientOptions.webhookSecret(webhookSecret)
+ }
+
+ /** Alias for calling [Builder.webhookSecret] with `webhookSecret.orElse(null)`. */
+ fun webhookSecret(webhookSecret: Optional) =
+ webhookSecret(webhookSecret.getOrNull())
+
fun headers(headers: Headers) = apply { clientOptions.headers(headers) }
fun headers(headers: Map>) = apply {
@@ -136,54 +241,6 @@ class OpenAIOkHttpClientAsync private constructor() {
clientOptions.removeAllQueryParams(keys)
}
- fun timeout(timeout: Timeout) = apply {
- clientOptions.timeout(timeout)
- this.timeout = timeout
- }
-
- /**
- * Sets the maximum time allowed for a complete HTTP call, not including retries.
- *
- * See [Timeout.request] for more details.
- *
- * For fine-grained control, pass a [Timeout] object.
- */
- fun timeout(timeout: Duration) = timeout(Timeout.builder().request(timeout).build())
-
- fun maxRetries(maxRetries: Int) = apply { clientOptions.maxRetries(maxRetries) }
-
- fun proxy(proxy: Proxy) = apply { this.proxy = proxy }
-
- fun responseValidation(responseValidation: Boolean) = apply {
- clientOptions.responseValidation(responseValidation)
- }
-
- fun apiKey(apiKey: String) = apply { clientOptions.apiKey(apiKey) }
-
- fun credential(credential: Credential) = apply { clientOptions.credential(credential) }
-
- fun azureServiceVersion(azureServiceVersion: AzureOpenAIServiceVersion) = apply {
- clientOptions.azureServiceVersion(azureServiceVersion)
- }
-
- fun organization(organization: String?) = apply { clientOptions.organization(organization) }
-
- /** Alias for calling [Builder.organization] with `organization.orElse(null)`. */
- fun organization(organization: Optional) = organization(organization.getOrNull())
-
- fun project(project: String?) = apply { clientOptions.project(project) }
-
- /** Alias for calling [Builder.project] with `project.orElse(null)`. */
- fun project(project: Optional) = project(project.getOrNull())
-
- fun webhookSecret(webhookSecret: String?) = apply {
- clientOptions.webhookSecret(webhookSecret)
- }
-
- /** Alias for calling [Builder.webhookSecret] with `webhookSecret.orElse(null)`. */
- fun webhookSecret(webhookSecret: Optional) =
- webhookSecret(webhookSecret.getOrNull())
-
fun fromEnv() = apply { clientOptions.fromEnv() }
/**
@@ -194,7 +251,15 @@ class OpenAIOkHttpClientAsync private constructor() {
fun build(): OpenAIClientAsync =
OpenAIClientAsyncImpl(
clientOptions
- .httpClient(OkHttpClient.builder().timeout(timeout).proxy(proxy).build())
+ .httpClient(
+ OkHttpClient.builder()
+ .timeout(clientOptions.timeout())
+ .proxy(proxy)
+ .sslSocketFactory(sslSocketFactory)
+ .trustManager(trustManager)
+ .hostnameVerifier(hostnameVerifier)
+ .build()
+ )
.build()
)
}
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 9e1255072..cf847f31f 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
@@ -13,6 +13,7 @@ import com.openai.core.http.RetryingHttpClient
import com.openai.credential.BearerTokenCredential
import com.openai.credential.Credential
import java.time.Clock
+import java.time.Duration
import java.util.Optional
import java.util.concurrent.Executor
import java.util.concurrent.Executors
@@ -24,6 +25,13 @@ class ClientOptions
private constructor(
private val originalHttpClient: HttpClient,
@get:JvmName("httpClient") val httpClient: HttpClient,
+ /**
+ * Whether to throw an exception if any of the Jackson versions detected at runtime are
+ * incompatible with the SDK's minimum supported Jackson version (2.13.4).
+ *
+ * Defaults to true. Use extreme caution when disabling this option. There is no guarantee that
+ * the SDK will work correctly when using an incompatible Jackson version.
+ */
@get:JvmName("checkJacksonVersionCompatibility") val checkJacksonVersionCompatibility: Boolean,
@get:JvmName("jsonMapper") val jsonMapper: JsonMapper,
@get:JvmName("streamHandlerExecutor") val streamHandlerExecutor: Executor,
@@ -119,6 +127,13 @@ private constructor(
this.httpClient = PhantomReachableClosingHttpClient(httpClient)
}
+ /**
+ * Whether to throw an exception if any of the Jackson versions detected at runtime are
+ * incompatible with the SDK's minimum supported Jackson version (2.13.4).
+ *
+ * Defaults to true. Use extreme caution when disabling this option. There is no guarantee
+ * that the SDK will work correctly when using an incompatible Jackson version.
+ */
fun checkJacksonVersionCompatibility(checkJacksonVersionCompatibility: Boolean) = apply {
this.checkJacksonVersionCompatibility = checkJacksonVersionCompatibility
}
@@ -142,6 +157,15 @@ private constructor(
fun timeout(timeout: Timeout) = apply { this.timeout = timeout }
+ /**
+ * Sets the maximum time allowed for a complete HTTP call, not including retries.
+ *
+ * See [Timeout.request] for more details.
+ *
+ * For fine-grained control, pass a [Timeout] object.
+ */
+ fun timeout(timeout: Duration) = timeout(Timeout.builder().request(timeout).build())
+
fun maxRetries(maxRetries: Int) = apply { this.maxRetries = maxRetries }
fun apiKey(apiKey: String) = apply {
@@ -250,6 +274,8 @@ private constructor(
fun removeAllQueryParams(keys: Set) = apply { queryParams.removeAll(keys) }
+ fun timeout(): Timeout = timeout
+
fun fromEnv() = apply {
System.getenv("OPENAI_BASE_URL")?.let { baseUrl(it) }
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/audio/transcriptions/TranscriptionCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/audio/transcriptions/TranscriptionCreateParams.kt
index 226cf34aa..29712039c 100644
--- a/openai-java-core/src/main/kotlin/com/openai/models/audio/transcriptions/TranscriptionCreateParams.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/models/audio/transcriptions/TranscriptionCreateParams.kt
@@ -209,6 +209,8 @@ private constructor(
fun _timestampGranularities(): MultipartField> =
body._timestampGranularities()
+ fun _additionalBodyProperties(): Map = body._additionalProperties()
+
fun _additionalHeaders(): Headers = additionalHeaders
fun _additionalQueryParams(): QueryParams = additionalQueryParams
@@ -466,6 +468,25 @@ private constructor(
body.addTimestampGranularity(timestampGranularity)
}
+ 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)
@@ -586,7 +607,7 @@ private constructor(
}
fun _body(): Map> =
- mapOf(
+ (mapOf(
"file" to _file(),
"model" to _model(),
"chunking_strategy" to _chunkingStrategy(),
@@ -596,7 +617,7 @@ private constructor(
"response_format" to _responseFormat(),
"temperature" to _temperature(),
"timestamp_granularities" to _timestampGranularities(),
- )
+ ) + _additionalBodyProperties().mapValues { MultipartField.of(it) })
.toImmutable()
override fun _headers(): Headers = additionalHeaders
@@ -614,6 +635,7 @@ private constructor(
private val responseFormat: MultipartField,
private val temperature: MultipartField,
private val timestampGranularities: MultipartField>,
+ private val additionalProperties: MutableMap,
) {
/**
@@ -792,6 +814,16 @@ private constructor(
fun _timestampGranularities(): MultipartField> =
timestampGranularities
+ @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 {
@@ -822,6 +854,7 @@ private constructor(
private var temperature: MultipartField = MultipartField.of(null)
private var timestampGranularities: MultipartField>? =
null
+ private var additionalProperties: MutableMap = mutableMapOf()
@JvmSynthetic
internal fun from(body: Body) = apply {
@@ -834,6 +867,7 @@ private constructor(
responseFormat = body.responseFormat
temperature = body.temperature
timestampGranularities = body.timestampGranularities.map { it.toMutableList() }
+ additionalProperties = body.additionalProperties.toMutableMap()
}
/**
@@ -1065,6 +1099,25 @@ private constructor(
}
}
+ 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].
*
@@ -1089,6 +1142,7 @@ private constructor(
responseFormat,
temperature,
(timestampGranularities ?: MultipartField.of(null)).map { it.toImmutable() },
+ additionalProperties.toMutableMap(),
)
}
@@ -1124,17 +1178,17 @@ private constructor(
return true
}
- return /* spotless:off */ other is Body && file == other.file && model == other.model && chunkingStrategy == other.chunkingStrategy && include == other.include && language == other.language && prompt == other.prompt && responseFormat == other.responseFormat && temperature == other.temperature && timestampGranularities == other.timestampGranularities /* spotless:on */
+ return /* spotless:off */ other is Body && file == other.file && model == other.model && chunkingStrategy == other.chunkingStrategy && include == other.include && language == other.language && prompt == other.prompt && responseFormat == other.responseFormat && temperature == other.temperature && timestampGranularities == other.timestampGranularities && additionalProperties == other.additionalProperties /* spotless:on */
}
/* spotless:off */
- private val hashCode: Int by lazy { Objects.hash(file, model, chunkingStrategy, include, language, prompt, responseFormat, temperature, timestampGranularities) }
+ private val hashCode: Int by lazy { Objects.hash(file, model, chunkingStrategy, include, language, prompt, responseFormat, temperature, timestampGranularities, additionalProperties) }
/* spotless:on */
override fun hashCode(): Int = hashCode
override fun toString() =
- "Body{file=$file, model=$model, chunkingStrategy=$chunkingStrategy, include=$include, language=$language, prompt=$prompt, responseFormat=$responseFormat, temperature=$temperature, timestampGranularities=$timestampGranularities}"
+ "Body{file=$file, model=$model, chunkingStrategy=$chunkingStrategy, include=$include, language=$language, prompt=$prompt, responseFormat=$responseFormat, temperature=$temperature, timestampGranularities=$timestampGranularities, additionalProperties=$additionalProperties}"
}
/**
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/audio/translations/TranslationCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/audio/translations/TranslationCreateParams.kt
index 7ce0911de..2ee019505 100644
--- a/openai-java-core/src/main/kotlin/com/openai/models/audio/translations/TranslationCreateParams.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/models/audio/translations/TranslationCreateParams.kt
@@ -2,11 +2,14 @@
package com.openai.models.audio.translations
+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.JsonValue
import com.openai.core.MultipartField
import com.openai.core.Params
import com.openai.core.checkRequired
@@ -17,6 +20,7 @@ import com.openai.errors.OpenAIInvalidDataException
import com.openai.models.audio.AudioModel
import java.io.InputStream
import java.nio.file.Path
+import java.util.Collections
import java.util.Objects
import java.util.Optional
import kotlin.io.path.inputStream
@@ -115,6 +119,8 @@ private constructor(
*/
fun _temperature(): MultipartField = body._temperature()
+ fun _additionalBodyProperties(): Map = body._additionalProperties()
+
fun _additionalHeaders(): Headers = additionalHeaders
fun _additionalQueryParams(): QueryParams = additionalQueryParams
@@ -267,6 +273,25 @@ private constructor(
body.temperature(temperature)
}
+ 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)
@@ -387,13 +412,13 @@ private constructor(
}
fun _body(): Map> =
- mapOf(
+ (mapOf(
"file" to _file(),
"model" to _model(),
"prompt" to _prompt(),
"response_format" to _responseFormat(),
"temperature" to _temperature(),
- )
+ ) + _additionalBodyProperties().mapValues { MultipartField.of(it) })
.toImmutable()
override fun _headers(): Headers = additionalHeaders
@@ -407,6 +432,7 @@ private constructor(
private val prompt: MultipartField,
private val responseFormat: MultipartField,
private val temperature: MultipartField,
+ private val additionalProperties: MutableMap,
) {
/**
@@ -500,6 +526,16 @@ private constructor(
@ExcludeMissing
fun _temperature(): MultipartField = temperature
+ @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 {
@@ -524,6 +560,7 @@ private constructor(
private var prompt: MultipartField = MultipartField.of(null)
private var responseFormat: MultipartField = MultipartField.of(null)
private var temperature: MultipartField = MultipartField.of(null)
+ private var additionalProperties: MutableMap = mutableMapOf()
@JvmSynthetic
internal fun from(body: Body) = apply {
@@ -532,6 +569,7 @@ private constructor(
prompt = body.prompt
responseFormat = body.responseFormat
temperature = body.temperature
+ additionalProperties = body.additionalProperties.toMutableMap()
}
/**
@@ -645,6 +683,25 @@ private constructor(
this.temperature = temperature
}
+ 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].
*
@@ -665,6 +722,7 @@ private constructor(
prompt,
responseFormat,
temperature,
+ additionalProperties.toMutableMap(),
)
}
@@ -696,17 +754,17 @@ private constructor(
return true
}
- return /* spotless:off */ other is Body && file == other.file && model == other.model && prompt == other.prompt && responseFormat == other.responseFormat && temperature == other.temperature /* spotless:on */
+ return /* spotless:off */ other is Body && file == other.file && model == other.model && prompt == other.prompt && responseFormat == other.responseFormat && temperature == other.temperature && additionalProperties == other.additionalProperties /* spotless:on */
}
/* spotless:off */
- private val hashCode: Int by lazy { Objects.hash(file, model, prompt, responseFormat, temperature) }
+ private val hashCode: Int by lazy { Objects.hash(file, model, prompt, responseFormat, temperature, additionalProperties) }
/* spotless:on */
override fun hashCode(): Int = hashCode
override fun toString() =
- "Body{file=$file, model=$model, prompt=$prompt, responseFormat=$responseFormat, temperature=$temperature}"
+ "Body{file=$file, model=$model, prompt=$prompt, responseFormat=$responseFormat, temperature=$temperature, additionalProperties=$additionalProperties}"
}
/**
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/containers/files/FileCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/containers/files/FileCreateParams.kt
index 4d0db6859..d41db32ef 100644
--- a/openai-java-core/src/main/kotlin/com/openai/models/containers/files/FileCreateParams.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/models/containers/files/FileCreateParams.kt
@@ -2,8 +2,11 @@
package com.openai.models.containers.files
+import com.fasterxml.jackson.annotation.JsonAnyGetter
+import com.fasterxml.jackson.annotation.JsonAnySetter
import com.fasterxml.jackson.annotation.JsonProperty
import com.openai.core.ExcludeMissing
+import com.openai.core.JsonValue
import com.openai.core.MultipartField
import com.openai.core.Params
import com.openai.core.http.Headers
@@ -12,6 +15,7 @@ import com.openai.core.toImmutable
import com.openai.errors.OpenAIInvalidDataException
import java.io.InputStream
import java.nio.file.Path
+import java.util.Collections
import java.util.Objects
import java.util.Optional
import kotlin.io.path.inputStream
@@ -64,6 +68,8 @@ private constructor(
*/
fun _fileId(): MultipartField = body._fileId()
+ fun _additionalBodyProperties(): Map = body._additionalProperties()
+
fun _additionalHeaders(): Headers = additionalHeaders
fun _additionalQueryParams(): QueryParams = additionalQueryParams
@@ -138,6 +144,25 @@ private constructor(
*/
fun fileId(fileId: MultipartField) = apply { body.fileId(fileId) }
+ 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)
@@ -251,7 +276,9 @@ private constructor(
}
fun _body(): Map> =
- mapOf("file" to _file(), "file_id" to _fileId()).toImmutable()
+ (mapOf("file" to _file(), "file_id" to _fileId()) +
+ _additionalBodyProperties().mapValues { MultipartField.of(it) })
+ .toImmutable()
fun _pathParam(index: Int): String =
when (index) {
@@ -267,6 +294,7 @@ private constructor(
private constructor(
private val file: MultipartField,
private val fileId: MultipartField,
+ private val additionalProperties: MutableMap,
) {
/**
@@ -299,6 +327,16 @@ private constructor(
*/
@JsonProperty("file_id") @ExcludeMissing fun _fileId(): MultipartField = fileId
+ @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 {
@@ -312,11 +350,13 @@ private constructor(
private var file: MultipartField = MultipartField.of(null)
private var fileId: MultipartField = MultipartField.of(null)
+ private var additionalProperties: MutableMap = mutableMapOf()
@JvmSynthetic
internal fun from(body: Body) = apply {
file = body.file
fileId = body.fileId
+ additionalProperties = body.additionalProperties.toMutableMap()
}
/** The File object (not file name) to be uploaded. */
@@ -355,12 +395,31 @@ private constructor(
*/
fun fileId(fileId: MultipartField) = apply { this.fileId = fileId }
+ 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(file, fileId)
+ fun build(): Body = Body(file, fileId, additionalProperties.toMutableMap())
}
private var validated: Boolean = false
@@ -388,16 +447,17 @@ private constructor(
return true
}
- return /* spotless:off */ other is Body && file == other.file && fileId == other.fileId /* spotless:on */
+ return /* spotless:off */ other is Body && file == other.file && fileId == other.fileId && additionalProperties == other.additionalProperties /* spotless:on */
}
/* spotless:off */
- private val hashCode: Int by lazy { Objects.hash(file, fileId) }
+ private val hashCode: Int by lazy { Objects.hash(file, fileId, additionalProperties) }
/* spotless:on */
override fun hashCode(): Int = hashCode
- override fun toString() = "Body{file=$file, fileId=$fileId}"
+ override fun toString() =
+ "Body{file=$file, fileId=$fileId, additionalProperties=$additionalProperties}"
}
override fun equals(other: Any?): Boolean {
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/files/FileCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/files/FileCreateParams.kt
index b87982873..d91219f9e 100644
--- a/openai-java-core/src/main/kotlin/com/openai/models/files/FileCreateParams.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/models/files/FileCreateParams.kt
@@ -2,8 +2,11 @@
package com.openai.models.files
+import com.fasterxml.jackson.annotation.JsonAnyGetter
+import com.fasterxml.jackson.annotation.JsonAnySetter
import com.fasterxml.jackson.annotation.JsonProperty
import com.openai.core.ExcludeMissing
+import com.openai.core.JsonValue
import com.openai.core.MultipartField
import com.openai.core.Params
import com.openai.core.checkRequired
@@ -13,6 +16,7 @@ import com.openai.core.toImmutable
import com.openai.errors.OpenAIInvalidDataException
import java.io.InputStream
import java.nio.file.Path
+import java.util.Collections
import java.util.Objects
import kotlin.io.path.inputStream
import kotlin.io.path.name
@@ -74,6 +78,8 @@ private constructor(
*/
fun _purpose(): MultipartField = body._purpose()
+ fun _additionalBodyProperties(): Map = body._additionalProperties()
+
fun _additionalHeaders(): Headers = additionalHeaders
fun _additionalQueryParams(): QueryParams = additionalQueryParams
@@ -153,6 +159,25 @@ private constructor(
*/
fun purpose(purpose: MultipartField) = apply { body.purpose(purpose) }
+ 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)
@@ -269,7 +294,9 @@ private constructor(
}
fun _body(): Map> =
- mapOf("file" to _file(), "purpose" to _purpose()).toImmutable()
+ (mapOf("file" to _file(), "purpose" to _purpose()) +
+ _additionalBodyProperties().mapValues { MultipartField.of(it) })
+ .toImmutable()
override fun _headers(): Headers = additionalHeaders
@@ -279,6 +306,7 @@ private constructor(
private constructor(
private val file: MultipartField,
private val purpose: MultipartField,
+ private val additionalProperties: MutableMap,
) {
/**
@@ -317,6 +345,16 @@ private constructor(
@ExcludeMissing
fun _purpose(): MultipartField = purpose
+ @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 {
@@ -338,11 +376,13 @@ private constructor(
private var file: MultipartField? = null
private var purpose: MultipartField? = null
+ private var additionalProperties: MutableMap = mutableMapOf()
@JvmSynthetic
internal fun from(body: Body) = apply {
file = body.file
purpose = body.purpose
+ additionalProperties = body.additionalProperties.toMutableMap()
}
/** The File object (not file name) to be uploaded. */
@@ -386,6 +426,25 @@ private constructor(
*/
fun purpose(purpose: MultipartField) = apply { this.purpose = purpose }
+ 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].
*
@@ -399,7 +458,12 @@ private constructor(
*
* @throws IllegalStateException if any required field is unset.
*/
- fun build(): Body = Body(checkRequired("file", file), checkRequired("purpose", purpose))
+ fun build(): Body =
+ Body(
+ checkRequired("file", file),
+ checkRequired("purpose", purpose),
+ additionalProperties.toMutableMap(),
+ )
}
private var validated: Boolean = false
@@ -427,16 +491,17 @@ private constructor(
return true
}
- return /* spotless:off */ other is Body && file == other.file && purpose == other.purpose /* spotless:on */
+ return /* spotless:off */ other is Body && file == other.file && purpose == other.purpose && additionalProperties == other.additionalProperties /* spotless:on */
}
/* spotless:off */
- private val hashCode: Int by lazy { Objects.hash(file, purpose) }
+ private val hashCode: Int by lazy { Objects.hash(file, purpose, additionalProperties) }
/* spotless:on */
override fun hashCode(): Int = hashCode
- override fun toString() = "Body{file=$file, purpose=$purpose}"
+ override fun toString() =
+ "Body{file=$file, purpose=$purpose, additionalProperties=$additionalProperties}"
}
override fun equals(other: Any?): Boolean {
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/images/ImageCreateVariationParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/images/ImageCreateVariationParams.kt
index 66d53a78a..4091857d6 100644
--- a/openai-java-core/src/main/kotlin/com/openai/models/images/ImageCreateVariationParams.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/models/images/ImageCreateVariationParams.kt
@@ -2,11 +2,14 @@
package com.openai.models.images
+import com.fasterxml.jackson.annotation.JsonAnyGetter
+import com.fasterxml.jackson.annotation.JsonAnySetter
import com.fasterxml.jackson.annotation.JsonCreator
import com.fasterxml.jackson.annotation.JsonProperty
import com.openai.core.Enum
import com.openai.core.ExcludeMissing
import com.openai.core.JsonField
+import com.openai.core.JsonValue
import com.openai.core.MultipartField
import com.openai.core.Params
import com.openai.core.checkRequired
@@ -16,6 +19,7 @@ import com.openai.core.toImmutable
import com.openai.errors.OpenAIInvalidDataException
import java.io.InputStream
import java.nio.file.Path
+import java.util.Collections
import java.util.Objects
import java.util.Optional
import kotlin.io.path.inputStream
@@ -125,6 +129,8 @@ private constructor(
*/
fun _user(): MultipartField = body._user()
+ fun _additionalBodyProperties(): Map = body._additionalProperties()
+
fun _additionalHeaders(): Headers = additionalHeaders
fun _additionalQueryParams(): QueryParams = additionalQueryParams
@@ -297,6 +303,25 @@ private constructor(
*/
fun user(user: MultipartField) = apply { body.user(user) }
+ 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)
@@ -416,14 +441,14 @@ private constructor(
}
fun _body(): Map> =
- mapOf(
+ (mapOf(
"image" to _image(),
"model" to _model(),
"n" to _n(),
"response_format" to _responseFormat(),
"size" to _size(),
"user" to _user(),
- )
+ ) + _additionalBodyProperties().mapValues { MultipartField.of(it) })
.toImmutable()
override fun _headers(): Headers = additionalHeaders
@@ -438,6 +463,7 @@ private constructor(
private val responseFormat: MultipartField,
private val size: MultipartField,
private val user: MultipartField,
+ private val additionalProperties: MutableMap,
) {
/**
@@ -538,6 +564,16 @@ private constructor(
*/
@JsonProperty("user") @ExcludeMissing fun _user(): MultipartField = user
+ @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 {
@@ -562,6 +598,7 @@ private constructor(
private var responseFormat: MultipartField = MultipartField.of(null)
private var size: MultipartField = MultipartField.of(null)
private var user: MultipartField = MultipartField.of(null)
+ private var additionalProperties: MutableMap = mutableMapOf()
@JvmSynthetic
internal fun from(body: Body) = apply {
@@ -571,6 +608,7 @@ private constructor(
responseFormat = body.responseFormat
size = body.size
user = body.user
+ additionalProperties = body.additionalProperties.toMutableMap()
}
/**
@@ -708,6 +746,25 @@ private constructor(
*/
fun user(user: MultipartField) = apply { this.user = user }
+ 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].
*
@@ -721,7 +778,15 @@ private constructor(
* @throws IllegalStateException if any required field is unset.
*/
fun build(): Body =
- Body(checkRequired("image", image), model, n, responseFormat, size, user)
+ Body(
+ checkRequired("image", image),
+ model,
+ n,
+ responseFormat,
+ size,
+ user,
+ additionalProperties.toMutableMap(),
+ )
}
private var validated: Boolean = false
@@ -753,17 +818,17 @@ private constructor(
return true
}
- return /* spotless:off */ other is Body && image == other.image && model == other.model && n == other.n && responseFormat == other.responseFormat && size == other.size && user == other.user /* spotless:on */
+ return /* spotless:off */ other is Body && image == other.image && model == other.model && n == other.n && responseFormat == other.responseFormat && size == other.size && user == other.user && additionalProperties == other.additionalProperties /* spotless:on */
}
/* spotless:off */
- private val hashCode: Int by lazy { Objects.hash(image, model, n, responseFormat, size, user) }
+ private val hashCode: Int by lazy { Objects.hash(image, model, n, responseFormat, size, user, additionalProperties) }
/* spotless:on */
override fun hashCode(): Int = hashCode
override fun toString() =
- "Body{image=$image, model=$model, n=$n, responseFormat=$responseFormat, size=$size, user=$user}"
+ "Body{image=$image, model=$model, n=$n, responseFormat=$responseFormat, size=$size, user=$user, additionalProperties=$additionalProperties}"
}
/**
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/images/ImageEditParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/images/ImageEditParams.kt
index 6872d5eeb..18fe5c9d3 100644
--- a/openai-java-core/src/main/kotlin/com/openai/models/images/ImageEditParams.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/models/images/ImageEditParams.kt
@@ -2,6 +2,8 @@
package com.openai.models.images
+import com.fasterxml.jackson.annotation.JsonAnyGetter
+import com.fasterxml.jackson.annotation.JsonAnySetter
import com.fasterxml.jackson.annotation.JsonCreator
import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.core.JsonGenerator
@@ -28,6 +30,7 @@ import com.openai.core.toImmutable
import com.openai.errors.OpenAIInvalidDataException
import java.io.InputStream
import java.nio.file.Path
+import java.util.Collections
import java.util.Objects
import java.util.Optional
import kotlin.io.path.inputStream
@@ -290,6 +293,8 @@ private constructor(
*/
fun _user(): MultipartField = body._user()
+ fun _additionalBodyProperties(): Map = body._additionalProperties()
+
fun _additionalHeaders(): Headers = additionalHeaders
fun _additionalQueryParams(): QueryParams = additionalQueryParams
@@ -686,6 +691,25 @@ private constructor(
*/
fun user(user: MultipartField) = apply { body.user(user) }
+ 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)
@@ -802,7 +826,7 @@ private constructor(
}
fun _body(): Map> =
- mapOf(
+ (mapOf(
"image" to _image(),
"prompt" to _prompt(),
"background" to _background(),
@@ -817,7 +841,7 @@ private constructor(
"response_format" to _responseFormat(),
"size" to _size(),
"user" to _user(),
- )
+ ) + _additionalBodyProperties().mapValues { MultipartField.of(it) })
.toImmutable()
override fun _headers(): Headers = additionalHeaders
@@ -840,6 +864,7 @@ private constructor(
private val responseFormat: MultipartField,
private val size: MultipartField,
private val user: MultipartField,
+ private val additionalProperties: MutableMap,
) {
/**
@@ -1106,6 +1131,16 @@ private constructor(
*/
@JsonProperty("user") @ExcludeMissing fun _user(): MultipartField = user
+ @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 {
@@ -1139,6 +1174,7 @@ private constructor(
private var responseFormat: MultipartField = MultipartField.of(null)
private var size: MultipartField = MultipartField.of(null)
private var user: MultipartField = MultipartField.of(null)
+ private var additionalProperties: MutableMap = mutableMapOf()
@JvmSynthetic
internal fun from(body: Body) = apply {
@@ -1156,6 +1192,7 @@ private constructor(
responseFormat = body.responseFormat
size = body.size
user = body.user
+ additionalProperties = body.additionalProperties.toMutableMap()
}
/**
@@ -1529,6 +1566,25 @@ private constructor(
*/
fun user(user: MultipartField) = apply { this.user = user }
+ 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].
*
@@ -1558,6 +1614,7 @@ private constructor(
responseFormat,
size,
user,
+ additionalProperties.toMutableMap(),
)
}
@@ -1598,17 +1655,17 @@ private constructor(
return true
}
- return /* spotless:off */ other is Body && image == other.image && prompt == other.prompt && background == other.background && inputFidelity == other.inputFidelity && mask == other.mask && model == other.model && n == other.n && outputCompression == other.outputCompression && outputFormat == other.outputFormat && partialImages == other.partialImages && quality == other.quality && responseFormat == other.responseFormat && size == other.size && user == other.user /* spotless:on */
+ return /* spotless:off */ other is Body && image == other.image && prompt == other.prompt && background == other.background && inputFidelity == other.inputFidelity && mask == other.mask && model == other.model && n == other.n && outputCompression == other.outputCompression && outputFormat == other.outputFormat && partialImages == other.partialImages && quality == other.quality && responseFormat == other.responseFormat && size == other.size && user == other.user && additionalProperties == other.additionalProperties /* spotless:on */
}
/* spotless:off */
- private val hashCode: Int by lazy { Objects.hash(image, prompt, background, inputFidelity, mask, model, n, outputCompression, outputFormat, partialImages, quality, responseFormat, size, user) }
+ private val hashCode: Int by lazy { Objects.hash(image, prompt, background, inputFidelity, mask, model, n, outputCompression, outputFormat, partialImages, quality, responseFormat, size, user, additionalProperties) }
/* spotless:on */
override fun hashCode(): Int = hashCode
override fun toString() =
- "Body{image=$image, prompt=$prompt, background=$background, inputFidelity=$inputFidelity, mask=$mask, model=$model, n=$n, outputCompression=$outputCompression, outputFormat=$outputFormat, partialImages=$partialImages, quality=$quality, responseFormat=$responseFormat, size=$size, user=$user}"
+ "Body{image=$image, prompt=$prompt, background=$background, inputFidelity=$inputFidelity, mask=$mask, model=$model, n=$n, outputCompression=$outputCompression, outputFormat=$outputFormat, partialImages=$partialImages, quality=$quality, responseFormat=$responseFormat, size=$size, user=$user, additionalProperties=$additionalProperties}"
}
/**
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/uploads/parts/PartCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/uploads/parts/PartCreateParams.kt
index 791713e4f..b7cfa4761 100644
--- a/openai-java-core/src/main/kotlin/com/openai/models/uploads/parts/PartCreateParams.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/models/uploads/parts/PartCreateParams.kt
@@ -2,8 +2,11 @@
package com.openai.models.uploads.parts
+import com.fasterxml.jackson.annotation.JsonAnyGetter
+import com.fasterxml.jackson.annotation.JsonAnySetter
import com.fasterxml.jackson.annotation.JsonProperty
import com.openai.core.ExcludeMissing
+import com.openai.core.JsonValue
import com.openai.core.MultipartField
import com.openai.core.Params
import com.openai.core.checkRequired
@@ -13,6 +16,7 @@ import com.openai.core.toImmutable
import com.openai.errors.OpenAIInvalidDataException
import java.io.InputStream
import java.nio.file.Path
+import java.util.Collections
import java.util.Objects
import java.util.Optional
import kotlin.io.path.inputStream
@@ -54,6 +58,8 @@ private constructor(
*/
fun _data(): MultipartField = body._data()
+ fun _additionalBodyProperties(): Map = body._additionalProperties()
+
fun _additionalHeaders(): Headers = additionalHeaders
fun _additionalQueryParams(): QueryParams = additionalQueryParams
@@ -121,6 +127,25 @@ private constructor(
/** The chunk of bytes for this Part. */
fun data(data: Path) = apply { body.data(data) }
+ 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)
@@ -240,7 +265,9 @@ private constructor(
)
}
- fun _body(): Map> = mapOf("data" to _data()).toImmutable()
+ fun _body(): Map> =
+ (mapOf("data" to _data()) + _additionalBodyProperties().mapValues { MultipartField.of(it) })
+ .toImmutable()
fun _pathParam(index: Int): String =
when (index) {
@@ -252,7 +279,11 @@ private constructor(
override fun _queryParams(): QueryParams = additionalQueryParams
- class Body private constructor(private val data: MultipartField) {
+ class Body
+ private constructor(
+ private val data: MultipartField,
+ private val additionalProperties: MutableMap,
+ ) {
/**
* The chunk of bytes for this Part.
@@ -269,6 +300,16 @@ private constructor(
*/
@JsonProperty("data") @ExcludeMissing fun _data(): MultipartField = data
+ @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 {
@@ -288,8 +329,13 @@ private constructor(
class Builder internal constructor() {
private var data: MultipartField? = null
+ private var additionalProperties: MutableMap = mutableMapOf()
- @JvmSynthetic internal fun from(body: Body) = apply { data = body.data }
+ @JvmSynthetic
+ internal fun from(body: Body) = apply {
+ data = body.data
+ additionalProperties = body.additionalProperties.toMutableMap()
+ }
/** The chunk of bytes for this Part. */
fun data(data: InputStream) = data(MultipartField.of(data))
@@ -315,6 +361,25 @@ private constructor(
.build()
)
+ 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].
*
@@ -327,7 +392,8 @@ private constructor(
*
* @throws IllegalStateException if any required field is unset.
*/
- fun build(): Body = Body(checkRequired("data", data))
+ fun build(): Body =
+ Body(checkRequired("data", data), additionalProperties.toMutableMap())
}
private var validated: Boolean = false
@@ -354,16 +420,16 @@ private constructor(
return true
}
- return /* spotless:off */ other is Body && data == other.data /* spotless:on */
+ return /* spotless:off */ other is Body && data == other.data && additionalProperties == other.additionalProperties /* spotless:on */
}
/* spotless:off */
- private val hashCode: Int by lazy { Objects.hash(data) }
+ private val hashCode: Int by lazy { Objects.hash(data, additionalProperties) }
/* spotless:on */
override fun hashCode(): Int = hashCode
- override fun toString() = "Body{data=$data}"
+ override fun toString() = "Body{data=$data, additionalProperties=$additionalProperties}"
}
override fun equals(other: Any?): Boolean {