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 @@
{
".": "0.13.0"
".": "0.14.0"
}
28 changes: 28 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,33 @@
# Changelog

## 0.14.0 (2025-01-24)

Full Changelog: [v0.13.0...v0.14.0](https://github.com/openai/openai-java/compare/v0.13.0...v0.14.0)

### ⚠ BREAKING CHANGES

* **client:** better union variant method and variable names ([#157](https://github.com/openai/openai-java/issues/157))

### Features

* **client:** better union variant method and variable names ([#157](https://github.com/openai/openai-java/issues/157)) ([da5bce5](https://github.com/openai/openai-java/commit/da5bce5d00af53d7297133af09352a7176c2f83e))


### Bug Fixes

* examples ([3473781](https://github.com/openai/openai-java/commit/3473781ca26d25531f368485291f9972e600631b))


### Chores

* **internal:** swap `checkNotNull` to `checkRequired` ([#156](https://github.com/openai/openai-java/issues/156)) ([d6f65f7](https://github.com/openai/openai-java/commit/d6f65f7c0e25adbce97b22f7a649f6c3eaeb61ed))


### Documentation

* move up requirements section ([#154](https://github.com/openai/openai-java/issues/154)) ([48fc646](https://github.com/openai/openai-java/commit/48fc646957ad4ff69c93b40d59ea9d5e8a22eece))
* update readme ([#152](https://github.com/openai/openai-java/issues/152)) ([293dc47](https://github.com/openai/openai-java/commit/293dc47b242e204b6c6e419002dbb560cb455169))

## 0.13.0 (2025-01-22)

Full Changelog: [v0.12.0...v0.13.0](https://github.com/openai/openai-java/compare/v0.12.0...v0.13.0)
Expand Down
36 changes: 16 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,43 +9,43 @@

<!-- 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/0.13.0)
[![javadoc](https://javadoc.io/badge2/com.openai/openai-java/0.13.0/javadoc.svg)](https://javadoc.io/doc/com.openai/openai-java/0.13.0)
[![Maven Central](https://img.shields.io/maven-central/v/com.openai/openai-java)](https://central.sonatype.com/artifact/com.openai/openai-java/0.14.0)
[![javadoc](https://javadoc.io/badge2/com.openai/openai-java/0.14.0/javadoc.svg)](https://javadoc.io/doc/com.openai/openai-java/0.14.0)

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

The OpenAI Java SDK provides convenient access to the OpenAI REST API from applications written in Java. It includes helper classes with helpful types and documentation for every request and response property.
The OpenAI Java SDK provides convenient access to the OpenAI REST API from applications written in Java.

## Documentation
The REST API documentation can be found on [platform.openai.com](https://platform.openai.com/docs). Javadocs are also available on [javadoc.io](https://javadoc.io/doc/com.openai/openai-java/0.0.1).

The REST API documentation can be found on [platform.openai.com](https://platform.openai.com/docs).

---

## Getting started

### Install dependencies

#### Gradle
## Installation

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

### Gradle

```kotlin
implementation("com.openai:openai-java:0.13.0")
implementation("com.openai:openai-java:0.14.0")
```

#### Maven
### Maven

```xml
<dependency>
<groupId>com.openai</groupId>
<artifactId>openai-java</artifactId>
<version>0.13.0</version>
<version>0.14.0</version>
</dependency>
```

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

## Requirements

This library requires Java 8 or later.

## Usage

### Configure the client

Use `OpenAIOkHttpClient.builder()` to configure the client. At a minimum you need to set `.apiKey()`:
Expand Down Expand Up @@ -418,7 +418,3 @@ This package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) con
We take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience.

We are keen for your feedback; please open an [issue](https://www.github.com/openai/openai-java/issues) with questions, bugs, or suggestions.

## Requirements

This library requires Java 8 or later.
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 = "0.13.0" // x-release-please-version
version = "0.14.0" // x-release-please-version
}

subprojects {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ public static void main(String[] args) {
OpenAIClient client = clientBuilder.build();

ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
.addMessage(ChatCompletionMessageParam.ofChatCompletionUserMessageParam(
.addMessage(
ChatCompletionUserMessageParam.builder()
.content(ChatCompletionUserMessageParam.Content.ofTextContent("Who won the world series in 2020?"))
.build()))
.content("Who won the world series in 2020?")
.build())
.model("gpt-4o")
.build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ public static void main(String[] args) {
OpenAIClientAsync client = asyncClientBuilder.build();

ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
.addMessage(ChatCompletionMessageParam.ofChatCompletionUserMessageParam(
.addMessage(
ChatCompletionUserMessageParam.builder()
.content(ChatCompletionUserMessageParam.Content.ofTextContent("Who won the world series in 2020?"))
.build()))
.content("Who won the world series in 2020?")
.build())
.model("gpt-4o")
.build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ public static void main(String[] args) {
OpenAIClient client = clientBuilder.build();

ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
.addMessage(ChatCompletionMessageParam.ofChatCompletionUserMessageParam(
.addMessage(
ChatCompletionUserMessageParam.builder()
.content(ChatCompletionUserMessageParam.Content.ofTextContent("Who won the world series in 2020?"))
.build()))
.content("Who won the world series in 2020?")
.build())
.model("gpt-4o")
.build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ public static void main(String[] args) {
OpenAIClientAsync asyncClient = asyncClientBuilder.build();

ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
.addMessage(ChatCompletionMessageParam.ofChatCompletionUserMessageParam(
.addMessage(
ChatCompletionUserMessageParam.builder()
.content(ChatCompletionUserMessageParam.Content.ofTextContent("Who won the world series in 2020?"))
.build()))
.content("Who won the world series in 2020?")
.build())
.model("gpt-4o")
.build();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.openai.client.okhttp

import com.openai.core.RequestOptions
import com.openai.core.checkRequired
import com.openai.core.http.Headers
import com.openai.core.http.HttpClient
import com.openai.core.http.HttpMethod
Expand Down Expand Up @@ -192,7 +193,7 @@ private constructor(private val okHttpClient: okhttp3.OkHttpClient, private val
.callTimeout(if (timeout.seconds == 0L) timeout else timeout.plusSeconds(30))
.proxy(proxy)
.build(),
checkNotNull(baseUrl) { "`baseUrl` is required but was not set" },
checkRequired("baseUrl", baseUrl),
)
}
}
3 changes: 1 addition & 2 deletions openai-java-core/src/main/kotlin/com/openai/core/Check.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

package com.openai.core

@JvmSynthetic
internal fun <T : Any> checkRequired(name: String, value: T?): T =
fun <T : Any> checkRequired(name: String, value: T?): T =
checkNotNull(value) { "`$name` is required, but was not set" }

@JvmSynthetic
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.openai.core.http

import com.openai.core.checkRequired
import com.openai.core.toImmutable

class HttpRequest
Expand Down Expand Up @@ -134,7 +135,7 @@ private constructor(

fun build(): HttpRequest =
HttpRequest(
checkNotNull(method) { "`method` is required but was not set" },
checkRequired("method", method),
url,
pathSegments.toImmutable(),
headers.build(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.openai.core.http

import com.openai.core.RequestOptions
import com.openai.core.checkRequired
import com.openai.errors.OpenAIIoException
import java.io.IOException
import java.time.Clock
Expand Down Expand Up @@ -259,7 +260,7 @@ private constructor(

fun build(): HttpClient =
RetryingHttpClient(
checkNotNull(httpClient) { "`httpClient` is required but was not set" },
checkRequired("httpClient", httpClient),
clock,
maxRetries,
idempotencyHeader,
Expand Down
64 changes: 27 additions & 37 deletions openai-java-core/src/main/kotlin/com/openai/models/Annotation.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ import kotlin.jvm.optionals.getOrNull
@JsonSerialize(using = Annotation.Serializer::class)
class Annotation
private constructor(
private val fileCitationAnnotation: FileCitationAnnotation? = null,
private val filePathAnnotation: FilePathAnnotation? = null,
private val fileCitation: FileCitationAnnotation? = null,
private val filePath: FilePathAnnotation? = null,
private val _json: JsonValue? = null,
) {

Expand All @@ -37,41 +37,37 @@ private constructor(
* with the assistant or the message. Generated when the assistant uses the "file_search" tool
* to search files.
*/
fun fileCitationAnnotation(): Optional<FileCitationAnnotation> =
Optional.ofNullable(fileCitationAnnotation)
fun fileCitation(): Optional<FileCitationAnnotation> = Optional.ofNullable(fileCitation)

/**
* A URL for the file that's generated when the assistant used the `code_interpreter` tool to
* generate a file.
*/
fun filePathAnnotation(): Optional<FilePathAnnotation> = Optional.ofNullable(filePathAnnotation)
fun filePath(): Optional<FilePathAnnotation> = Optional.ofNullable(filePath)

fun isFileCitationAnnotation(): Boolean = fileCitationAnnotation != null
fun isFileCitation(): Boolean = fileCitation != null

fun isFilePathAnnotation(): Boolean = filePathAnnotation != null
fun isFilePath(): Boolean = filePath != null

/**
* A citation within the message that points to a specific quote from a specific File associated
* with the assistant or the message. Generated when the assistant uses the "file_search" tool
* to search files.
*/
fun asFileCitationAnnotation(): FileCitationAnnotation =
fileCitationAnnotation.getOrThrow("fileCitationAnnotation")
fun asFileCitation(): FileCitationAnnotation = fileCitation.getOrThrow("fileCitation")

/**
* A URL for the file that's generated when the assistant used the `code_interpreter` tool to
* generate a file.
*/
fun asFilePathAnnotation(): FilePathAnnotation =
filePathAnnotation.getOrThrow("filePathAnnotation")
fun asFilePath(): FilePathAnnotation = filePath.getOrThrow("filePath")

fun _json(): Optional<JsonValue> = Optional.ofNullable(_json)

fun <T> accept(visitor: Visitor<T>): T {
return when {
fileCitationAnnotation != null ->
visitor.visitFileCitationAnnotation(fileCitationAnnotation)
filePathAnnotation != null -> visitor.visitFilePathAnnotation(filePathAnnotation)
fileCitation != null -> visitor.visitFileCitation(fileCitation)
filePath != null -> visitor.visitFilePath(filePath)
else -> visitor.unknown(_json)
}
}
Expand All @@ -85,14 +81,12 @@ private constructor(

accept(
object : Visitor<Unit> {
override fun visitFileCitationAnnotation(
fileCitationAnnotation: FileCitationAnnotation
) {
fileCitationAnnotation.validate()
override fun visitFileCitation(fileCitation: FileCitationAnnotation) {
fileCitation.validate()
}

override fun visitFilePathAnnotation(filePathAnnotation: FilePathAnnotation) {
filePathAnnotation.validate()
override fun visitFilePath(filePath: FilePathAnnotation) {
filePath.validate()
}
}
)
Expand All @@ -104,16 +98,15 @@ private constructor(
return true
}

return /* spotless:off */ other is Annotation && fileCitationAnnotation == other.fileCitationAnnotation && filePathAnnotation == other.filePathAnnotation /* spotless:on */
return /* spotless:off */ other is Annotation && fileCitation == other.fileCitation && filePath == other.filePath /* spotless:on */
}

override fun hashCode(): Int = /* spotless:off */ Objects.hash(fileCitationAnnotation, filePathAnnotation) /* spotless:on */
override fun hashCode(): Int = /* spotless:off */ Objects.hash(fileCitation, filePath) /* spotless:on */

override fun toString(): String =
when {
fileCitationAnnotation != null ->
"Annotation{fileCitationAnnotation=$fileCitationAnnotation}"
filePathAnnotation != null -> "Annotation{filePathAnnotation=$filePathAnnotation}"
fileCitation != null -> "Annotation{fileCitation=$fileCitation}"
filePath != null -> "Annotation{filePath=$filePath}"
_json != null -> "Annotation{_unknown=$_json}"
else -> throw IllegalStateException("Invalid Annotation")
}
Expand All @@ -126,16 +119,14 @@ private constructor(
* "file_search" tool to search files.
*/
@JvmStatic
fun ofFileCitationAnnotation(fileCitationAnnotation: FileCitationAnnotation) =
Annotation(fileCitationAnnotation = fileCitationAnnotation)
fun ofFileCitation(fileCitation: FileCitationAnnotation) =
Annotation(fileCitation = fileCitation)

/**
* A URL for the file that's generated when the assistant used the `code_interpreter` tool
* to generate a file.
*/
@JvmStatic
fun ofFilePathAnnotation(filePathAnnotation: FilePathAnnotation) =
Annotation(filePathAnnotation = filePathAnnotation)
@JvmStatic fun ofFilePath(filePath: FilePathAnnotation) = Annotation(filePath = filePath)
}

interface Visitor<out T> {
Expand All @@ -145,13 +136,13 @@ private constructor(
* associated with the assistant or the message. Generated when the assistant uses the
* "file_search" tool to search files.
*/
fun visitFileCitationAnnotation(fileCitationAnnotation: FileCitationAnnotation): T
fun visitFileCitation(fileCitation: FileCitationAnnotation): T

/**
* A URL for the file that's generated when the assistant used the `code_interpreter` tool
* to generate a file.
*/
fun visitFilePathAnnotation(filePathAnnotation: FilePathAnnotation): T
fun visitFilePath(filePath: FilePathAnnotation): T

fun unknown(json: JsonValue?): T {
throw OpenAIInvalidDataException("Unknown Annotation: $json")
Expand All @@ -168,13 +159,13 @@ private constructor(
"file_citation" -> {
tryDeserialize(node, jacksonTypeRef<FileCitationAnnotation>()) { it.validate() }
?.let {
return Annotation(fileCitationAnnotation = it, _json = json)
return Annotation(fileCitation = it, _json = json)
}
}
"file_path" -> {
tryDeserialize(node, jacksonTypeRef<FilePathAnnotation>()) { it.validate() }
?.let {
return Annotation(filePathAnnotation = it, _json = json)
return Annotation(filePath = it, _json = json)
}
}
}
Expand All @@ -191,9 +182,8 @@ private constructor(
provider: SerializerProvider
) {
when {
value.fileCitationAnnotation != null ->
generator.writeObject(value.fileCitationAnnotation)
value.filePathAnnotation != null -> generator.writeObject(value.filePathAnnotation)
value.fileCitation != null -> generator.writeObject(value.fileCitation)
value.filePath != null -> generator.writeObject(value.filePath)
value._json != null -> generator.writeObject(value._json)
else -> throw IllegalStateException("Invalid Annotation")
}
Expand Down
Loading
Loading