diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 52afe059..fe87cd91 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.42.0"
+ ".": "0.43.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index 1f1a1736..b80d385d 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 80
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-4bce8217a697c729ac98046d4caf2c9e826b54c427fb0ab4f98e549a2e0ce31c.yml
openapi_spec_hash: 7996d2c34cc44fe2ce9ffe93c0ab774e
-config_hash: 178ba1bfb1237bf6b94abb3408072aa7
+config_hash: 578c5bff4208d560c0c280f13324409f
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d05d1214..920a70bb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,19 @@
# Changelog
+## 0.43.0 (2025-04-02)
+
+Full Changelog: [v0.42.0...v0.43.0](https://github.com/openai/openai-java/compare/v0.42.0...v0.43.0)
+
+### Features
+
+* **api:** manual updates ([9679525](https://github.com/openai/openai-java/commit/967952553d5fd2e7f47cd7c82fac45cc9dcef43e))
+* **client:** expose request body setter and getter ([#392](https://github.com/openai/openai-java/issues/392)) ([eaa0bc9](https://github.com/openai/openai-java/commit/eaa0bc96ba8898e064709a571e97d6b99f478597))
+
+
+### Chores
+
+* **internal:** codegen related update ([#389](https://github.com/openai/openai-java/issues/389)) ([b0e9d31](https://github.com/openai/openai-java/commit/b0e9d316bde7866f0d6c9381a5bec5a6667f46f6))
+
## 0.42.0 (2025-04-02)
Full Changelog: [v0.41.1...v0.42.0](https://github.com/openai/openai-java/compare/v0.41.1...v0.42.0)
diff --git a/README.md b/README.md
index f1d9f7ba..ea25d2d2 100644
--- a/README.md
+++ b/README.md
@@ -9,8 +9,8 @@
-[](https://central.sonatype.com/artifact/com.openai/openai-java/0.42.0)
-[](https://javadoc.io/doc/com.openai/openai-java/0.42.0)
+[](https://central.sonatype.com/artifact/com.openai/openai-java/0.43.0)
+[](https://javadoc.io/doc/com.openai/openai-java/0.43.0)
@@ -18,7 +18,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 also available on [javadoc.io](https://javadoc.io/doc/com.openai/openai-java/0.42.0).
+The REST API documentation can be found on [platform.openai.com](https://platform.openai.com/docs). Javadocs are also available on [javadoc.io](https://javadoc.io/doc/com.openai/openai-java/0.43.0).
@@ -29,7 +29,7 @@ The REST API documentation can be found on [platform.openai.com](https://platfor
### Gradle
```kotlin
-implementation("com.openai:openai-java:0.42.0")
+implementation("com.openai:openai-java:0.43.0")
```
### Maven
@@ -38,7 +38,7 @@ implementation("com.openai:openai-java:0.42.0")
com.openai
openai-java
- 0.42.0
+ 0.43.0
```
diff --git a/build.gradle.kts b/build.gradle.kts
index 12705605..9794d6c5 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -8,7 +8,7 @@ repositories {
allprojects {
group = "com.openai"
- version = "0.42.0" // x-release-please-version
+ version = "0.43.0" // x-release-please-version
}
subprojects {
diff --git a/openai-java-core/src/main/kotlin/com/openai/core/ObjectMappers.kt b/openai-java-core/src/main/kotlin/com/openai/core/ObjectMappers.kt
index 7be25df3..24bec380 100644
--- a/openai-java-core/src/main/kotlin/com/openai/core/ObjectMappers.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/core/ObjectMappers.kt
@@ -4,12 +4,16 @@ package com.openai.core
import com.fasterxml.jackson.annotation.JsonInclude
import com.fasterxml.jackson.core.JsonGenerator
+import com.fasterxml.jackson.core.JsonParseException
+import com.fasterxml.jackson.core.JsonParser
+import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.MapperFeature
import com.fasterxml.jackson.databind.SerializationFeature
import com.fasterxml.jackson.databind.SerializerProvider
import com.fasterxml.jackson.databind.cfg.CoercionAction
import com.fasterxml.jackson.databind.cfg.CoercionInputShape
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer
import com.fasterxml.jackson.databind.json.JsonMapper
import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.databind.type.LogicalType
@@ -17,13 +21,23 @@ import com.fasterxml.jackson.datatype.jdk8.Jdk8Module
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
import com.fasterxml.jackson.module.kotlin.kotlinModule
import java.io.InputStream
+import java.time.DateTimeException
+import java.time.LocalDate
+import java.time.LocalDateTime
+import java.time.ZonedDateTime
+import java.time.format.DateTimeFormatter
+import java.time.temporal.ChronoField
fun jsonMapper(): JsonMapper =
JsonMapper.builder()
.addModule(kotlinModule())
.addModule(Jdk8Module())
.addModule(JavaTimeModule())
- .addModule(SimpleModule().addSerializer(InputStreamJsonSerializer))
+ .addModule(
+ SimpleModule()
+ .addSerializer(InputStreamSerializer)
+ .addDeserializer(LocalDateTime::class.java, LenientLocalDateTimeDeserializer())
+ )
.withCoercionConfig(LogicalType.Boolean) {
it.setCoercion(CoercionInputShape.Integer, CoercionAction.Fail)
.setCoercion(CoercionInputShape.Float, CoercionAction.Fail)
@@ -91,7 +105,10 @@ fun jsonMapper(): JsonMapper =
.disable(MapperFeature.AUTO_DETECT_SETTERS)
.build()
-private object InputStreamJsonSerializer : BaseSerializer(InputStream::class) {
+/** A serializer that serializes [InputStream] to bytes. */
+private object InputStreamSerializer : BaseSerializer(InputStream::class) {
+
+ private fun readResolve(): Any = InputStreamSerializer
override fun serialize(
value: InputStream?,
@@ -105,3 +122,46 @@ private object InputStreamJsonSerializer : BaseSerializer(InputStre
}
}
}
+
+/**
+ * A deserializer that can deserialize [LocalDateTime] from datetimes, dates, and zoned datetimes.
+ */
+private class LenientLocalDateTimeDeserializer :
+ StdDeserializer(LocalDateTime::class.java) {
+
+ companion object {
+
+ private val DATE_TIME_FORMATTERS =
+ listOf(
+ DateTimeFormatter.ISO_LOCAL_DATE_TIME,
+ DateTimeFormatter.ISO_LOCAL_DATE,
+ DateTimeFormatter.ISO_ZONED_DATE_TIME,
+ )
+ }
+
+ override fun logicalType(): LogicalType = LogicalType.DateTime
+
+ override fun deserialize(p: JsonParser, context: DeserializationContext?): LocalDateTime {
+ val exceptions = mutableListOf()
+
+ for (formatter in DATE_TIME_FORMATTERS) {
+ try {
+ val temporal = formatter.parse(p.text)
+
+ return when {
+ !temporal.isSupported(ChronoField.HOUR_OF_DAY) ->
+ LocalDate.from(temporal).atStartOfDay()
+ !temporal.isSupported(ChronoField.OFFSET_SECONDS) ->
+ LocalDateTime.from(temporal)
+ else -> ZonedDateTime.from(temporal).toLocalDateTime()
+ }
+ } catch (e: DateTimeException) {
+ exceptions.add(e)
+ }
+ }
+
+ throw JsonParseException(p, "Cannot parse `LocalDateTime` from value: ${p.text}").apply {
+ exceptions.forEach { addSuppressed(it) }
+ }
+ }
+}
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/audio/speech/SpeechCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/audio/speech/SpeechCreateParams.kt
index 44190cfa..089121a4 100644
--- a/openai-java-core/src/main/kotlin/com/openai/models/audio/speech/SpeechCreateParams.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/models/audio/speech/SpeechCreateParams.kt
@@ -161,6 +161,20 @@ private constructor(
additionalQueryParams = speechCreateParams.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:
+ * - [input]
+ * - [model]
+ * - [voice]
+ * - [instructions]
+ * - [responseFormat]
+ * - etc.
+ */
+ fun body(body: Body) = apply { this.body = body.toBuilder() }
+
/** The text to generate audio for. The maximum length is 4096 characters. */
fun input(input: String) = apply { body.input(input) }
@@ -408,7 +422,7 @@ private constructor(
)
}
- @JvmSynthetic internal fun _body(): Body = body
+ fun _body(): Body = body
override fun _headers(): Headers = additionalHeaders
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 5ff32133..5973dd72 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
@@ -208,6 +208,20 @@ private constructor(
additionalQueryParams = transcriptionCreateParams.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:
+ * - [file]
+ * - [model]
+ * - [include]
+ * - [language]
+ * - [prompt]
+ * - etc.
+ */
+ fun body(body: Body) = apply { this.body = body.toBuilder() }
+
/**
* The audio file object (not file name) to transcribe, in one of these formats: flac, mp3,
* mp4, mpeg, mpga, m4a, ogg, wav, or webm.
@@ -503,8 +517,7 @@ private constructor(
)
}
- @JvmSynthetic
- internal fun _body(): Map> =
+ fun _body(): Map> =
mapOf(
"file" to _file(),
"model" to _model(),
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 dc7565f5..ec4db548 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
@@ -149,6 +149,20 @@ private constructor(
additionalQueryParams = translationCreateParams.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:
+ * - [file]
+ * - [model]
+ * - [prompt]
+ * - [responseFormat]
+ * - [temperature]
+ * - etc.
+ */
+ fun body(body: Body) = apply { this.body = body.toBuilder() }
+
/**
* The audio file object (not file name) translate, in one of these formats: flac, mp3, mp4,
* mpeg, mpga, m4a, ogg, wav, or webm.
@@ -372,8 +386,7 @@ private constructor(
)
}
- @JvmSynthetic
- internal fun _body(): Map> =
+ fun _body(): Map> =
mapOf(
"file" to _file(),
"model" to _model(),
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/batches/BatchCancelParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/batches/BatchCancelParams.kt
index 8ffd2380..c9a0e725 100644
--- a/openai-java-core/src/main/kotlin/com/openai/models/batches/BatchCancelParams.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/models/batches/BatchCancelParams.kt
@@ -206,8 +206,7 @@ private constructor(
)
}
- @JvmSynthetic
- internal fun _body(): Optional