From fd3b67cef9c4457506a76b9e994210e512e0181f Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 17 Mar 2026 21:17:26 +0000 Subject: [PATCH 1/3] fix(client): allow updating header/query affecting fields in `toBuilder()` --- .../kotlin/com/openai/core/ClientOptions.kt | 11 ++++-- .../com/openai/core/ClientOptionsTest.kt | 38 +++++++++++++++++++ 2 files changed, 46 insertions(+), 3 deletions(-) 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 f1a1aff10..1a07cdde2 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 @@ -533,9 +533,7 @@ private constructor( headers.put("X-Stainless-Runtime", "JRE") headers.put("X-Stainless-Runtime-Version", getJavaVersion()) headers.put("X-Stainless-Kotlin-Version", KotlinVersion.CURRENT.toString()) - organization?.let { headers.put("OpenAI-Organization", it) } - project?.let { headers.put("OpenAI-Project", it) } - + // We replace after all the default headers to allow end-users to overwrite them. headers.replaceAll(this.headers.build()) when (credential) { is AzureApiKeyCredential -> { @@ -568,6 +566,13 @@ private constructor( } queryParams.replaceAll(this.queryParams.build()) + organization?.let { headers.replace("OpenAI-Organization", it) } + project?.let { headers.replace("OpenAI-Project", it) } + apiKey.let { + if (!it.isEmpty()) { + headers.replace("Authorization", "Bearer $it") + } + } return ClientOptions( httpClient, diff --git a/openai-java-core/src/test/kotlin/com/openai/core/ClientOptionsTest.kt b/openai-java-core/src/test/kotlin/com/openai/core/ClientOptionsTest.kt index 9aef24029..74ab42f4a 100644 --- a/openai-java-core/src/test/kotlin/com/openai/core/ClientOptionsTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/core/ClientOptionsTest.kt @@ -16,6 +16,44 @@ internal class ClientOptionsTest { private val httpClient = mock() + @Test + fun putHeader_canOverwriteDefaultHeader() { + val clientOptions = + ClientOptions.builder() + .httpClient(httpClient) + .putHeader("User-Agent", "My User Agent") + .apiKey("My API Key") + .build() + + assertThat(clientOptions.headers.values("User-Agent")).containsExactly("My User Agent") + } + + @Test + fun toBuilder_organizationCanBeUpdated() { + var clientOptions = + ClientOptions.builder() + .httpClient(httpClient) + .organization("My Organization") + .apiKey("My API Key") + .build() + + clientOptions = clientOptions.toBuilder().organization("another My Organization").build() + + assertThat(clientOptions.headers.values("OpenAI-Organization")) + .containsExactly("another My Organization") + } + + @Test + fun toBuilder_bearerAuthCanBeUpdated() { + var clientOptions = + ClientOptions.builder().httpClient(httpClient).apiKey("My API Key").build() + + clientOptions = clientOptions.toBuilder().apiKey("another My API Key").build() + + assertThat(clientOptions.headers.values("Authorization")) + .containsExactly("Bearer another My API Key") + } + @Test fun toBuilder_whenOriginalClientOptionsGarbageCollected_doesNotCloseOriginalClient() { var clientOptions = From 8383a7de659aa6f17e1707614f5a246ced127532 Mon Sep 17 00:00:00 2001 From: Alex Chang Date: Tue, 17 Mar 2026 22:35:15 -0400 Subject: [PATCH 2/3] fix(client): remove redundant apiKey override --- .../src/main/kotlin/com/openai/core/ClientOptions.kt | 5 ----- 1 file changed, 5 deletions(-) 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 1a07cdde2..e48abf7bd 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 @@ -568,11 +568,6 @@ private constructor( queryParams.replaceAll(this.queryParams.build()) organization?.let { headers.replace("OpenAI-Organization", it) } project?.let { headers.replace("OpenAI-Project", it) } - apiKey.let { - if (!it.isEmpty()) { - headers.replace("Authorization", "Bearer $it") - } - } return ClientOptions( httpClient, From 53561aa953025daf13564269de9ce6e759bb7f2e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 19 Mar 2026 05:30:30 +0000 Subject: [PATCH 3/3] release: 4.29.1 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 9 +++++++++ README.md | 14 +++++++------- build.gradle.kts | 2 +- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 1b1593054..b85eea742 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "4.29.0" + ".": "4.29.1" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index c6278093a..85257fac6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 4.29.1 (2026-03-19) + +Full Changelog: [v4.29.0...v4.29.1](https://github.com/openai/openai-java/compare/v4.29.0...v4.29.1) + +### Bug Fixes + +* **client:** allow updating header/query affecting fields in `toBuilder()` ([fd3b67c](https://github.com/openai/openai-java/commit/fd3b67cef9c4457506a76b9e994210e512e0181f)) +* **client:** remove redundant apiKey override ([8383a7d](https://github.com/openai/openai-java/commit/8383a7de659aa6f17e1707614f5a246ced127532)) + ## 4.29.0 (2026-03-17) Full Changelog: [v4.28.0...v4.29.0](https://github.com/openai/openai-java/compare/v4.28.0...v4.29.0) diff --git a/README.md b/README.md index fc9c39104..9ac2349ce 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ -[![Maven Central](https://img.shields.io/maven-central/v/com.openai/openai-java)](https://central.sonatype.com/artifact/com.openai/openai-java/4.29.0) -[![javadoc](https://javadoc.io/badge2/com.openai/openai-java/4.29.0/javadoc.svg)](https://javadoc.io/doc/com.openai/openai-java/4.29.0) +[![Maven Central](https://img.shields.io/maven-central/v/com.openai/openai-java)](https://central.sonatype.com/artifact/com.openai/openai-java/4.29.1) +[![javadoc](https://javadoc.io/badge2/com.openai/openai-java/4.29.1/javadoc.svg)](https://javadoc.io/doc/com.openai/openai-java/4.29.1) @@ -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/4.29.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/4.29.1). @@ -24,7 +24,7 @@ The REST API documentation can be found on [platform.openai.com](https://platfor ### Gradle ```kotlin -implementation("com.openai:openai-java:4.29.0") +implementation("com.openai:openai-java:4.29.1") ``` ### Maven @@ -33,7 +33,7 @@ implementation("com.openai:openai-java:4.29.0") com.openai openai-java - 4.29.0 + 4.29.1 ``` @@ -1342,7 +1342,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:4.29.0") +implementation("com.openai:openai-java-spring-boot-starter:4.29.1") ``` #### Maven @@ -1351,7 +1351,7 @@ implementation("com.openai:openai-java-spring-boot-starter:4.29.0") com.openai openai-java-spring-boot-starter - 4.29.0 + 4.29.1 ``` diff --git a/build.gradle.kts b/build.gradle.kts index bbdcad0c8..782ec6a02 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ repositories { allprojects { group = "com.openai" - version = "4.29.0" // x-release-please-version + version = "4.29.1" // x-release-please-version } subprojects {