Skip to content

Commit 067258e

Browse files
stainless-app[bot]dtmeadowsTomerAberbachdamo
authored
release: 2.15.0 (#538)
* add draft contributing.md * remove a few things * Apply suggestions from code review Co-authored-by: Tomer Aberbach <[email protected]> * address more comments * Update CONTRIBUTING.md Co-authored-by: Tomer Aberbach <[email protected]> * Apply suggestions from code review Co-authored-by: Tomer Aberbach <[email protected]> * pr comments * chore(internal): allow running specific example from cli * fix(client): ensure error handling always occurs * feat(client): add `ResponseAccumulator` (#391) * response-accumulator: first draft for review. * response-accumulator: added accumulator and documented streaming support. * chore(client): remove non-existent method * release: 2.15.0 --------- Co-authored-by: David Meadows <[email protected]> Co-authored-by: Tomer Aberbach <[email protected]> Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com> Co-authored-by: D Gardner <[email protected]> Co-authored-by: Tomer Aberbach <[email protected]>
1 parent 908c42c commit 067258e

File tree

73 files changed

+2404
-655
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+2404
-655
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-
".": "2.14.0"
2+
".": "2.15.0"
33
}

CHANGELOG.md

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

3+
## 2.15.0 (2025-07-17)
4+
5+
Full Changelog: [v2.14.0...v2.15.0](https://github.com/openai/openai-java/compare/v2.14.0...v2.15.0)
6+
7+
### Features
8+
9+
* **client:** add `ResponseAccumulator` ([#391](https://github.com/openai/openai-java/issues/391)) ([77f54fd](https://github.com/openai/openai-java/commit/77f54fdea8bf0a609f90ec511977531bffc1a9b1))
10+
11+
12+
### Bug Fixes
13+
14+
* **client:** ensure error handling always occurs ([a00c39b](https://github.com/openai/openai-java/commit/a00c39b9b1e06a15fa3a0b2b495adfff86cddd10))
15+
16+
17+
### Chores
18+
19+
* **client:** remove non-existent method ([2d185ba](https://github.com/openai/openai-java/commit/2d185ba387569d90ffffa07adf3337ffce918e3e))
20+
* **internal:** Add CONTRIBUTING.md for SDK developers ([608947c](https://github.com/openai/openai-java/commit/608947cd875167c5aa2beb65cf98f47050914b71))
21+
* **internal:** allow running specific example from cli ([3239c2d](https://github.com/openai/openai-java/commit/3239c2de360864456786043a2a3ffb1a71ac0a45))
22+
323
## 2.14.0 (2025-07-16)
424

525
Full Changelog: [v2.13.1...v2.14.0](https://github.com/openai/openai-java/compare/v2.13.1...v2.14.0)

CONTRIBUTING.md

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
# Contributing to OpenAI Java SDK
2+
3+
## Setting up the environment
4+
5+
This repository uses [Gradle](https://gradle.org/) with Kotlin DSL for building and dependency management. The SDK requires Java 8, but development requires JDK 21 for the Kotlin toolchain.
6+
7+
## Project structure
8+
9+
The SDK consists of three artifacts:
10+
11+
- `openai-java-core`
12+
- Contains core SDK logic
13+
- Does not depend on [OkHttp](https://square.github.io/okhttp)
14+
- Exposes [`OpenAIClient`](openai-java-core/src/main/kotlin/com/openai/client/OpenAIClient.kt), [`OpenAIClientAsync`](openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientAsync.kt), [`OpenAIClientImpl`](openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientImpl.kt), and [`OpenAIClientAsyncImpl`](openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientAsyncImpl.kt), all of which can work with any HTTP client
15+
- `openai-java-client-okhttp`
16+
- Depends on [OkHttp](https://square.github.io/okhttp)
17+
- Exposes [`OpenAIOkHttpClient`](openai-java-client-okhttp/src/main/kotlin/com/openai/client/okhttp/OpenAIOkHttpClient.kt) and [`OpenAIOkHttpClientAsync`](openai-java-client-okhttp/src/main/kotlin/com/openai/client/okhttp/OpenAIOkHttpClientAsync.kt), which provide a way to construct [`OpenAIClientImpl`](openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientImpl.kt) and [`OpenAIClientAsyncImpl`](openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientAsyncImpl.kt), respectively, using OkHttp
18+
- `openai-java`
19+
- Depends on and exposes the APIs of both `openai-java-core` and `openai-java-client-okhttp`
20+
- Does not have its own logic
21+
22+
## Modifying or adding code
23+
24+
Most of the SDK is generated code. Modifications to code will be persisted between generations, but may
25+
result in merge conflicts between manual patches and changes from the generator. The generator will never
26+
modify the contents of the `openai-java-example/` directory.
27+
28+
## Adding and running examples
29+
30+
All files in the `openai-java-example/` directory are not modified by the generator and can be freely edited or added to.
31+
32+
```java
33+
// openai-java-example/src/main/java/com/openai/example/YourExample.java
34+
package com.openai.example;
35+
36+
public class YourExample {
37+
public static void main(String[] args) {
38+
// ...
39+
}
40+
}
41+
```
42+
43+
```sh
44+
$ ./gradlew :openai-java-example:run -PmainClass=com.openai.example.YourExample
45+
```
46+
47+
## Using the repository from source
48+
49+
If you'd like to use the repository from source, you can either [install from git](https://jitpack.io/) or link to a cloned repository.
50+
51+
To use a local version of this library from source in another project, you can publish it to your local Maven repository:
52+
53+
```sh
54+
$ ./gradlew publishToMavenLocal
55+
```
56+
57+
> [!NOTE]
58+
> For now, to publish locally, you'll need to comment out the line for `signAllPublications()` here: `buildSrc/src/main/kotlin/openai.publish.gradle.kts`
59+
60+
Then in your project's `build.gradle.kts` or `pom.xml`, reference the locally published version:
61+
62+
<!-- x-release-please-start-version -->
63+
64+
```kotlin
65+
implementation("com.openai:openai-java:2.9.1")
66+
```
67+
68+
```xml
69+
<dependency>
70+
<groupId>com.openai</groupId>
71+
<artifactId>openai-java</artifactId>
72+
<version>2.9.1</version>
73+
</dependency>
74+
```
75+
76+
<!-- x-release-please-end -->
77+
78+
Alternatively, you can build and install the JAR files directly:
79+
80+
```sh
81+
$ ./gradlew build
82+
```
83+
84+
JAR files will be available in each module's `build/libs/` directory.
85+
86+
## Running tests
87+
88+
Most tests require [our mock server](https://github.com/stoplightio/prism) to be running against the OpenAPI spec to work.
89+
90+
The test script will automatically start the mock server for you (if it's not already running) and run the tests against it:
91+
92+
```sh
93+
$ ./scripts/test
94+
```
95+
96+
You can also manually start the mock server if you want to run tests repeatedly:
97+
98+
```sh
99+
$ ./scripts/mock
100+
```
101+
102+
Then run the tests:
103+
104+
```sh
105+
$ ./scripts/test
106+
107+
```
108+
109+
### Test configuration
110+
111+
- Tests run in parallel for better performance
112+
- Mock server runs on `localhost:4010`
113+
- You can disable mock server tests with `SKIP_MOCK_TESTS=true`
114+
- You can target a custom API URL with `TEST_API_BASE_URL=<url>`
115+
116+
### Testing framework
117+
118+
The project uses:
119+
120+
- **JUnit 5** for test framework
121+
- **Mockito** for mocking
122+
- **AssertJ** for fluent assertions
123+
- **WireMock** for HTTP service mocking
124+
- **Custom TestServerExtension** for mock server management
125+
126+
## Linting and formatting
127+
128+
This repository uses [Spotless](https://github.com/diffplug/spotless) with Palantir Java Format for code formatting and various linting tools.
129+
130+
To check formatting and run lints:
131+
132+
```sh
133+
$ ./scripts/lint
134+
```
135+
136+
This will compile all modules and run static analysis checks.
137+
138+
To fix all formatting issues automatically:
139+
140+
```sh
141+
$ ./scripts/format
142+
```
143+
144+
You can also check formatting directly with Gradle:
145+
146+
```sh
147+
$ ./gradlew spotlessCheck # Check formatting
148+
```
149+
150+
## Building
151+
152+
To build all modules:
153+
154+
```sh
155+
$ ./gradlew build
156+
```
157+
158+
To build a specific module:
159+
160+
```sh
161+
$ ./gradlew :openai-java-core:build
162+
```
163+
164+
## Adding and running examples
165+
166+
All files in the `openai-java-example/` directory are not modified by the generator and can be freely edited or added to.
167+
168+
```java
169+
// add an example to openai-java-example/src/main/java/com/openai/example/<YourExample>.java
170+
171+
package com.openai.example;
172+
173+
public class YourExample {
174+
public static void main(String[] args) {
175+
// ...
176+
}
177+
}
178+
```
179+
180+
## Publishing and releases
181+
182+
Changes made to this repository via the automated release PR pipeline should publish to Maven Central automatically. If
183+
the changes aren't made through the automated pipeline, you may want to make releases manually.
184+
185+
### Publish with a GitHub workflow
186+
187+
You can release to package managers by using [the `Publish Sonatype` GitHub action](https://www.github.com/openai/openai-java/actions/workflows/publish-sonatype.yml). This requires setup organization or repository secrets to be configured.
188+
189+
### Publish manually
190+
191+
If you need to manually release a package, you can run:
192+
193+
```sh
194+
$ ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository
195+
```
196+
197+
This requires the following environment variables to be set:
198+
199+
- `SONATYPE_USER` - Your Sonatype Central Portal username
200+
- `SONATYPE_PASSWORD` - Your Sonatype Central Portal password
201+
- `GPG_SIGNING_KEY` - Your GPG private key for signing artifacts
202+
- `GPG_SIGNING_PASSWORD` - Your GPG key passphrase
203+
204+
## Development tools
205+
206+
### Available gradle tasks
207+
208+
Some useful Gradle tasks:
209+
210+
```sh
211+
$ ./gradlew tasks # List all available tasks
212+
$ ./gradlew build # Build all modules
213+
$ ./gradlew test # Run all tests
214+
$ ./gradlew spotlessApply # Format code
215+
$ ./gradlew publishToMavenLocal # Publish to local Maven repository
216+
$ ./gradlew dependencies # Show dependency tree
217+
```

README.md

Lines changed: 62 additions & 10 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/2.14.0)
6-
[![javadoc](https://javadoc.io/badge2/com.openai/openai-java/2.14.0/javadoc.svg)](https://javadoc.io/doc/com.openai/openai-java/2.14.0)
5+
[![Maven Central](https://img.shields.io/maven-central/v/com.openai/openai-java)](https://central.sonatype.com/artifact/com.openai/openai-java/2.15.0)
6+
[![javadoc](https://javadoc.io/badge2/com.openai/openai-java/2.15.0/javadoc.svg)](https://javadoc.io/doc/com.openai/openai-java/2.15.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/2.14.0).
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/2.15.0).
1515

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

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

2424
```kotlin
25-
implementation("com.openai:openai-java:2.14.0")
25+
implementation("com.openai:openai-java:2.15.0")
2626
```
2727

2828
### Maven
@@ -31,7 +31,7 @@ implementation("com.openai:openai-java:2.14.0")
3131
<dependency>
3232
<groupId>com.openai</groupId>
3333
<artifactId>openai-java</artifactId>
34-
<version>2.14.0</version>
34+
<version>2.15.0</version>
3535
</dependency>
3636
```
3737

@@ -350,6 +350,53 @@ client.chat()
350350
ChatCompletion chatCompletion = chatCompletionAccumulator.chatCompletion();
351351
```
352352

353+
The SDK provides conveniences for streamed responses. A
354+
[`ResponseAccumulator`](openai-java-core/src/main/kotlin/com/openai/helpers/ResponseAccumulator.kt)
355+
can record the stream of response events as they are processed and accumulate a
356+
[`Response`](openai-java-core/src/main/kotlin/com/openai/models/responses/Response.kt)
357+
object similar to that which would have been returned by the non-streaming API.
358+
359+
For a synchronous response add a
360+
[`Stream.peek()`](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#peek-java.util.function.Consumer-)
361+
call to the stream pipeline to accumulate each event:
362+
363+
```java
364+
import com.openai.core.http.StreamResponse;
365+
import com.openai.helpers.ResponseAccumulator;
366+
import com.openai.models.responses.Response;
367+
import com.openai.models.responses.ResponseStreamEvent;
368+
369+
ResponseAccumulator responseAccumulator = ResponseAccumulator.create();
370+
371+
try (StreamResponse<ResponseStreamEvent> streamResponse =
372+
client.responses().createStreaming(createParams)) {
373+
streamResponse.stream()
374+
.peek(responseAccumulator::accumulate)
375+
.flatMap(event -> event.outputTextDelta().stream())
376+
.forEach(textEvent -> System.out.print(textEvent.delta()));
377+
}
378+
379+
Response response = responseAccumulator.response();
380+
```
381+
382+
For an asynchronous response, add the `ResponseAccumulator` to the `subscribe()` call:
383+
384+
```java
385+
import com.openai.helpers.ResponseAccumulator;
386+
import com.openai.models.responses.Response;
387+
388+
ResponseAccumulator responseAccumulator = ResponseAccumulator.create();
389+
390+
client.responses()
391+
.createStreaming(createParams)
392+
.subscribe(event -> responseAccumulator.accumulate(event)
393+
.outputTextDelta().ifPresent(textEvent -> System.out.print(textEvent.delta())))
394+
.onCompleteFuture()
395+
.join();
396+
397+
Response response = responseAccumulator.response();
398+
```
399+
353400
## Structured outputs with JSON schemas
354401

355402
Open AI [Structured Outputs](https://platform.openai.com/docs/guides/structured-outputs?api-mode=chat)
@@ -527,11 +574,16 @@ For a full example of the usage of _Structured Outputs_ with Streaming and the C
527574
see
528575
[`StructuredOutputsStreamingExample`](openai-java-example/src/main/java/com/openai/example/StructuredOutputsStreamingExample.java).
529576

530-
At present, there is no accumulator for streaming responses using the Responses API. It is still
531-
possible to derive a JSON schema from a Java class and create a streaming response for a
532-
[`StructuredResponseCreateParams`](openai-java-core/src/main/kotlin/com/openai/models/responses/StructuredResponseCreateParams.kt)
533-
object, but there is no helper for deserialization of the response to an instance of that Java
534-
class.
577+
With the Responses API, accumulate events while streaming using the
578+
[`ResponseAccumulator`](openai-java-core/src/main/kotlin/com/openai/helpers/ResponseAccumulator.kt).
579+
Once accumulated, use `ResponseAccumulator.response(Class<T>)` to convert the accumulated `Response`
580+
into a
581+
[`StructuredResponse`](openai-java-core/src/main/kotlin/com/openai/models/responses/StructuredResponse.kt).
582+
The [`StructuredResponse`] can then automatically deserialize the JSON strings into instances of
583+
your Java class.
584+
585+
For a full example of the usage of _Structured Outputs_ with Streaming and the Responses API, see
586+
[`ResponsesStructuredOutputsStreamingExample`](openai-java-example/src/main/java/com/openai/example/ResponsesStructuredOutputsStreamingExample.java).
535587

536588
### Defining JSON schema properties
537589

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 = "2.14.0" // x-release-please-version
11+
version = "2.15.0" // x-release-please-version
1212
}
1313

1414
subprojects {

0 commit comments

Comments
 (0)