Skip to content
Open
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
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,11 @@ annotations. These allow type-specific constraints to be added to your schema pr
learn more about the supported constraints in the OpenAI documentation on
[Supported properties](https://platform.openai.com/docs/guides/structured-outputs#supported-properties).

Add either `io.swagger.core.v3:swagger-annotations` or `io.swagger.core.v3:swagger-annotations-jakarta`
to your project yourself (the SDK no longer ships either as a transitive dependency, so javax and
Jakarta consumers do not conflict). Without one of those artifacts on the classpath, Swagger
annotations are ignored and Jackson annotations still work for schema generation.

```java
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.ArraySchema;
Expand Down
6 changes: 5 additions & 1 deletion openai-java-core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,10 @@ dependencies {
api("com.fasterxml.jackson.core:jackson-core:$jacksonPublishedVersion")
api("com.fasterxml.jackson.core:jackson-databind:$jacksonPublishedVersion")
api("com.google.errorprone:error_prone_annotations:2.33.0")
api("io.swagger.core.v3:swagger-annotations:2.2.31")
// compileOnly: do not force javax swagger-annotations onto consumers. It conflicts with
// swagger-annotations-jakarta (same package). Consumers who use @Schema / @ArraySchema must
// declare either artifact themselves. See extractSchema() for optional Swagger2Module wiring.
compileOnly("io.swagger.core.v3:swagger-annotations:2.2.31")

implementation("com.fasterxml.jackson.core:jackson-annotations:$jacksonPublishedVersion")
implementation("com.fasterxml.jackson.datatype:jackson-datatype-jdk8:$jacksonPublishedVersion")
Expand All @@ -88,6 +91,7 @@ dependencies {
testImplementation(kotlin("test"))
testImplementation(project(":openai-java-client-okhttp"))
testImplementation(platform("com.fasterxml.jackson:jackson-bom:2.21.5"))
testImplementation("io.swagger.core.v3:swagger-annotations:2.2.31")
testImplementation("org.assertj:assertj-core:3.27.7")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.3")
testImplementation("org.junit.jupiter:junit-jupiter-params:5.9.3")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,15 @@ internal fun extractSchema(type: Class<*>): ObjectNode {
// Use `JacksonModule` to support the use of Jackson annotations to set property and
// class names and descriptions and to mark fields with `@JsonIgnore`.
.with(JacksonModule())
// Use `Swagger2Module` to support OpenAPI Swagger 2 `@Schema` annotations to set
// property constraints (e.g., a `"pattern"` constraint for a string property).
.with(Swagger2Module())

// Swagger annotations are compileOnly (not a transitive dependency) so consumers can use
// either swagger-annotations or swagger-annotations-jakarta. Swagger2Module hard-references
// those classes; only register it when they are loadable on the consumer classpath.
if (isSwaggerAnnotationsPresent()) {
// Use `Swagger2Module` to support OpenAPI Swagger 2 `@Schema` annotations to set
// property constraints (e.g., a `"pattern"` constraint for a string property).
configBuilder.with(Swagger2Module())
}

configBuilder
.forFields()
Expand All @@ -218,6 +224,10 @@ internal fun extractSchema(type: Class<*>): ObjectNode {
return SchemaGenerator(configBuilder.build()).generateSchema(type)
}

/** True when javax or jakarta swagger-annotations are on the classpath (shared package). */
private fun isSwaggerAnnotationsPresent(): Boolean =
runCatching { Class.forName("io.swagger.v3.oas.annotations.media.Schema") }.isSuccess

/**
* Creates an instance of a Java class using data from a JSON string. The JSON data should conform
* to the JSON schema previously extracted from the Java class.
Expand Down
2 changes: 2 additions & 0 deletions openai-java-example/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ repositories {
dependencies {
implementation(project(":openai-java"))
implementation(project(":openai-java-bedrock"))
// Structured-output examples use @Schema / @ArraySchema; not transitive from openai-java-core.
implementation("io.swagger.core.v3:swagger-annotations:2.2.31")
// Keep Azure Identity's Netty runtime aligned on a secure release.
implementation(platform("io.netty:netty-bom:4.1.136.Final"))
implementation("com.azure:azure-identity:1.18.4")
Expand Down