Skip to content

Commit c960b74

Browse files
release: 3.3.0 (#606)
* feat(client): support verbosity with structured outputs (#603) * verbosity: structured output support for verbosity #576 * verbosity: minor doc fixes * release: 3.3.0 --------- Co-authored-by: D Gardner <[email protected]> Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com>
1 parent d207fb4 commit c960b74

17 files changed

+487
-36
lines changed

.release-please-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
".": "3.2.1"
2+
".": "3.3.0"
33
}

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Changelog
22

3+
## 3.3.0 (2025-09-03)
4+
5+
Full Changelog: [v3.2.1...v3.3.0](https://github.com/openai/openai-java/compare/v3.2.1...v3.3.0)
6+
7+
### Features
8+
9+
* **client:** support verbosity with structured outputs ([#603](https://github.com/openai/openai-java/issues/603)) ([2496464](https://github.com/openai/openai-java/commit/24964646ab02a3ff61efb9802facac66b204bdaf))
10+
311
## 3.2.1 (2025-09-02)
412

513
Full Changelog: [v3.2.0...v3.2.1](https://github.com/openai/openai-java/compare/v3.2.0...v3.2.1)

README.md

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22

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

5-
[![Maven Central](https://img.shields.io/maven-central/v/com.openai/openai-java)](https://central.sonatype.com/artifact/com.openai/openai-java/3.2.1)
6-
[![javadoc](https://javadoc.io/badge2/com.openai/openai-java/3.2.1/javadoc.svg)](https://javadoc.io/doc/com.openai/openai-java/3.2.1)
5+
[![Maven Central](https://img.shields.io/maven-central/v/com.openai/openai-java)](https://central.sonatype.com/artifact/com.openai/openai-java/3.3.0)
6+
[![javadoc](https://javadoc.io/badge2/com.openai/openai-java/3.3.0/javadoc.svg)](https://javadoc.io/doc/com.openai/openai-java/3.3.0)
77

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

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

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

14-
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.2.1).
14+
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.3.0).
1515

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

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

2626
```kotlin
27-
implementation("com.openai:openai-java:3.2.1")
27+
implementation("com.openai:openai-java:3.3.0")
2828
```
2929

3030
### Maven
@@ -33,7 +33,7 @@ implementation("com.openai:openai-java:3.2.1")
3333
<dependency>
3434
<groupId>com.openai</groupId>
3535
<artifactId>openai-java</artifactId>
36-
<version>3.2.1</version>
36+
<version>3.3.0</version>
3737
</dependency>
3838
```
3939

@@ -565,6 +565,18 @@ the latter when `ResponseCreateParams.Builder.text(Class<T>)` is called.
565565
For a full example of the usage of _Structured Outputs_ with the Responses API, see
566566
[`ResponsesStructuredOutputsExample`](openai-java-example/src/main/java/com/openai/example/ResponsesStructuredOutputsExample.java).
567567

568+
Instead of using `ResponseCreateParams.text(Class<T>)`, you can build a
569+
[`StructuredResponseTextConfig`](openai-java-core/src/main/kotlin/com/openai/models/responses/StructuredResponseTextConfig.kt)
570+
and set it on the `ResponseCreateParams` using the `text(StructuredResponseTextConfig)` method.
571+
Similar to using `ResponseCreateParams`, you can start with a `ResponseTextConfig.Builder` and its
572+
`format(Class<T>)` method will change it to a `StructuredResponseTextConfig.Builder`. This also
573+
allows you to set the `verbosity` configuration parameter on the text configuration before adding it
574+
to the `ResponseCreateParams`.
575+
576+
For a full example of the usage of _Structured Outputs_ with the `ResponseTextConfig` and its
577+
`verbosity` parameter, see
578+
[`ResponsesStructuredOutputsVerbosityExample`](openai-java-example/src/main/java/com/openai/example/ResponsesStructuredOutputsVerbosityExample.java).
579+
568580
### Usage with streaming
569581

570582
_Structured Outputs_ can also be used with [Streaming](#streaming) and the Chat Completions API. As
@@ -1330,7 +1342,7 @@ If you're using Spring Boot, then you can use the SDK's [Spring Boot starter](ht
13301342
#### Gradle
13311343

13321344
```kotlin
1333-
implementation("com.openai:openai-java-spring-boot-starter:3.2.1")
1345+
implementation("com.openai:openai-java-spring-boot-starter:3.3.0")
13341346
```
13351347

13361348
#### Maven
@@ -1339,7 +1351,7 @@ implementation("com.openai:openai-java-spring-boot-starter:3.2.1")
13391351
<dependency>
13401352
<groupId>com.openai</groupId>
13411353
<artifactId>openai-java-spring-boot-starter</artifactId>
1342-
<version>3.2.1</version>
1354+
<version>3.3.0</version>
13431355
</dependency>
13441356
```
13451357

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ repositories {
88

99
allprojects {
1010
group = "com.openai"
11-
version = "3.2.1" // x-release-please-version
11+
version = "3.3.0" // x-release-please-version
1212
}
1313

1414
subprojects {

openai-java-core/src/main/kotlin/com/openai/core/JsonSchemaValidator.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ internal class JsonSchemaValidator private constructor() {
312312

313313
/**
314314
* Validates a schema if it has an `"anyOf"` field. OpenAI does not support the use of `"anyOf"`
315-
* at the root of a JSON schema. The value is the field is expected to be an array of valid
315+
* at the root of a JSON schema. The value of the field is expected to be an array of valid
316316
* sub-schemas. If the schema has no `"anyOf"` field, no action is taken.
317317
*/
318318
private fun validateAnyOfSchema(schema: JsonNode, path: String, depth: Int) {

openai-java-core/src/main/kotlin/com/openai/core/StructuredOutputs.kt

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,20 @@ internal fun validateSchema(
8585
return schema
8686
}
8787

88+
/** Builds a text configuration's JSON schema, deriving it from the structure of a class. */
89+
@JvmSynthetic
90+
internal fun jsonSchemaFromClass(
91+
type: Class<*>,
92+
localValidation: JsonSchemaLocalValidation = JsonSchemaLocalValidation.YES,
93+
): ResponseFormatTextJsonSchemaConfig =
94+
ResponseFormatTextJsonSchemaConfig.builder()
95+
.name("json-schema-from-${type.simpleName}")
96+
.schema(JsonValue.fromJsonNode(validateSchema(extractSchema(type), type, localValidation)))
97+
// Ensure the model's output strictly adheres to this JSON schema. This is the essential
98+
// "ON switch" for Structured Outputs.
99+
.strict(true)
100+
.build()
101+
88102
/**
89103
* Builds a text configuration with its format set to a JSON schema derived from the structure of an
90104
* arbitrary Java class.
@@ -94,21 +108,7 @@ internal fun textConfigFromClass(
94108
type: Class<*>,
95109
localValidation: JsonSchemaLocalValidation = JsonSchemaLocalValidation.YES,
96110
): ResponseTextConfig =
97-
ResponseTextConfig.builder()
98-
.format(
99-
ResponseFormatTextJsonSchemaConfig.builder()
100-
.name("json-schema-from-${type.simpleName}")
101-
.schema(
102-
JsonValue.fromJsonNode(
103-
validateSchema(extractSchema(type), type, localValidation)
104-
)
105-
)
106-
// Ensure the model's output strictly adheres to this JSON schema. This is the
107-
// essential "ON switch" for Structured Outputs.
108-
.strict(true)
109-
.build()
110-
)
111-
.build()
111+
ResponseTextConfig.builder().format(jsonSchemaFromClass(type, localValidation)).build()
112112

113113
// "internal" instead of "private" for testing purposes.
114114
internal data class FunctionInfo(

openai-java-core/src/main/kotlin/com/openai/models/chat/completions/ChatCompletionMessageFunctionToolCall.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ private constructor(
267267
* Gets the arguments to the function call, converting the values from the model in JSON
268268
* format to an instance of a class that holds those values. The class must previously have
269269
* been used to define the JSON schema for the function definition's parameters, so that the
270-
* JSON corresponds to structure of the given class.
270+
* JSON corresponds to the structure of the given class.
271271
*
272272
* @throws OpenAIInvalidDataException If the JSON data is missing, `null`, or cannot be
273273
* parsed to an instance of the [functionParametersType] class. This might occur if the

openai-java-core/src/main/kotlin/com/openai/models/chat/completions/StructuredChatCompletionCreateParams.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import java.util.Optional
1515
/**
1616
* A wrapper for [ChatCompletionCreateParams] that provides a type-safe [Builder] that can record
1717
* the [responseType] used to derive a JSON schema from an arbitrary class when using the
18-
* _Structured Outputs_ feature. When a JSON response is received, it is deserialized to am instance
18+
* _Structured Outputs_ feature. When a JSON response is received, it is deserialized to an instance
1919
* of that type. See the SDK documentation for more details on _Structured Outputs_.
2020
*
2121
* @param T The type of the class that will be used to derive the JSON schema in the request and to

openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseCreateParams.kt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,6 +1098,8 @@ private constructor(
10981098
* [StructuredResponseCreateParams.Builder] that will build a
10991099
* [StructuredResponseCreateParams] instance when `build()` is called.
11001100
*
1101+
* Use this method or the `text(StructuredResponseTextConfig<T>)` method, but not both.
1102+
*
11011103
* @param responseType A class from which a JSON schema will be derived to define the text
11021104
* configuration's format.
11031105
* @param localValidation [JsonSchemaLocalValidation.YES] (the default) to validate the JSON
@@ -1114,6 +1116,21 @@ private constructor(
11141116
localValidation: JsonSchemaLocalValidation = JsonSchemaLocalValidation.YES,
11151117
) = StructuredResponseCreateParams.builder<T>().wrap(responseType, this, localValidation)
11161118

1119+
/**
1120+
* Sets the text configuration to a [StructuredResponseTextConfig] where the format was set
1121+
* to a JSON schema derived from the structure of a class. This changes the builder to a
1122+
* type-safe [StructuredResponseCreateParams.Builder] that will build a
1123+
* [StructuredResponseCreateParams] instance when `build()` is called.
1124+
*
1125+
* Use this method or the `text(Class<T>)` method, but not both.
1126+
*
1127+
* @param text A text configuration in which the JSON schema defining the format was derived
1128+
* from the structure of a class. The `verbosity` parameter can also be set on the text
1129+
* configuration, if required.
1130+
*/
1131+
fun <T : Any> text(text: StructuredResponseTextConfig<T>) =
1132+
StructuredResponseCreateParams.builder<T>().wrap(text, this)
1133+
11171134
/**
11181135
* How the model should select which tool (or tools) to use when generating a response. See
11191136
* the `tools` parameter to see how to specify which tools the model can call.

openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseTextConfig.kt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import com.openai.core.Enum
1010
import com.openai.core.ExcludeMissing
1111
import com.openai.core.JsonField
1212
import com.openai.core.JsonMissing
13+
import com.openai.core.JsonSchemaLocalValidation
1314
import com.openai.core.JsonValue
1415
import com.openai.errors.OpenAIInvalidDataException
1516
import com.openai.models.ResponseFormatJsonObject
@@ -157,6 +158,28 @@ private constructor(
157158
fun format(jsonObject: ResponseFormatJsonObject) =
158159
format(ResponseFormatTextConfig.ofJsonObject(jsonObject))
159160

161+
/**
162+
* Sets the text configuration's format to a JSON schema derived from the structure of the
163+
* given class. This changes the builder to a type-safe
164+
* [StructuredResponseTextConfig.Builder] that will build a [StructuredResponseTextConfig]
165+
* instance when `build()` is called.
166+
*
167+
* @param responseType A class from which a JSON schema will be derived to define the text
168+
* configuration's format.
169+
* @param localValidation [JsonSchemaLocalValidation.YES] (the default) to validate the JSON
170+
* schema locally when it is generated by this method to confirm that it adheres to the
171+
* requirements and restrictions on JSON schemas imposed by the OpenAI specification; or
172+
* [JsonSchemaLocalValidation.NO] to skip local validation and rely only on remote
173+
* validation. See the SDK documentation for more details.
174+
* @throws IllegalArgumentException If local validation is enabled, but it fails because a
175+
* valid JSON schema cannot be derived from the given class.
176+
*/
177+
@JvmOverloads
178+
fun <T : Any> format(
179+
responseType: Class<T>,
180+
localValidation: JsonSchemaLocalValidation = JsonSchemaLocalValidation.YES,
181+
) = StructuredResponseTextConfig.builder<T>().wrap(responseType, this, localValidation)
182+
160183
/**
161184
* Constrains the verbosity of the model's response. Lower values will result in more
162185
* concise responses, while higher values will result in more verbose responses. Currently

0 commit comments

Comments
 (0)