Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "3.7.1"
".": "4.0.0"
}
6 changes: 3 additions & 3 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 118
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-410219ea680089f02bb55163c673919703f946c3d6ad7ff5d6f607121d5287d5.yml
openapi_spec_hash: 2b3eee95d3f6796c7a61dfddf694a59a
config_hash: 666d6bb4b564f0d9d431124b5d1a0665
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-49233088b5e73dbb96bf7af27be3d4547632e3db1c2b00f14184900613325bbc.yml
openapi_spec_hash: b34f14b141d5019244112901c5c7c2d8
config_hash: 94e9ba08201c3d1ca46e093e6a0138fa
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
# Changelog

## 4.0.0 (2025-09-30)

Full Changelog: [v3.7.1...v4.0.0](https://github.com/openai/openai-java/compare/v3.7.1...v4.0.0)

### ⚠ BREAKING CHANGES

* **api:** `ResponseFunctionToolCallOutputItem.output` and `ResponseCustomToolCallOutput.output` now return `string | Array<ResponseInputText | ResponseInputImage | ResponseInputFile>` instead of `string` only. This may break existing callsites that assume `output` is always a string.

### Features

* **api:** Support images and files for function call outputs in responses, BatchUsage ([de7a6c1](https://github.com/openai/openai-java/commit/de7a6c18862af4f94ce7bbc3a3ae447520be5880))


### Bug Fixes

* **client:** remove duplicate outputAsJson function ([4718871](https://github.com/openai/openai-java/commit/4718871e7e281b0a75c914d013e3b644340d5c4b))

## 3.7.1 (2025-09-26)

Full Changelog: [v3.7.0...v3.7.1](https://github.com/openai/openai-java/compare/v3.7.0...v3.7.1)
Expand Down
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@

<!-- x-release-please-start-version -->

[![Maven Central](https://img.shields.io/maven-central/v/com.openai/openai-java)](https://central.sonatype.com/artifact/com.openai/openai-java/3.7.1)
[![javadoc](https://javadoc.io/badge2/com.openai/openai-java/3.7.1/javadoc.svg)](https://javadoc.io/doc/com.openai/openai-java/3.7.1)
[![Maven Central](https://img.shields.io/maven-central/v/com.openai/openai-java)](https://central.sonatype.com/artifact/com.openai/openai-java/4.0.0)
[![javadoc](https://javadoc.io/badge2/com.openai/openai-java/4.0.0/javadoc.svg)](https://javadoc.io/doc/com.openai/openai-java/4.0.0)

<!-- x-release-please-end -->

The OpenAI Java SDK provides convenient access to the [OpenAI REST API](https://platform.openai.com/docs) from applications written in Java.

<!-- x-release-please-start-version -->

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/3.7.1).
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.0.0).

<!-- x-release-please-end -->

Expand All @@ -24,7 +24,7 @@ The REST API documentation can be found on [platform.openai.com](https://platfor
### Gradle

```kotlin
implementation("com.openai:openai-java:3.7.1")
implementation("com.openai:openai-java:4.0.0")
```

### Maven
Expand All @@ -33,7 +33,7 @@ implementation("com.openai:openai-java:3.7.1")
<dependency>
<groupId>com.openai</groupId>
<artifactId>openai-java</artifactId>
<version>3.7.1</version>
<version>4.0.0</version>
</dependency>
```

Expand Down Expand Up @@ -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:3.7.1")
implementation("com.openai:openai-java-spring-boot-starter:4.0.0")
```

#### Maven
Expand All @@ -1351,7 +1351,7 @@ implementation("com.openai:openai-java-spring-boot-starter:3.7.1")
<dependency>
<groupId>com.openai</groupId>
<artifactId>openai-java-spring-boot-starter</artifactId>
<version>3.7.1</version>
<version>4.0.0</version>
</dependency>
```

Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ repositories {

allprojects {
group = "com.openai"
version = "3.7.1" // x-release-please-version
version = "4.0.0" // x-release-please-version
}

subprojects {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@ private constructor(
private val finalizingAt: JsonField<Long>,
private val inProgressAt: JsonField<Long>,
private val metadata: JsonField<Metadata>,
private val model: JsonField<String>,
private val outputFileId: JsonField<String>,
private val requestCounts: JsonField<BatchRequestCounts>,
private val usage: JsonField<BatchUsage>,
private val additionalProperties: MutableMap<String, JsonValue>,
) {

Expand Down Expand Up @@ -82,12 +84,14 @@ private constructor(
@ExcludeMissing
inProgressAt: JsonField<Long> = JsonMissing.of(),
@JsonProperty("metadata") @ExcludeMissing metadata: JsonField<Metadata> = JsonMissing.of(),
@JsonProperty("model") @ExcludeMissing model: JsonField<String> = JsonMissing.of(),
@JsonProperty("output_file_id")
@ExcludeMissing
outputFileId: JsonField<String> = JsonMissing.of(),
@JsonProperty("request_counts")
@ExcludeMissing
requestCounts: JsonField<BatchRequestCounts> = JsonMissing.of(),
@JsonProperty("usage") @ExcludeMissing usage: JsonField<BatchUsage> = JsonMissing.of(),
) : this(
id,
completionWindow,
Expand All @@ -107,8 +111,10 @@ private constructor(
finalizingAt,
inProgressAt,
metadata,
model,
outputFileId,
requestCounts,
usage,
mutableMapOf(),
)

Expand Down Expand Up @@ -262,6 +268,17 @@ private constructor(
*/
fun metadata(): Optional<Metadata> = metadata.getOptional("metadata")

/**
* Model ID used to process the batch, like `gpt-5-2025-08-07`. OpenAI offers a wide range of
* models with different capabilities, performance characteristics, and price points. Refer to
* the [model guide](https://platform.openai.com/docs/models) to browse and compare available
* models.
*
* @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the
* server responded with an unexpected value).
*/
fun model(): Optional<String> = model.getOptional("model")

/**
* The ID of the file containing the outputs of successfully executed requests.
*
Expand All @@ -278,6 +295,15 @@ private constructor(
*/
fun requestCounts(): Optional<BatchRequestCounts> = requestCounts.getOptional("request_counts")

/**
* Represents token usage details including input tokens, output tokens, a breakdown of output
* tokens, and the total tokens used. Only populated on batches created after September 7, 2025.
*
* @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the
* server responded with an unexpected value).
*/
fun usage(): Optional<BatchUsage> = usage.getOptional("usage")

/**
* Returns the raw JSON value of [id].
*
Expand Down Expand Up @@ -410,6 +436,13 @@ private constructor(
*/
@JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField<Metadata> = metadata

/**
* Returns the raw JSON value of [model].
*
* Unlike [model], this method doesn't throw if the JSON field has an unexpected type.
*/
@JsonProperty("model") @ExcludeMissing fun _model(): JsonField<String> = model

/**
* Returns the raw JSON value of [outputFileId].
*
Expand All @@ -428,6 +461,13 @@ private constructor(
@ExcludeMissing
fun _requestCounts(): JsonField<BatchRequestCounts> = requestCounts

/**
* Returns the raw JSON value of [usage].
*
* Unlike [usage], this method doesn't throw if the JSON field has an unexpected type.
*/
@JsonProperty("usage") @ExcludeMissing fun _usage(): JsonField<BatchUsage> = usage

@JsonAnySetter
private fun putAdditionalProperty(key: String, value: JsonValue) {
additionalProperties.put(key, value)
Expand Down Expand Up @@ -479,8 +519,10 @@ private constructor(
private var finalizingAt: JsonField<Long> = JsonMissing.of()
private var inProgressAt: JsonField<Long> = JsonMissing.of()
private var metadata: JsonField<Metadata> = JsonMissing.of()
private var model: JsonField<String> = JsonMissing.of()
private var outputFileId: JsonField<String> = JsonMissing.of()
private var requestCounts: JsonField<BatchRequestCounts> = JsonMissing.of()
private var usage: JsonField<BatchUsage> = JsonMissing.of()
private var additionalProperties: MutableMap<String, JsonValue> = mutableMapOf()

@JvmSynthetic
Expand All @@ -503,8 +545,10 @@ private constructor(
finalizingAt = batch.finalizingAt
inProgressAt = batch.inProgressAt
metadata = batch.metadata
model = batch.model
outputFileId = batch.outputFileId
requestCounts = batch.requestCounts
usage = batch.usage
additionalProperties = batch.additionalProperties.toMutableMap()
}

Expand Down Expand Up @@ -729,6 +773,22 @@ private constructor(
*/
fun metadata(metadata: JsonField<Metadata>) = apply { this.metadata = metadata }

/**
* Model ID used to process the batch, like `gpt-5-2025-08-07`. OpenAI offers a wide range
* of models with different capabilities, performance characteristics, and price points.
* Refer to the [model guide](https://platform.openai.com/docs/models) to browse and compare
* available models.
*/
fun model(model: String) = model(JsonField.of(model))

/**
* Sets [Builder.model] to an arbitrary JSON value.
*
* You should usually call [Builder.model] with a well-typed [String] value instead. This
* method is primarily for setting the field to an undocumented or not yet supported value.
*/
fun model(model: JsonField<String>) = apply { this.model = model }

/** The ID of the file containing the outputs of successfully executed requests. */
fun outputFileId(outputFileId: String) = outputFileId(JsonField.of(outputFileId))

Expand Down Expand Up @@ -758,6 +818,22 @@ private constructor(
this.requestCounts = requestCounts
}

/**
* Represents token usage details including input tokens, output tokens, a breakdown of
* output tokens, and the total tokens used. Only populated on batches created after
* September 7, 2025.
*/
fun usage(usage: BatchUsage) = usage(JsonField.of(usage))

/**
* Sets [Builder.usage] to an arbitrary JSON value.
*
* You should usually call [Builder.usage] with a well-typed [BatchUsage] value instead.
* This method is primarily for setting the field to an undocumented or not yet supported
* value.
*/
fun usage(usage: JsonField<BatchUsage>) = apply { this.usage = usage }

fun additionalProperties(additionalProperties: Map<String, JsonValue>) = apply {
this.additionalProperties.clear()
putAllAdditionalProperties(additionalProperties)
Expand Down Expand Up @@ -814,8 +890,10 @@ private constructor(
finalizingAt,
inProgressAt,
metadata,
model,
outputFileId,
requestCounts,
usage,
additionalProperties.toMutableMap(),
)
}
Expand Down Expand Up @@ -849,8 +927,10 @@ private constructor(
finalizingAt()
inProgressAt()
metadata().ifPresent { it.validate() }
model()
outputFileId()
requestCounts().ifPresent { it.validate() }
usage().ifPresent { it.validate() }
validated = true
}

Expand Down Expand Up @@ -887,8 +967,10 @@ private constructor(
(if (finalizingAt.asKnown().isPresent) 1 else 0) +
(if (inProgressAt.asKnown().isPresent) 1 else 0) +
(metadata.asKnown().getOrNull()?.validity() ?: 0) +
(if (model.asKnown().isPresent) 1 else 0) +
(if (outputFileId.asKnown().isPresent) 1 else 0) +
(requestCounts.asKnown().getOrNull()?.validity() ?: 0)
(requestCounts.asKnown().getOrNull()?.validity() ?: 0) +
(usage.asKnown().getOrNull()?.validity() ?: 0)

/** The current status of the batch. */
class Status @JsonCreator private constructor(private val value: JsonField<String>) : Enum {
Expand Down Expand Up @@ -1378,8 +1460,10 @@ private constructor(
finalizingAt == other.finalizingAt &&
inProgressAt == other.inProgressAt &&
metadata == other.metadata &&
model == other.model &&
outputFileId == other.outputFileId &&
requestCounts == other.requestCounts &&
usage == other.usage &&
additionalProperties == other.additionalProperties
}

Expand All @@ -1403,14 +1487,16 @@ private constructor(
finalizingAt,
inProgressAt,
metadata,
model,
outputFileId,
requestCounts,
usage,
additionalProperties,
)
}

override fun hashCode(): Int = hashCode

override fun toString() =
"Batch{id=$id, completionWindow=$completionWindow, createdAt=$createdAt, endpoint=$endpoint, inputFileId=$inputFileId, object_=$object_, status=$status, cancelledAt=$cancelledAt, cancellingAt=$cancellingAt, completedAt=$completedAt, errorFileId=$errorFileId, errors=$errors, expiredAt=$expiredAt, expiresAt=$expiresAt, failedAt=$failedAt, finalizingAt=$finalizingAt, inProgressAt=$inProgressAt, metadata=$metadata, outputFileId=$outputFileId, requestCounts=$requestCounts, additionalProperties=$additionalProperties}"
"Batch{id=$id, completionWindow=$completionWindow, createdAt=$createdAt, endpoint=$endpoint, inputFileId=$inputFileId, object_=$object_, status=$status, cancelledAt=$cancelledAt, cancellingAt=$cancellingAt, completedAt=$completedAt, errorFileId=$errorFileId, errors=$errors, expiredAt=$expiredAt, expiresAt=$expiresAt, failedAt=$failedAt, finalizingAt=$finalizingAt, inProgressAt=$inProgressAt, metadata=$metadata, model=$model, outputFileId=$outputFileId, requestCounts=$requestCounts, usage=$usage, additionalProperties=$additionalProperties}"
}
Loading