diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 5ce2d725..2e968815 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,12 +1,14 @@
name: CI
on:
push:
- branches-ignore:
- - 'generated'
- - 'codegen/**'
- - 'integrated/**'
- - 'stl-preview-head/**'
- - 'stl-preview-base/**'
+ branches:
+ - '**'
+ - '!integrated/**'
+ - '!stl-preview-head/**'
+ - '!stl-preview-base/**'
+ - '!generated'
+ - '!codegen/**'
+ - 'codegen/stl/**'
pull_request:
branches-ignore:
- 'stl-preview-head/**'
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index cd95c250..1b159305 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "4.28.0"
+ ".": "4.29.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index 900598b9..05fedda9 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 151
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-cb3e4451108eed58d59cff25bf77ec0dc960ec9c6f3dba68f90e7a9847c09d21.yml
-openapi_spec_hash: dec6d9be64a5ba8f474a1f2a7a4fafef
-config_hash: e922f01e25accd07d8fd3641c37fbd62
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-55ef7034334e938c30656a404ce5e21466103be87542a796425346299f450404.yml
+openapi_spec_hash: 4a5bfd2ee4ad47f5b7cf6f1ad08d5d7f
+config_hash: 96fbf82cf74a44ccd513f5acf0956ffd
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d7f1086e..c6278093 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,22 @@
# Changelog
+## 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)
+
+### Features
+
+* **api:** 5.4 nano and mini model slugs ([397027a](https://github.com/openai/openai-java/commit/397027a4117ab49e0a500b8dec8594ad34763011))
+* **api:** add defer_loading field to NamespaceTool.Tool.Function ([ff60586](https://github.com/openai/openai-java/commit/ff60586659f25204a545cb08623fe0a12810cbfa))
+* **api:** add IN and NIN filter types to ComparisonFilter ([6d0eac3](https://github.com/openai/openai-java/commit/6d0eac374f8eab9de341ae1a19c185512614893b))
+* **api:** add v1/videos endpoint to batch create ([421acd8](https://github.com/openai/openai-java/commit/421acd884ef736944c5368a7282fda8a890f0aed))
+
+
+### Chores
+
+* **internal:** tweak CI branches ([bfe3f0a](https://github.com/openai/openai-java/commit/bfe3f0ac8ac068443a40b4b7b23e7d179e8b4837))
+* **internal:** update retry delay tests ([dfcccf1](https://github.com/openai/openai-java/commit/dfcccf14f4f3a72e85db513955a3ede7bcdb1d6b))
+
## 4.28.0 (2026-03-13)
Full Changelog: [v4.27.0...v4.28.0](https://github.com/openai/openai-java/compare/v4.27.0...v4.28.0)
diff --git a/README.md b/README.md
index a8480cdb..fc9c3910 100644
--- a/README.md
+++ b/README.md
@@ -2,8 +2,8 @@
-[](https://central.sonatype.com/artifact/com.openai/openai-java/4.28.0)
-[](https://javadoc.io/doc/com.openai/openai-java/4.28.0)
+[](https://central.sonatype.com/artifact/com.openai/openai-java/4.29.0)
+[](https://javadoc.io/doc/com.openai/openai-java/4.29.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/4.28.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.0).
@@ -24,7 +24,7 @@ The REST API documentation can be found on [platform.openai.com](https://platfor
### Gradle
```kotlin
-implementation("com.openai:openai-java:4.28.0")
+implementation("com.openai:openai-java:4.29.0")
```
### Maven
@@ -33,7 +33,7 @@ implementation("com.openai:openai-java:4.28.0")
com.openai
openai-java
- 4.28.0
+ 4.29.0
```
@@ -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.28.0")
+implementation("com.openai:openai-java-spring-boot-starter:4.29.0")
```
#### Maven
@@ -1351,7 +1351,7 @@ implementation("com.openai:openai-java-spring-boot-starter:4.28.0")
com.openai
openai-java-spring-boot-starter
- 4.28.0
+ 4.29.0
```
diff --git a/build.gradle.kts b/build.gradle.kts
index 804d46a9..bbdcad0c 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -8,7 +8,7 @@ repositories {
allprojects {
group = "com.openai"
- version = "4.28.0" // x-release-please-version
+ version = "4.29.0" // x-release-please-version
}
subprojects {
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/ChatModel.kt b/openai-java-core/src/main/kotlin/com/openai/models/ChatModel.kt
index a04238e1..6ae3ba18 100644
--- a/openai-java-core/src/main/kotlin/com/openai/models/ChatModel.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/models/ChatModel.kt
@@ -22,6 +22,14 @@ class ChatModel @JsonCreator private constructor(private val value: JsonField Value.GPT_5_4
+ GPT_5_4_MINI -> Value.GPT_5_4_MINI
+ GPT_5_4_NANO -> Value.GPT_5_4_NANO
+ GPT_5_4_MINI_2026_03_17 -> Value.GPT_5_4_MINI_2026_03_17
+ GPT_5_4_NANO_2026_03_17 -> Value.GPT_5_4_NANO_2026_03_17
GPT_5_3_CHAT_LATEST -> Value.GPT_5_3_CHAT_LATEST
GPT_5_2 -> Value.GPT_5_2
GPT_5_2_2025_12_11 -> Value.GPT_5_2_2025_12_11
@@ -436,6 +456,10 @@ class ChatModel @JsonCreator private constructor(private val value: JsonField Known.GPT_5_4
+ GPT_5_4_MINI -> Known.GPT_5_4_MINI
+ GPT_5_4_NANO -> Known.GPT_5_4_NANO
+ GPT_5_4_MINI_2026_03_17 -> Known.GPT_5_4_MINI_2026_03_17
+ GPT_5_4_NANO_2026_03_17 -> Known.GPT_5_4_NANO_2026_03_17
GPT_5_3_CHAT_LATEST -> Known.GPT_5_3_CHAT_LATEST
GPT_5_2 -> Known.GPT_5_2
GPT_5_2_2025_12_11 -> Known.GPT_5_2_2025_12_11
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/ComparisonFilter.kt b/openai-java-core/src/main/kotlin/com/openai/models/ComparisonFilter.kt
index 905c7a78..3a597e52 100644
--- a/openai-java-core/src/main/kotlin/com/openai/models/ComparisonFilter.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/models/ComparisonFilter.kt
@@ -320,6 +320,10 @@ private constructor(
@JvmField val LTE = of("lte")
+ @JvmField val IN = of("in")
+
+ @JvmField val NIN = of("nin")
+
@JvmStatic fun of(value: String) = Type(JsonField.of(value))
}
@@ -331,6 +335,8 @@ private constructor(
GTE,
LT,
LTE,
+ IN,
+ NIN,
}
/**
@@ -349,6 +355,8 @@ private constructor(
GTE,
LT,
LTE,
+ IN,
+ NIN,
/** An enum member indicating that [Type] was instantiated with an unknown value. */
_UNKNOWN,
}
@@ -368,6 +376,8 @@ private constructor(
GTE -> Value.GTE
LT -> Value.LT
LTE -> Value.LTE
+ IN -> Value.IN
+ NIN -> Value.NIN
else -> Value._UNKNOWN
}
@@ -388,6 +398,8 @@ private constructor(
GTE -> Known.GTE
LT -> Known.LT
LTE -> Known.LTE
+ IN -> Known.IN
+ NIN -> Known.NIN
else -> throw OpenAIInvalidDataException("Unknown Type: $value")
}
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/batches/BatchCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/batches/BatchCreateParams.kt
index 6968e467..eabb949e 100644
--- a/openai-java-core/src/main/kotlin/com/openai/models/batches/BatchCreateParams.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/models/batches/BatchCreateParams.kt
@@ -41,9 +41,9 @@ private constructor(
/**
* The endpoint to be used for all requests in the batch. Currently `/v1/responses`,
* `/v1/chat/completions`, `/v1/embeddings`, `/v1/completions`, `/v1/moderations`,
- * `/v1/images/generations`, and `/v1/images/edits` are supported. Note that `/v1/embeddings`
- * batches are also restricted to a maximum of 50,000 embedding inputs across all requests in
- * the batch.
+ * `/v1/images/generations`, `/v1/images/edits`, and `/v1/videos` are supported. Note that
+ * `/v1/embeddings` batches are also restricted to a maximum of 50,000 embedding inputs across
+ * all requests in the batch.
*
* @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is
* unexpectedly missing or null (e.g. if the server responded with an unexpected value).
@@ -199,7 +199,7 @@ private constructor(
/**
* The endpoint to be used for all requests in the batch. Currently `/v1/responses`,
* `/v1/chat/completions`, `/v1/embeddings`, `/v1/completions`, `/v1/moderations`,
- * `/v1/images/generations`, and `/v1/images/edits` are supported. Note that
+ * `/v1/images/generations`, `/v1/images/edits`, and `/v1/videos` are supported. Note that
* `/v1/embeddings` batches are also restricted to a maximum of 50,000 embedding inputs
* across all requests in the batch.
*/
@@ -470,7 +470,7 @@ private constructor(
/**
* The endpoint to be used for all requests in the batch. Currently `/v1/responses`,
* `/v1/chat/completions`, `/v1/embeddings`, `/v1/completions`, `/v1/moderations`,
- * `/v1/images/generations`, and `/v1/images/edits` are supported. Note that
+ * `/v1/images/generations`, `/v1/images/edits`, and `/v1/videos` are supported. Note that
* `/v1/embeddings` batches are also restricted to a maximum of 50,000 embedding inputs
* across all requests in the batch.
*
@@ -628,9 +628,9 @@ private constructor(
/**
* The endpoint to be used for all requests in the batch. Currently `/v1/responses`,
* `/v1/chat/completions`, `/v1/embeddings`, `/v1/completions`, `/v1/moderations`,
- * `/v1/images/generations`, and `/v1/images/edits` are supported. Note that
- * `/v1/embeddings` batches are also restricted to a maximum of 50,000 embedding inputs
- * across all requests in the batch.
+ * `/v1/images/generations`, `/v1/images/edits`, and `/v1/videos` are supported. Note
+ * that `/v1/embeddings` batches are also restricted to a maximum of 50,000 embedding
+ * inputs across all requests in the batch.
*/
fun endpoint(endpoint: Endpoint) = endpoint(JsonField.of(endpoint))
@@ -948,9 +948,9 @@ private constructor(
/**
* The endpoint to be used for all requests in the batch. Currently `/v1/responses`,
* `/v1/chat/completions`, `/v1/embeddings`, `/v1/completions`, `/v1/moderations`,
- * `/v1/images/generations`, and `/v1/images/edits` are supported. Note that `/v1/embeddings`
- * batches are also restricted to a maximum of 50,000 embedding inputs across all requests in
- * the batch.
+ * `/v1/images/generations`, `/v1/images/edits`, and `/v1/videos` are supported. Note that
+ * `/v1/embeddings` batches are also restricted to a maximum of 50,000 embedding inputs across
+ * all requests in the batch.
*/
class Endpoint @JsonCreator private constructor(private val value: JsonField) : Enum {
@@ -980,6 +980,8 @@ private constructor(
@JvmField val V1_IMAGES_EDITS = of("/v1/images/edits")
+ @JvmField val V1_VIDEOS = of("/v1/videos")
+
@JvmStatic fun of(value: String) = Endpoint(JsonField.of(value))
}
@@ -992,6 +994,7 @@ private constructor(
V1_MODERATIONS,
V1_IMAGES_GENERATIONS,
V1_IMAGES_EDITS,
+ V1_VIDEOS,
}
/**
@@ -1011,6 +1014,7 @@ private constructor(
V1_MODERATIONS,
V1_IMAGES_GENERATIONS,
V1_IMAGES_EDITS,
+ V1_VIDEOS,
/** An enum member indicating that [Endpoint] was instantiated with an unknown value. */
_UNKNOWN,
}
@@ -1031,6 +1035,7 @@ private constructor(
V1_MODERATIONS -> Value.V1_MODERATIONS
V1_IMAGES_GENERATIONS -> Value.V1_IMAGES_GENERATIONS
V1_IMAGES_EDITS -> Value.V1_IMAGES_EDITS
+ V1_VIDEOS -> Value.V1_VIDEOS
else -> Value._UNKNOWN
}
@@ -1052,6 +1057,7 @@ private constructor(
V1_MODERATIONS -> Known.V1_MODERATIONS
V1_IMAGES_GENERATIONS -> Known.V1_IMAGES_GENERATIONS
V1_IMAGES_EDITS -> Known.V1_IMAGES_EDITS
+ V1_VIDEOS -> Known.V1_VIDEOS
else -> throw OpenAIInvalidDataException("Unknown Endpoint: $value")
}
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/NamespaceTool.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/NamespaceTool.kt
index 08778dc6..7c0e1adc 100644
--- a/openai-java-core/src/main/kotlin/com/openai/models/responses/NamespaceTool.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/NamespaceTool.kt
@@ -505,6 +505,7 @@ private constructor(
private constructor(
private val name: JsonField,
private val type: JsonValue,
+ private val deferLoading: JsonField,
private val description: JsonField,
private val parameters: JsonValue,
private val strict: JsonField,
@@ -515,6 +516,9 @@ private constructor(
private constructor(
@JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(),
@JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(),
+ @JsonProperty("defer_loading")
+ @ExcludeMissing
+ deferLoading: JsonField = JsonMissing.of(),
@JsonProperty("description")
@ExcludeMissing
description: JsonField = JsonMissing.of(),
@@ -524,7 +528,7 @@ private constructor(
@JsonProperty("strict")
@ExcludeMissing
strict: JsonField = JsonMissing.of(),
- ) : this(name, type, description, parameters, strict, mutableMapOf())
+ ) : this(name, type, deferLoading, description, parameters, strict, mutableMapOf())
/**
* @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is
@@ -544,6 +548,14 @@ private constructor(
*/
@JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type
+ /**
+ * Whether this function should be deferred and discovered via tool search.
+ *
+ * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if
+ * the server responded with an unexpected value).
+ */
+ fun deferLoading(): Optional = deferLoading.getOptional("defer_loading")
+
/**
* @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if
* the server responded with an unexpected value).
@@ -572,6 +584,16 @@ private constructor(
*/
@JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name
+ /**
+ * Returns the raw JSON value of [deferLoading].
+ *
+ * Unlike [deferLoading], this method doesn't throw if the JSON field has an unexpected
+ * type.
+ */
+ @JsonProperty("defer_loading")
+ @ExcludeMissing
+ fun _deferLoading(): JsonField = deferLoading
+
/**
* Returns the raw JSON value of [description].
*
@@ -619,6 +641,7 @@ private constructor(
private var name: JsonField? = null
private var type: JsonValue = JsonValue.from("function")
+ private var deferLoading: JsonField = JsonMissing.of()
private var description: JsonField = JsonMissing.of()
private var parameters: JsonValue = JsonMissing.of()
private var strict: JsonField = JsonMissing.of()
@@ -628,6 +651,7 @@ private constructor(
internal fun from(function: Function) = apply {
name = function.name
type = function.type
+ deferLoading = function.deferLoading
description = function.description
parameters = function.parameters
strict = function.strict
@@ -659,6 +683,20 @@ private constructor(
*/
fun type(type: JsonValue) = apply { this.type = type }
+ /** Whether this function should be deferred and discovered via tool search. */
+ fun deferLoading(deferLoading: Boolean) = deferLoading(JsonField.of(deferLoading))
+
+ /**
+ * Sets [Builder.deferLoading] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.deferLoading] with a well-typed [Boolean] value
+ * instead. This method is primarily for setting the field to an undocumented or not
+ * yet supported value.
+ */
+ fun deferLoading(deferLoading: JsonField) = apply {
+ this.deferLoading = deferLoading
+ }
+
fun description(description: String?) =
description(JsonField.ofNullable(description))
@@ -738,6 +776,7 @@ private constructor(
Function(
checkRequired("name", name),
type,
+ deferLoading,
description,
parameters,
strict,
@@ -758,6 +797,7 @@ private constructor(
throw OpenAIInvalidDataException("'type' is invalid, received $it")
}
}
+ deferLoading()
description()
strict()
validated = true
@@ -781,6 +821,7 @@ private constructor(
internal fun validity(): Int =
(if (name.asKnown().isPresent) 1 else 0) +
type.let { if (it == JsonValue.from("function")) 1 else 0 } +
+ (if (deferLoading.asKnown().isPresent) 1 else 0) +
(if (description.asKnown().isPresent) 1 else 0) +
(if (strict.asKnown().isPresent) 1 else 0)
@@ -792,6 +833,7 @@ private constructor(
return other is Function &&
name == other.name &&
type == other.type &&
+ deferLoading == other.deferLoading &&
description == other.description &&
parameters == other.parameters &&
strict == other.strict &&
@@ -799,13 +841,21 @@ private constructor(
}
private val hashCode: Int by lazy {
- Objects.hash(name, type, description, parameters, strict, additionalProperties)
+ Objects.hash(
+ name,
+ type,
+ deferLoading,
+ description,
+ parameters,
+ strict,
+ additionalProperties,
+ )
}
override fun hashCode(): Int = hashCode
override fun toString() =
- "Function{name=$name, type=$type, description=$description, parameters=$parameters, strict=$strict, additionalProperties=$additionalProperties}"
+ "Function{name=$name, type=$type, deferLoading=$deferLoading, description=$description, parameters=$parameters, strict=$strict, additionalProperties=$additionalProperties}"
}
}
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseCompactParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseCompactParams.kt
index eb7fdac3..fa9a5f6f 100644
--- a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseCompactParams.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseCompactParams.kt
@@ -861,6 +861,14 @@ private constructor(
@JvmField val GPT_5_4 = of("gpt-5.4")
+ @JvmField val GPT_5_4_MINI = of("gpt-5.4-mini")
+
+ @JvmField val GPT_5_4_NANO = of("gpt-5.4-nano")
+
+ @JvmField val GPT_5_4_MINI_2026_03_17 = of("gpt-5.4-mini-2026-03-17")
+
+ @JvmField val GPT_5_4_NANO_2026_03_17 = of("gpt-5.4-nano-2026-03-17")
+
@JvmField val GPT_5_3_CHAT_LATEST = of("gpt-5.3-chat-latest")
@JvmField val GPT_5_2 = of("gpt-5.2")
@@ -1043,6 +1051,10 @@ private constructor(
/** An enum containing [Model]'s known values. */
enum class Known {
GPT_5_4,
+ GPT_5_4_MINI,
+ GPT_5_4_NANO,
+ GPT_5_4_MINI_2026_03_17,
+ GPT_5_4_NANO_2026_03_17,
GPT_5_3_CHAT_LATEST,
GPT_5_2,
GPT_5_2_2025_12_11,
@@ -1143,6 +1155,10 @@ private constructor(
*/
enum class Value {
GPT_5_4,
+ GPT_5_4_MINI,
+ GPT_5_4_NANO,
+ GPT_5_4_MINI_2026_03_17,
+ GPT_5_4_NANO_2026_03_17,
GPT_5_3_CHAT_LATEST,
GPT_5_2,
GPT_5_2_2025_12_11,
@@ -1244,6 +1260,10 @@ private constructor(
fun value(): Value =
when (this) {
GPT_5_4 -> Value.GPT_5_4
+ GPT_5_4_MINI -> Value.GPT_5_4_MINI
+ GPT_5_4_NANO -> Value.GPT_5_4_NANO
+ GPT_5_4_MINI_2026_03_17 -> Value.GPT_5_4_MINI_2026_03_17
+ GPT_5_4_NANO_2026_03_17 -> Value.GPT_5_4_NANO_2026_03_17
GPT_5_3_CHAT_LATEST -> Value.GPT_5_3_CHAT_LATEST
GPT_5_2 -> Value.GPT_5_2
GPT_5_2_2025_12_11 -> Value.GPT_5_2_2025_12_11
@@ -1346,6 +1366,10 @@ private constructor(
fun known(): Known =
when (this) {
GPT_5_4 -> Known.GPT_5_4
+ GPT_5_4_MINI -> Known.GPT_5_4_MINI
+ GPT_5_4_NANO -> Known.GPT_5_4_NANO
+ GPT_5_4_MINI_2026_03_17 -> Known.GPT_5_4_MINI_2026_03_17
+ GPT_5_4_NANO_2026_03_17 -> Known.GPT_5_4_NANO_2026_03_17
GPT_5_3_CHAT_LATEST -> Known.GPT_5_3_CHAT_LATEST
GPT_5_2 -> Known.GPT_5_2
GPT_5_2_2025_12_11 -> Known.GPT_5_2_2025_12_11
diff --git a/openai-java-core/src/test/kotlin/com/openai/core/http/RetryingHttpClientTest.kt b/openai-java-core/src/test/kotlin/com/openai/core/http/RetryingHttpClientTest.kt
index 0c3dba32..21834efa 100644
--- a/openai-java-core/src/test/kotlin/com/openai/core/http/RetryingHttpClientTest.kt
+++ b/openai-java-core/src/test/kotlin/com/openai/core/http/RetryingHttpClientTest.kt
@@ -400,9 +400,9 @@ internal class RetryingHttpClientTest {
assertThat(sleeper.durations).hasSize(3)
// retries=1: 0.5s * [0.75, 1.0]
assertThat(sleeper.durations[0]).isBetween(Duration.ofMillis(375), Duration.ofMillis(500))
- // retries=2: 1.0s * [0.75, 1.0]
+ // retries=2: 1s * [0.75, 1.0]
assertThat(sleeper.durations[1]).isBetween(Duration.ofMillis(750), Duration.ofMillis(1000))
- // retries=3: 2.0s * [0.75, 1.0]
+ // retries=3: 2s * [0.75, 1.0]
assertThat(sleeper.durations[2]).isBetween(Duration.ofMillis(1500), Duration.ofMillis(2000))
assertNoResponseLeaks()
}
@@ -427,9 +427,9 @@ internal class RetryingHttpClientTest {
assertThat(response.statusCode()).isEqualTo(503)
verify(7, postRequestedFor(urlPathEqualTo("/something")))
assertThat(sleeper.durations).hasSize(6)
- // retries=5: min(0.5 * 2^4, 8) = 8.0s * [0.75, 1.0]
+ // retries=5: backoff hits the 8s cap * [0.75, 1.0]
assertThat(sleeper.durations[4]).isBetween(Duration.ofMillis(6000), Duration.ofMillis(8000))
- // retries=6: min(0.5 * 2^5, 8) = min(16, 8) = 8.0s * [0.75, 1.0] (capped)
+ // retries=6: still capped at 8s * [0.75, 1.0]
assertThat(sleeper.durations[5]).isBetween(Duration.ofMillis(6000), Duration.ofMillis(8000))
assertNoResponseLeaks()
}
diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/NamespaceToolTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/NamespaceToolTest.kt
index 56b8d8ab..4bc1bd59 100644
--- a/openai-java-core/src/test/kotlin/com/openai/models/responses/NamespaceToolTest.kt
+++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/NamespaceToolTest.kt
@@ -19,6 +19,7 @@ internal class NamespaceToolTest {
.addTool(
NamespaceTool.Tool.Function.builder()
.name("name")
+ .deferLoading(true)
.description("description")
.parameters(JsonValue.from(mapOf()))
.strict(true)
@@ -33,6 +34,7 @@ internal class NamespaceToolTest {
NamespaceTool.Tool.ofFunction(
NamespaceTool.Tool.Function.builder()
.name("name")
+ .deferLoading(true)
.description("description")
.parameters(JsonValue.from(mapOf()))
.strict(true)
@@ -51,6 +53,7 @@ internal class NamespaceToolTest {
.addTool(
NamespaceTool.Tool.Function.builder()
.name("name")
+ .deferLoading(true)
.description("description")
.parameters(JsonValue.from(mapOf()))
.strict(true)
diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ToolTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ToolTest.kt
index f2a92903..519ce566 100644
--- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ToolTest.kt
+++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ToolTest.kt
@@ -649,6 +649,7 @@ internal class ToolTest {
.addTool(
NamespaceTool.Tool.Function.builder()
.name("name")
+ .deferLoading(true)
.description("description")
.parameters(JsonValue.from(mapOf()))
.strict(true)
@@ -686,6 +687,7 @@ internal class ToolTest {
.addTool(
NamespaceTool.Tool.Function.builder()
.name("name")
+ .deferLoading(true)
.description("description")
.parameters(JsonValue.from(mapOf()))
.strict(true)