diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index ba2c94bf6..a95c85271 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "4.30.0"
+ ".": "4.31.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index de3730f1e..e2b52c7b5 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-00994178cc8e20d71754b00c54b0e4f5b4128e1c1cce765e9b7d696bd8c80d33.yml
-openapi_spec_hash: 81f404053b663f987209b4fb2d08a230
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-dd99495ad509338e6de862802839360dfe394d5cd6d6ba6d13fec8fca92328b8.yml
+openapi_spec_hash: 68abda9122013a9ae3f084cfdbe8e8c1
config_hash: 5635033cdc8c930255f8b529a78de722
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 55bf3a5b0..999a0a802 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,31 @@
# Changelog
+## 4.31.0 (2026-04-04)
+
+Full Changelog: [v4.30.0...v4.31.0](https://github.com/openai/openai-java/compare/v4.30.0...v4.31.0)
+
+### Features
+
+* **api:** add phase field to conversations Message ([e562a17](https://github.com/openai/openai-java/commit/e562a1701cfb7c92aa308d80d7bfe8e99c6394c8))
+* **api:** add WEB_SEARCH_CALL_RESULTS to ResponseIncludable enum ([eda0a61](https://github.com/openai/openai-java/commit/eda0a61f837af3a0aba2851a23320aadfce82979))
+
+
+### Bug Fixes
+
+* **api:** remove web_search_call.results from ResponseIncludable ([936b2ab](https://github.com/openai/openai-java/commit/936b2ab08e8641bd1d6a1b2432140762185e22eb))
+
+
+### Chores
+
+* **internal:** update multipart form array serialization ([240ca42](https://github.com/openai/openai-java/commit/240ca42401366b75cf70b0eb0ff9f63425c9b358))
+* **tests:** bump steady to v0.20.1 ([a3c95b0](https://github.com/openai/openai-java/commit/a3c95b073d7b10a13ce83865947ab4fbec5a95d0))
+* **tests:** bump steady to v0.20.2 ([78b1d56](https://github.com/openai/openai-java/commit/78b1d5629bf7d31173ec1cec50f3191959cdba9d))
+
+
+### Documentation
+
+* **api:** clarify file_batches usage in vector stores files and file batches ([9c56841](https://github.com/openai/openai-java/commit/9c56841ff2f052a7e54290b36c3f74528be3de19))
+
## 4.30.0 (2026-03-25)
Full Changelog: [v4.29.1...v4.30.0](https://github.com/openai/openai-java/compare/v4.29.1...v4.30.0)
diff --git a/README.md b/README.md
index f166faed5..4448599ec 100644
--- a/README.md
+++ b/README.md
@@ -2,8 +2,8 @@
-[](https://central.sonatype.com/artifact/com.openai/openai-java/4.30.0)
-[](https://javadoc.io/doc/com.openai/openai-java/4.30.0)
+[](https://central.sonatype.com/artifact/com.openai/openai-java/4.31.0)
+[](https://javadoc.io/doc/com.openai/openai-java/4.31.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.30.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.31.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.30.0")
+implementation("com.openai:openai-java:4.31.0")
```
### Maven
@@ -33,7 +33,7 @@ implementation("com.openai:openai-java:4.30.0")
com.openai
openai-java
- 4.30.0
+ 4.31.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.30.0")
+implementation("com.openai:openai-java-spring-boot-starter:4.31.0")
```
#### Maven
@@ -1351,7 +1351,7 @@ implementation("com.openai:openai-java-spring-boot-starter:4.30.0")
com.openai
openai-java-spring-boot-starter
- 4.30.0
+ 4.31.0
```
diff --git a/build.gradle.kts b/build.gradle.kts
index 4ade3a792..9f350c477 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -8,7 +8,7 @@ repositories {
allprojects {
group = "com.openai"
- version = "4.30.0" // x-release-please-version
+ version = "4.31.0" // x-release-please-version
}
subprojects {
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/conversations/Message.kt b/openai-java-core/src/main/kotlin/com/openai/models/conversations/Message.kt
index 374309960..bd0496273 100644
--- a/openai-java-core/src/main/kotlin/com/openai/models/conversations/Message.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/models/conversations/Message.kt
@@ -44,6 +44,7 @@ private constructor(
private val role: JsonField,
private val status: JsonField,
private val type: JsonValue,
+ private val phase: JsonField,
private val additionalProperties: MutableMap,
) {
@@ -56,7 +57,8 @@ private constructor(
@JsonProperty("role") @ExcludeMissing role: JsonField = JsonMissing.of(),
@JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(),
@JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(),
- ) : this(id, content, role, status, type, mutableMapOf())
+ @JsonProperty("phase") @ExcludeMissing phase: JsonField = JsonMissing.of(),
+ ) : this(id, content, role, status, type, phase, mutableMapOf())
/**
* The unique ID of the message.
@@ -105,6 +107,17 @@ private constructor(
*/
@JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type
+ /**
+ * Labels an `assistant` message as intermediate commentary (`commentary`) or the final answer
+ * (`final_answer`). For models like `gpt-5.3-codex` and beyond, when sending follow-up
+ * requests, preserve and resend phase on all assistant messages — dropping it can degrade
+ * performance. Not used for user messages.
+ *
+ * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the
+ * server responded with an unexpected value).
+ */
+ fun phase(): Optional = phase.getOptional("phase")
+
/**
* Returns the raw JSON value of [id].
*
@@ -133,6 +146,13 @@ private constructor(
*/
@JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status
+ /**
+ * Returns the raw JSON value of [phase].
+ *
+ * Unlike [phase], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("phase") @ExcludeMissing fun _phase(): JsonField = phase
+
@JsonAnySetter
private fun putAdditionalProperty(key: String, value: JsonValue) {
additionalProperties.put(key, value)
@@ -169,6 +189,7 @@ private constructor(
private var role: JsonField? = null
private var status: JsonField? = null
private var type: JsonValue = JsonValue.from("message")
+ private var phase: JsonField = JsonMissing.of()
private var additionalProperties: MutableMap = mutableMapOf()
@JvmSynthetic
@@ -178,6 +199,7 @@ private constructor(
role = message.role
status = message.status
type = message.type
+ phase = message.phase
additionalProperties = message.additionalProperties.toMutableMap()
}
@@ -359,6 +381,25 @@ private constructor(
*/
fun type(type: JsonValue) = apply { this.type = type }
+ /**
+ * Labels an `assistant` message as intermediate commentary (`commentary`) or the final
+ * answer (`final_answer`). For models like `gpt-5.3-codex` and beyond, when sending
+ * follow-up requests, preserve and resend phase on all assistant messages — dropping it can
+ * degrade performance. Not used for user messages.
+ */
+ fun phase(phase: Phase?) = phase(JsonField.ofNullable(phase))
+
+ /** Alias for calling [Builder.phase] with `phase.orElse(null)`. */
+ fun phase(phase: Optional) = phase(phase.getOrNull())
+
+ /**
+ * Sets [Builder.phase] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.phase] with a well-typed [Phase] value instead. This
+ * method is primarily for setting the field to an undocumented or not yet supported value.
+ */
+ fun phase(phase: JsonField) = apply { this.phase = phase }
+
fun additionalProperties(additionalProperties: Map) = apply {
this.additionalProperties.clear()
putAllAdditionalProperties(additionalProperties)
@@ -400,6 +441,7 @@ private constructor(
checkRequired("role", role),
checkRequired("status", status),
type,
+ phase,
additionalProperties.toMutableMap(),
)
}
@@ -420,6 +462,7 @@ private constructor(
throw OpenAIInvalidDataException("'type' is invalid, received $it")
}
}
+ phase().ifPresent { it.validate() }
validated = true
}
@@ -442,7 +485,8 @@ private constructor(
(content.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) +
(role.asKnown().getOrNull()?.validity() ?: 0) +
(status.asKnown().getOrNull()?.validity() ?: 0) +
- type.let { if (it == JsonValue.from("message")) 1 else 0 }
+ type.let { if (it == JsonValue.from("message")) 1 else 0 } +
+ (phase.asKnown().getOrNull()?.validity() ?: 0)
/** A content part that makes up an input or output item. */
@JsonDeserialize(using = Content.Deserializer::class)
@@ -1379,6 +1423,137 @@ private constructor(
override fun toString() = value.toString()
}
+ /**
+ * Labels an `assistant` message as intermediate commentary (`commentary`) or the final answer
+ * (`final_answer`). For models like `gpt-5.3-codex` and beyond, when sending follow-up
+ * requests, preserve and resend phase on all assistant messages — dropping it can degrade
+ * performance. Not used for user messages.
+ */
+ class Phase @JsonCreator private constructor(private val value: JsonField) : Enum {
+
+ /**
+ * Returns this class instance's raw value.
+ *
+ * This is usually only useful if this instance was deserialized from data that doesn't
+ * match any known member, and you want to know that value. For example, if the SDK is on an
+ * older version than the API, then the API may respond with new members that the SDK is
+ * unaware of.
+ */
+ @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value
+
+ companion object {
+
+ @JvmField val COMMENTARY = of("commentary")
+
+ @JvmField val FINAL_ANSWER = of("final_answer")
+
+ @JvmStatic fun of(value: String) = Phase(JsonField.of(value))
+ }
+
+ /** An enum containing [Phase]'s known values. */
+ enum class Known {
+ COMMENTARY,
+ FINAL_ANSWER,
+ }
+
+ /**
+ * An enum containing [Phase]'s known values, as well as an [_UNKNOWN] member.
+ *
+ * An instance of [Phase] can contain an unknown value in a couple of cases:
+ * - It was deserialized from data that doesn't match any known member. For example, if the
+ * SDK is on an older version than the API, then the API may respond with new members that
+ * the SDK is unaware of.
+ * - It was constructed with an arbitrary value using the [of] method.
+ */
+ enum class Value {
+ COMMENTARY,
+ FINAL_ANSWER,
+ /** An enum member indicating that [Phase] was instantiated with an unknown value. */
+ _UNKNOWN,
+ }
+
+ /**
+ * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN]
+ * if the class was instantiated with an unknown value.
+ *
+ * Use the [known] method instead if you're certain the value is always known or if you want
+ * to throw for the unknown case.
+ */
+ fun value(): Value =
+ when (this) {
+ COMMENTARY -> Value.COMMENTARY
+ FINAL_ANSWER -> Value.FINAL_ANSWER
+ else -> Value._UNKNOWN
+ }
+
+ /**
+ * Returns an enum member corresponding to this class instance's value.
+ *
+ * Use the [value] method instead if you're uncertain the value is always known and don't
+ * want to throw for the unknown case.
+ *
+ * @throws OpenAIInvalidDataException if this class instance's value is a not a known
+ * member.
+ */
+ fun known(): Known =
+ when (this) {
+ COMMENTARY -> Known.COMMENTARY
+ FINAL_ANSWER -> Known.FINAL_ANSWER
+ else -> throw OpenAIInvalidDataException("Unknown Phase: $value")
+ }
+
+ /**
+ * Returns this class instance's primitive wire representation.
+ *
+ * This differs from the [toString] method because that method is primarily for debugging
+ * and generally doesn't throw.
+ *
+ * @throws OpenAIInvalidDataException if this class instance's value does not have the
+ * expected primitive type.
+ */
+ fun asString(): String =
+ _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") }
+
+ private var validated: Boolean = false
+
+ fun validate(): Phase = apply {
+ if (validated) {
+ return@apply
+ }
+
+ known()
+ validated = true
+ }
+
+ fun isValid(): Boolean =
+ try {
+ validate()
+ true
+ } catch (e: OpenAIInvalidDataException) {
+ false
+ }
+
+ /**
+ * Returns a score indicating how many valid values are contained in this object
+ * recursively.
+ *
+ * Used for best match union deserialization.
+ */
+ @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) {
+ return true
+ }
+
+ return other is Phase && value == other.value
+ }
+
+ override fun hashCode() = value.hashCode()
+
+ override fun toString() = value.toString()
+ }
+
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
@@ -1390,15 +1565,16 @@ private constructor(
role == other.role &&
status == other.status &&
type == other.type &&
+ phase == other.phase &&
additionalProperties == other.additionalProperties
}
private val hashCode: Int by lazy {
- Objects.hash(id, content, role, status, type, additionalProperties)
+ Objects.hash(id, content, role, status, type, phase, additionalProperties)
}
override fun hashCode(): Int = hashCode
override fun toString() =
- "Message{id=$id, content=$content, role=$role, status=$status, type=$type, additionalProperties=$additionalProperties}"
+ "Message{id=$id, content=$content, role=$role, status=$status, type=$type, phase=$phase, additionalProperties=$additionalProperties}"
}
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeSessionCreateRequest.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeSessionCreateRequest.kt
index 9bad2ba3f..2557626d9 100644
--- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeSessionCreateRequest.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeSessionCreateRequest.kt
@@ -208,9 +208,9 @@ private constructor(
fun tools(): Optional> = tools.getOptional("tools")
/**
- * Realtime API can write session traces to the [Traces Dashboard](/logs?api=traces). Set to
- * null to disable tracing. Once tracing is enabled for a session, the configuration cannot be
- * modified.
+ * Realtime API can write session traces to the
+ * [Traces Dashboard](https://platform.openai.com/logs?api=traces). Set to null to disable
+ * tracing. Once tracing is enabled for a session, the configuration cannot be modified.
*
* `auto` will create a trace for the session with default values for the workflow name, group
* id, and metadata.
@@ -647,9 +647,9 @@ private constructor(
addTool(RealtimeToolsConfigUnion.Mcp.builder().serverLabel(serverLabel).build())
/**
- * Realtime API can write session traces to the [Traces Dashboard](/logs?api=traces). Set to
- * null to disable tracing. Once tracing is enabled for a session, the configuration cannot
- * be modified.
+ * Realtime API can write session traces to the
+ * [Traces Dashboard](https://platform.openai.com/logs?api=traces). Set to null to disable
+ * tracing. Once tracing is enabled for a session, the configuration cannot be modified.
*
* `auto` will create a trace for the session with default values for the workflow name,
* group id, and metadata.
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeTracingConfig.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeTracingConfig.kt
index 1e8eeec30..50e2423dc 100644
--- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeTracingConfig.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeTracingConfig.kt
@@ -27,8 +27,9 @@ import java.util.Objects
import java.util.Optional
/**
- * Realtime API can write session traces to the [Traces Dashboard](/logs?api=traces). Set to null to
- * disable tracing. Once tracing is enabled for a session, the configuration cannot be modified.
+ * Realtime API can write session traces to the
+ * [Traces Dashboard](https://platform.openai.com/logs?api=traces). Set to null to disable tracing.
+ * Once tracing is enabled for a session, the configuration cannot be modified.
*
* `auto` will create a trace for the session with default values for the workflow name, group id,
* and metadata.
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/clientsecrets/RealtimeSessionCreateResponse.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/clientsecrets/RealtimeSessionCreateResponse.kt
index 438da7053..f35310cf2 100644
--- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/clientsecrets/RealtimeSessionCreateResponse.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/clientsecrets/RealtimeSessionCreateResponse.kt
@@ -224,9 +224,9 @@ private constructor(
fun tools(): Optional> = tools.getOptional("tools")
/**
- * Realtime API can write session traces to the [Traces Dashboard](/logs?api=traces). Set to
- * null to disable tracing. Once tracing is enabled for a session, the configuration cannot be
- * modified.
+ * Realtime API can write session traces to the
+ * [Traces Dashboard](https://platform.openai.com/logs?api=traces). Set to null to disable
+ * tracing. Once tracing is enabled for a session, the configuration cannot be modified.
*
* `auto` will create a trace for the session with default values for the workflow name, group
* id, and metadata.
@@ -664,9 +664,9 @@ private constructor(
fun addTool(mcp: Tool.McpTool) = addTool(Tool.ofMcp(mcp))
/**
- * Realtime API can write session traces to the [Traces Dashboard](/logs?api=traces). Set to
- * null to disable tracing. Once tracing is enabled for a session, the configuration cannot
- * be modified.
+ * Realtime API can write session traces to the
+ * [Traces Dashboard](https://platform.openai.com/logs?api=traces). Set to null to disable
+ * tracing. Once tracing is enabled for a session, the configuration cannot be modified.
*
* `auto` will create a trace for the session with default values for the workflow name,
* group id, and metadata.
@@ -6753,9 +6753,9 @@ private constructor(
}
/**
- * Realtime API can write session traces to the [Traces Dashboard](/logs?api=traces). Set to
- * null to disable tracing. Once tracing is enabled for a session, the configuration cannot be
- * modified.
+ * Realtime API can write session traces to the
+ * [Traces Dashboard](https://platform.openai.com/logs?api=traces). Set to null to disable
+ * tracing. Once tracing is enabled for a session, the configuration cannot be modified.
*
* `auto` will create a trace for the session with default values for the workflow name, group
* id, and metadata.
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/filebatches/FileBatchCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/filebatches/FileBatchCreateParams.kt
index ca03a868d..275f87ef5 100644
--- a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/filebatches/FileBatchCreateParams.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/filebatches/FileBatchCreateParams.kt
@@ -61,7 +61,8 @@ private constructor(
* A list of [File](https://platform.openai.com/docs/api-reference/files) IDs that the vector
* store should use. Useful for tools like `file_search` that can access files. If `attributes`
* or `chunking_strategy` are provided, they will be applied to all files in the batch. The
- * maximum batch size is 2000 files. Mutually exclusive with `files`.
+ * maximum batch size is 2000 files. This endpoint is recommended for multi-file ingestion and
+ * helps reduce per-vector-store write request pressure. Mutually exclusive with `files`.
*
* @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the
* server responded with an unexpected value).
@@ -72,7 +73,9 @@ private constructor(
* A list of objects that each include a `file_id` plus optional `attributes` or
* `chunking_strategy`. Use this when you need to override metadata for specific files. The
* global `attributes` or `chunking_strategy` will be ignored and must be specified for each
- * file. The maximum batch size is 2000 files. Mutually exclusive with `file_ids`.
+ * file. The maximum batch size is 2000 files. This endpoint is recommended for multi-file
+ * ingestion and helps reduce per-vector-store write request pressure. Mutually exclusive with
+ * `file_ids`.
*
* @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the
* server responded with an unexpected value).
@@ -228,7 +231,9 @@ private constructor(
* A list of [File](https://platform.openai.com/docs/api-reference/files) IDs that the
* vector store should use. Useful for tools like `file_search` that can access files. If
* `attributes` or `chunking_strategy` are provided, they will be applied to all files in
- * the batch. The maximum batch size is 2000 files. Mutually exclusive with `files`.
+ * the batch. The maximum batch size is 2000 files. This endpoint is recommended for
+ * multi-file ingestion and helps reduce per-vector-store write request pressure. Mutually
+ * exclusive with `files`.
*/
fun fileIds(fileIds: List) = apply { body.fileIds(fileIds) }
@@ -252,7 +257,9 @@ private constructor(
* A list of objects that each include a `file_id` plus optional `attributes` or
* `chunking_strategy`. Use this when you need to override metadata for specific files. The
* global `attributes` or `chunking_strategy` will be ignored and must be specified for each
- * file. The maximum batch size is 2000 files. Mutually exclusive with `file_ids`.
+ * file. The maximum batch size is 2000 files. This endpoint is recommended for multi-file
+ * ingestion and helps reduce per-vector-store write request pressure. Mutually exclusive
+ * with `file_ids`.
*/
fun files(files: List) = apply { body.files(files) }
@@ -465,7 +472,9 @@ private constructor(
* A list of [File](https://platform.openai.com/docs/api-reference/files) IDs that the
* vector store should use. Useful for tools like `file_search` that can access files. If
* `attributes` or `chunking_strategy` are provided, they will be applied to all files in
- * the batch. The maximum batch size is 2000 files. Mutually exclusive with `files`.
+ * the batch. The maximum batch size is 2000 files. This endpoint is recommended for
+ * multi-file ingestion and helps reduce per-vector-store write request pressure. Mutually
+ * exclusive with `files`.
*
* @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the
* server responded with an unexpected value).
@@ -476,7 +485,9 @@ private constructor(
* A list of objects that each include a `file_id` plus optional `attributes` or
* `chunking_strategy`. Use this when you need to override metadata for specific files. The
* global `attributes` or `chunking_strategy` will be ignored and must be specified for each
- * file. The maximum batch size is 2000 files. Mutually exclusive with `file_ids`.
+ * file. The maximum batch size is 2000 files. This endpoint is recommended for multi-file
+ * ingestion and helps reduce per-vector-store write request pressure. Mutually exclusive
+ * with `file_ids`.
*
* @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the
* server responded with an unexpected value).
@@ -623,8 +634,9 @@ private constructor(
* A list of [File](https://platform.openai.com/docs/api-reference/files) IDs that the
* vector store should use. Useful for tools like `file_search` that can access files.
* If `attributes` or `chunking_strategy` are provided, they will be applied to all
- * files in the batch. The maximum batch size is 2000 files. Mutually exclusive with
- * `files`.
+ * files in the batch. The maximum batch size is 2000 files. This endpoint is
+ * recommended for multi-file ingestion and helps reduce per-vector-store write request
+ * pressure. Mutually exclusive with `files`.
*/
fun fileIds(fileIds: List) = fileIds(JsonField.of(fileIds))
@@ -655,8 +667,9 @@ private constructor(
* A list of objects that each include a `file_id` plus optional `attributes` or
* `chunking_strategy`. Use this when you need to override metadata for specific files.
* The global `attributes` or `chunking_strategy` will be ignored and must be specified
- * for each file. The maximum batch size is 2000 files. Mutually exclusive with
- * `file_ids`.
+ * for each file. The maximum batch size is 2000 files. This endpoint is recommended for
+ * multi-file ingestion and helps reduce per-vector-store write request pressure.
+ * Mutually exclusive with `file_ids`.
*/
fun files(files: List) = files(JsonField.of(files))
@@ -902,7 +915,10 @@ private constructor(
/**
* A [File](https://platform.openai.com/docs/api-reference/files) ID that the vector store
- * should use. Useful for tools like `file_search` that can access files.
+ * should use. Useful for tools like `file_search` that can access files. For multi-file
+ * ingestion, we recommend
+ * [`file_batches`](https://platform.openai.com/docs/api-reference/vector-stores-file-batches/createBatch)
+ * to minimize per-vector-store write requests.
*
* @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).
@@ -1000,7 +1016,10 @@ private constructor(
/**
* A [File](https://platform.openai.com/docs/api-reference/files) ID that the vector
- * store should use. Useful for tools like `file_search` that can access files.
+ * store should use. Useful for tools like `file_search` that can access files. For
+ * multi-file ingestion, we recommend
+ * [`file_batches`](https://platform.openai.com/docs/api-reference/vector-stores-file-batches/createBatch)
+ * to minimize per-vector-store write requests.
*/
fun fileId(fileId: String) = fileId(JsonField.of(fileId))
diff --git a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileCreateParams.kt
index c31d297d6..e5f7cddbc 100644
--- a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileCreateParams.kt
+++ b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileCreateParams.kt
@@ -42,7 +42,10 @@ private constructor(
/**
* A [File](https://platform.openai.com/docs/api-reference/files) ID that the vector store
- * should use. Useful for tools like `file_search` that can access files.
+ * should use. Useful for tools like `file_search` that can access files. For multi-file
+ * ingestion, we recommend
+ * [`file_batches`](https://platform.openai.com/docs/api-reference/vector-stores-file-batches/createBatch)
+ * to minimize per-vector-store write requests.
*
* @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).
@@ -149,7 +152,10 @@ private constructor(
/**
* A [File](https://platform.openai.com/docs/api-reference/files) ID that the vector store
- * should use. Useful for tools like `file_search` that can access files.
+ * should use. Useful for tools like `file_search` that can access files. For multi-file
+ * ingestion, we recommend
+ * [`file_batches`](https://platform.openai.com/docs/api-reference/vector-stores-file-batches/createBatch)
+ * to minimize per-vector-store write requests.
*/
fun fileId(fileId: String) = apply { body.fileId(fileId) }
@@ -397,7 +403,10 @@ private constructor(
/**
* A [File](https://platform.openai.com/docs/api-reference/files) ID that the vector store
- * should use. Useful for tools like `file_search` that can access files.
+ * should use. Useful for tools like `file_search` that can access files. For multi-file
+ * ingestion, we recommend
+ * [`file_batches`](https://platform.openai.com/docs/api-reference/vector-stores-file-batches/createBatch)
+ * to minimize per-vector-store write requests.
*
* @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).
@@ -495,7 +504,10 @@ private constructor(
/**
* A [File](https://platform.openai.com/docs/api-reference/files) ID that the vector
- * store should use. Useful for tools like `file_search` that can access files.
+ * store should use. Useful for tools like `file_search` that can access files. For
+ * multi-file ingestion, we recommend
+ * [`file_batches`](https://platform.openai.com/docs/api-reference/vector-stores-file-batches/createBatch)
+ * to minimize per-vector-store write requests.
*/
fun fileId(fileId: String) = fileId(JsonField.of(fileId))
diff --git a/openai-java-core/src/test/kotlin/com/openai/models/conversations/MessageTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/conversations/MessageTest.kt
index 8de929c5b..db242e069 100644
--- a/openai-java-core/src/test/kotlin/com/openai/models/conversations/MessageTest.kt
+++ b/openai-java-core/src/test/kotlin/com/openai/models/conversations/MessageTest.kt
@@ -18,6 +18,7 @@ internal class MessageTest {
.addInputTextContent("text")
.role(Message.Role.UNKNOWN)
.status(Message.Status.IN_PROGRESS)
+ .phase(Message.Phase.COMMENTARY)
.build()
assertThat(message.id()).isEqualTo("id")
@@ -27,6 +28,7 @@ internal class MessageTest {
)
assertThat(message.role()).isEqualTo(Message.Role.UNKNOWN)
assertThat(message.status()).isEqualTo(Message.Status.IN_PROGRESS)
+ assertThat(message.phase()).contains(Message.Phase.COMMENTARY)
}
@Test
@@ -38,6 +40,7 @@ internal class MessageTest {
.addInputTextContent("text")
.role(Message.Role.UNKNOWN)
.status(Message.Status.IN_PROGRESS)
+ .phase(Message.Phase.COMMENTARY)
.build()
val roundtrippedMessage =
diff --git a/openai-java-core/src/test/kotlin/com/openai/models/conversations/items/ConversationItemListTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/conversations/items/ConversationItemListTest.kt
index 59b6bcc23..135473c92 100644
--- a/openai-java-core/src/test/kotlin/com/openai/models/conversations/items/ConversationItemListTest.kt
+++ b/openai-java-core/src/test/kotlin/com/openai/models/conversations/items/ConversationItemListTest.kt
@@ -20,6 +20,7 @@ internal class ConversationItemListTest {
.addInputTextContent("text")
.role(Message.Role.UNKNOWN)
.status(Message.Status.IN_PROGRESS)
+ .phase(Message.Phase.COMMENTARY)
.build()
)
.firstId("first_id")
@@ -35,6 +36,7 @@ internal class ConversationItemListTest {
.addInputTextContent("text")
.role(Message.Role.UNKNOWN)
.status(Message.Status.IN_PROGRESS)
+ .phase(Message.Phase.COMMENTARY)
.build()
)
)
@@ -54,6 +56,7 @@ internal class ConversationItemListTest {
.addInputTextContent("text")
.role(Message.Role.UNKNOWN)
.status(Message.Status.IN_PROGRESS)
+ .phase(Message.Phase.COMMENTARY)
.build()
)
.firstId("first_id")
diff --git a/openai-java-core/src/test/kotlin/com/openai/models/conversations/items/ConversationItemTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/conversations/items/ConversationItemTest.kt
index 80f794850..f075ef029 100644
--- a/openai-java-core/src/test/kotlin/com/openai/models/conversations/items/ConversationItemTest.kt
+++ b/openai-java-core/src/test/kotlin/com/openai/models/conversations/items/ConversationItemTest.kt
@@ -45,6 +45,7 @@ internal class ConversationItemTest {
.addInputTextContent("text")
.role(Message.Role.UNKNOWN)
.status(Message.Status.IN_PROGRESS)
+ .phase(Message.Phase.COMMENTARY)
.build()
val conversationItem = ConversationItem.ofMessage(message)
@@ -86,6 +87,7 @@ internal class ConversationItemTest {
.addInputTextContent("text")
.role(Message.Role.UNKNOWN)
.status(Message.Status.IN_PROGRESS)
+ .phase(Message.Phase.COMMENTARY)
.build()
)
diff --git a/scripts/mock b/scripts/mock
index 9ecceca0a..886f2ffc1 100755
--- a/scripts/mock
+++ b/scripts/mock
@@ -22,9 +22,9 @@ echo "==> Starting mock server with URL ${URL}"
# Run steady mock on the given spec
if [ "$1" == "--daemon" ]; then
# Pre-install the package so the download doesn't eat into the startup timeout
- npm exec --package=@stdy/cli@0.19.7 -- steady --version
+ npm exec --package=@stdy/cli@0.20.2 -- steady --version
- npm exec --package=@stdy/cli@0.19.7 -- steady --host 127.0.0.1 -p 4010 --validator-form-array-format=brackets --validator-query-array-format=brackets --validator-form-object-format=brackets --validator-query-object-format=brackets "$URL" &> .stdy.log &
+ npm exec --package=@stdy/cli@0.20.2 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=brackets --validator-form-array-format=brackets --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" &> .stdy.log &
# Wait for server to come online via health endpoint (max 30s)
echo -n "Waiting for server"
@@ -48,5 +48,5 @@ if [ "$1" == "--daemon" ]; then
echo
else
- npm exec --package=@stdy/cli@0.19.7 -- steady --host 127.0.0.1 -p 4010 --validator-form-array-format=brackets --validator-query-array-format=brackets --validator-form-object-format=brackets --validator-query-object-format=brackets "$URL"
+ npm exec --package=@stdy/cli@0.20.2 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=brackets --validator-form-array-format=brackets --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL"
fi
diff --git a/scripts/test b/scripts/test
index 728c9521e..30e9cdf41 100755
--- a/scripts/test
+++ b/scripts/test
@@ -43,7 +43,7 @@ elif ! steady_is_running ; then
echo -e "To run the server, pass in the path or url of your OpenAPI"
echo -e "spec to the steady command:"
echo
- echo -e " \$ ${YELLOW}npm exec --package=@stdy/cli@0.19.7 -- steady path/to/your.openapi.yml --host 127.0.0.1 -p 4010 --validator-form-array-format=brackets --validator-query-array-format=brackets --validator-form-object-format=brackets --validator-query-object-format=brackets${NC}"
+ echo -e " \$ ${YELLOW}npm exec --package=@stdy/cli@0.20.2 -- steady path/to/your.openapi.yml --host 127.0.0.1 -p 4010 --validator-query-array-format=brackets --validator-form-array-format=brackets --validator-query-object-format=brackets --validator-form-object-format=brackets${NC}"
echo
exit 1