diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index d1d50bcaf..a71305534 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.11.10"
+ ".": "0.12.0"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 243092256..a190bf7e6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,18 @@
# Changelog
+## 0.12.0 (2025-01-22)
+
+Full Changelog: [v0.11.10...v0.12.0](https://github.com/openai/openai-java/compare/v0.11.10...v0.12.0)
+
+### Features
+
+* **client:** make it easy to roundtrip messages ([#148](https://github.com/openai/openai-java/issues/148)) ([f4a1617](https://github.com/openai/openai-java/commit/f4a1617148ffc276a324ed9a59654091f57222d2))
+
+
+### Bug Fixes
+
+* **client:** bad assistants v2 deserialization ([#146](https://github.com/openai/openai-java/issues/146)) ([59d6de8](https://github.com/openai/openai-java/commit/59d6de8cf5857a4b46eeece4f3c8d930d67103d6))
+
## 0.11.10 (2025-01-21)
Full Changelog: [v0.11.9...v0.11.10](https://github.com/openai/openai-java/compare/v0.11.9...v0.11.10)
diff --git a/README.md b/README.md
index 39d7ee38f..c6a6797d4 100644
--- a/README.md
+++ b/README.md
@@ -9,8 +9,8 @@
-[](https://central.sonatype.com/artifact/com.openai/openai-java/0.11.10)
-[](https://javadoc.io/doc/com.openai/openai-java/0.11.10)
+[](https://central.sonatype.com/artifact/com.openai/openai-java/0.12.0)
+[](https://javadoc.io/doc/com.openai/openai-java/0.12.0)
@@ -31,7 +31,7 @@ The REST API documentation can be foundĀ on [platform.openai.com](https://platfo
```kotlin
-implementation("com.openai:openai-java:0.11.10")
+implementation("com.openai:openai-java:0.12.0")
```
#### Maven
@@ -40,7 +40,7 @@ implementation("com.openai:openai-java:0.11.10")
com.openai
openai-java
- 0.11.10
+ 0.12.0
```
diff --git a/build.gradle.kts b/build.gradle.kts
index 6f3392cf4..7c362cb38 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -8,7 +8,7 @@ repositories {
allprojects {
group = "com.openai"
- version = "0.11.10" // x-release-please-version
+ version = "0.12.0" // x-release-please-version
}
subprojects {
diff --git a/openai-java-core/src/main/kotlin/com/openai/core/handlers/SseHandler.kt b/openai-java-core/src/main/kotlin/com/openai/core/handlers/SseHandler.kt
index a5dd25746..82476f9fc 100644
--- a/openai-java-core/src/main/kotlin/com/openai/core/handlers/SseHandler.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/core/handlers/SseHandler.kt
@@ -1,3 +1,5 @@
+// File generated from our OpenAPI spec by Stainless.
+
@file:JvmName("SseHandler")
package com.openai.core.handlers
@@ -117,13 +119,14 @@ private class SseState(
}
@JvmSynthetic
-internal inline fun Handler>.mapJson():
- Handler> =
+internal inline fun Handler>.mapJson(
+ includeEventAndData: Boolean = false
+): Handler> =
object : Handler> {
override fun handle(response: HttpResponse): StreamResponse =
this@mapJson.handle(response).map {
try {
- it.json()
+ it.json(includeEventAndData)
} catch (e: Exception) {
throw OpenAIException("Error reading response", e)
}
diff --git a/openai-java-core/src/main/kotlin/com/openai/core/http/SseMessage.kt b/openai-java-core/src/main/kotlin/com/openai/core/http/SseMessage.kt
index 2fa8484e1..4314f17ce 100644
--- a/openai-java-core/src/main/kotlin/com/openai/core/http/SseMessage.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/core/http/SseMessage.kt
@@ -1,3 +1,5 @@
+// File generated from our OpenAPI spec by Stainless.
+
package com.openai.core.http
import com.fasterxml.jackson.databind.json.JsonMapper
@@ -39,7 +41,17 @@ private constructor(
fun build(): SseMessage = SseMessage(jsonMapper!!, event, data, id, retry)
}
- inline fun json(): T = jsonMapper.readerFor(jacksonTypeRef()).readValue(jsonNode)
+ inline fun json(includeEventAndData: Boolean = false): T {
+ var jsonNode = jsonNode
+ if (includeEventAndData) {
+ val newJsonNode = jsonMapper.createObjectNode()
+ event?.let { newJsonNode.put("event", event) }
+ newJsonNode.replace("data", jsonNode)
+ jsonNode = newJsonNode
+ }
+
+ return jsonMapper.readerFor(jacksonTypeRef()).readValue(jsonNode)
+ }
private val jsonNode by lazy {
try {
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/ChatCompletionCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/ChatCompletionCreateParams.kt
index 361895dd3..4baa099d1 100644
--- a/openai-java-core/src/main/kotlin/com/openai/models/ChatCompletionCreateParams.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/models/ChatCompletionCreateParams.kt
@@ -1413,6 +1413,10 @@ constructor(
)
)
+ /** Messages sent by the model in response to user messages. */
+ fun addMessage(chatCompletionAssistantMessageParam: ChatCompletionMessage) =
+ addMessage(chatCompletionAssistantMessageParam.toParam())
+
/**
* A list of messages comprising the conversation so far. Depending on the
* [model](https://platform.openai.com/docs/models) you use, different message types
@@ -2558,6 +2562,11 @@ constructor(
body.addMessage(chatCompletionAssistantMessageParam)
}
+ /** Messages sent by the model in response to user messages. */
+ fun addMessage(chatCompletionAssistantMessageParam: ChatCompletionMessage) = apply {
+ body.addMessage(chatCompletionAssistantMessageParam)
+ }
+
/**
* A list of messages comprising the conversation so far. Depending on the
* [model](https://platform.openai.com/docs/models) you use, different message types
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/ChatCompletionMessage.kt b/openai-java-core/src/main/kotlin/com/openai/models/ChatCompletionMessage.kt
index 168eef7f2..b8b6ce64b 100644
--- a/openai-java-core/src/main/kotlin/com/openai/models/ChatCompletionMessage.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/models/ChatCompletionMessage.kt
@@ -103,6 +103,29 @@ private constructor(
@ExcludeMissing
fun _additionalProperties(): Map = additionalProperties
+ fun toParam(): ChatCompletionAssistantMessageParam =
+ ChatCompletionAssistantMessageParam.builder()
+ .role(_role().map { ChatCompletionAssistantMessageParam.Role.of(it.toString()) })
+ .audio(
+ _audio().map {
+ ChatCompletionAssistantMessageParam.Audio.builder().id(it._id()).build()
+ }
+ )
+ .content(
+ _content().map { ChatCompletionAssistantMessageParam.Content.ofTextContent(it) }
+ )
+ .functionCall(
+ _functionCall().map {
+ ChatCompletionAssistantMessageParam.FunctionCall.builder()
+ .arguments(it._arguments())
+ .name(it._name())
+ .build()
+ }
+ )
+ .refusal(_refusal())
+ .toolCalls(_toolCalls())
+ .build()
+
private var validated: Boolean = false
fun validate(): ChatCompletionMessage = apply {
diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/beta/ThreadServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/beta/ThreadServiceAsyncImpl.kt
index 9915f6bb3..5e159cdbe 100644
--- a/openai-java-core/src/main/kotlin/com/openai/services/async/beta/ThreadServiceAsyncImpl.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/services/async/beta/ThreadServiceAsyncImpl.kt
@@ -211,7 +211,7 @@ internal constructor(
private val createAndRunStreamingHandler: Handler> =
sseHandler(clientOptions.jsonMapper)
- .mapJson()
+ .mapJson(includeEventAndData = true)
.withErrorHandler(errorHandler)
/** Create a thread and run it in one request. */
diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/beta/threads/RunServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/beta/threads/RunServiceAsyncImpl.kt
index 84ea3506d..5592b8fa6 100644
--- a/openai-java-core/src/main/kotlin/com/openai/services/async/beta/threads/RunServiceAsyncImpl.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/services/async/beta/threads/RunServiceAsyncImpl.kt
@@ -82,7 +82,7 @@ internal constructor(
private val createStreamingHandler: Handler> =
sseHandler(clientOptions.jsonMapper)
- .mapJson()
+ .mapJson(includeEventAndData = true)
.withErrorHandler(errorHandler)
/** Create a run. */
@@ -299,7 +299,7 @@ internal constructor(
private val submitToolOutputsStreamingHandler: Handler> =
sseHandler(clientOptions.jsonMapper)
- .mapJson()
+ .mapJson(includeEventAndData = true)
.withErrorHandler(errorHandler)
/**
diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/ThreadServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/ThreadServiceImpl.kt
index e84e00620..f16bcae65 100644
--- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/ThreadServiceImpl.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/ThreadServiceImpl.kt
@@ -197,7 +197,7 @@ internal constructor(
private val createAndRunStreamingHandler: Handler> =
sseHandler(clientOptions.jsonMapper)
- .mapJson()
+ .mapJson(includeEventAndData = true)
.withErrorHandler(errorHandler)
/** Create a thread and run it in one request. */
diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/threads/RunServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/threads/RunServiceImpl.kt
index 53b0e9f1b..8ac306075 100644
--- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/threads/RunServiceImpl.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/threads/RunServiceImpl.kt
@@ -75,7 +75,7 @@ internal constructor(
private val createStreamingHandler: Handler> =
sseHandler(clientOptions.jsonMapper)
- .mapJson()
+ .mapJson(includeEventAndData = true)
.withErrorHandler(errorHandler)
/** Create a run. */
@@ -278,7 +278,7 @@ internal constructor(
private val submitToolOutputsStreamingHandler: Handler> =
sseHandler(clientOptions.jsonMapper)
- .mapJson()
+ .mapJson(includeEventAndData = true)
.withErrorHandler(errorHandler)
/**