diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 59565e8e..65f558e7 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "1.6.1" + ".": "2.0.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 089abe5d..5a1f2ff0 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 95 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-0ee6b36cf3cc278cef4199a6aec5f7d530a6c1f17a74830037e96d50ca1edc50.yml -openapi_spec_hash: e8ec5f46bc0655b34f292422d58a60f6 -config_hash: d9b6b6e6bc85744663e300eebc482067 +configured_endpoints: 99 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-794a6ed3c3d3d77887564755168056af8a426b17cf1ec721e3a300503dc22a41.yml +openapi_spec_hash: 25a81c220713cd5b0bafc221d1dfa79a +config_hash: 0b768ed1b56c6d82816f0fa40dc4aaf5 diff --git a/CHANGELOG.md b/CHANGELOG.md index f164c88f..013a2250 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,46 @@ # Changelog +## 2.0.0 (2025-05-11) + +Full Changelog: [v1.6.1...v2.0.0](https://github.com/openai/openai-java/compare/v1.6.1...v2.0.0) + +### ⚠ BREAKING CHANGES + +* **client:** change precision of some numeric types +* **client:** extract auto pagination to shared classes +* **client:** **Migration:** - If you were referencing the `AutoPager` class on a specific `*Page` or `*PageAsync` type, then you should instead reference the shared `AutoPager` and `AutoPagerAsync` types, under the `core` package + - `AutoPagerAsync` now has different usage. You can call `.subscribe(...)` on the returned object instead to get called back each page item. You can also call `onCompleteFuture()` to get a future that completes when all items have been processed. Finally, you can call `.close()` on the returned object to stop auto-paginating early + - If you were referencing `getNextPage` or `getNextPageParams`: + - Swap to `nextPage()` and `nextPageParams()` + - Note that these both now return non-optional types (use `hasNextPage()` before calling these, since they will throw if it's impossible to get another page) + +### Features + +* **api:** Add reinforcement fine-tuning api support ([d243892](https://github.com/openai/openai-java/commit/d2438923c2f53a76879464ab3816732b5c4b5718)) +* **client:** allow providing some params positionally ([7200cf6](https://github.com/openai/openai-java/commit/7200cf61d31fcc16b15d01cd83d3a0bcc53eba4d)) +* **client:** extract auto pagination to shared classes ([f623bca](https://github.com/openai/openai-java/commit/f623bcac1e66ed15f8ba6c89375468b764cb900f)) + + +### Bug Fixes + +* add missing `deploymentModel` params ([bb85d0d](https://github.com/openai/openai-java/commit/bb85d0d1a899b3981f5c1f818dc4200939cb571d)) +* merge conflict ([4587737](https://github.com/openai/openai-java/commit/458773748bba0efefce9e67d17b8d2879338cb61)) + + +### Chores + +* **internal:** fix custom code ([1da6c92](https://github.com/openai/openai-java/commit/1da6c92fc964837aec19a3688ffb9a1089b3d91c)) + + +### Documentation + +* remove or fix invalid readme examples ([4bf868a](https://github.com/openai/openai-java/commit/4bf868a717f9f782cd2f288bffc74bb24b2bb0e7)) + + +### Refactors + +* **client:** change precision of some numeric types ([6cdb671](https://github.com/openai/openai-java/commit/6cdb6717e047e96f9f4186bec3beca0744f27a3a)) + ## 1.6.1 (2025-05-08) Full Changelog: [v1.6.0...v1.6.1](https://github.com/openai/openai-java/compare/v1.6.0...v1.6.1) diff --git a/README.md b/README.md index 6a05116a..71037bd6 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ -[![Maven Central](https://img.shields.io/maven-central/v/com.openai/openai-java)](https://central.sonatype.com/artifact/com.openai/openai-java/1.6.1) -[![javadoc](https://javadoc.io/badge2/com.openai/openai-java/1.6.1/javadoc.svg)](https://javadoc.io/doc/com.openai/openai-java/1.6.1) +[![Maven Central](https://img.shields.io/maven-central/v/com.openai/openai-java)](https://central.sonatype.com/artifact/com.openai/openai-java/2.0.0) +[![javadoc](https://javadoc.io/badge2/com.openai/openai-java/2.0.0/javadoc.svg)](https://javadoc.io/doc/com.openai/openai-java/2.0.0) @@ -11,7 +11,7 @@ The OpenAI Java SDK provides convenient access to the [OpenAI REST API](https:// -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/1.6.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/2.0.0). @@ -22,7 +22,7 @@ The REST API documentation can be found on [platform.openai.com](https://platfor ### Gradle ```kotlin -implementation("com.openai:openai-java:1.6.1") +implementation("com.openai:openai-java:2.0.0") ``` ### Maven @@ -31,7 +31,7 @@ implementation("com.openai:openai-java:1.6.1") com.openai openai-java - 1.6.1 + 2.0.0 ``` @@ -412,10 +412,7 @@ These methods return [`HttpResponse`](openai-java-core/src/main/kotlin/com/opena import com.openai.core.http.HttpResponse; import com.openai.models.files.FileContentParams; -FileContentParams params = FileContentParams.builder() - .fileId("file_id") - .build(); -HttpResponse response = client.files().content(params); +HttpResponse response = client.files().content("file_id"); ``` To save the response content to a file, use the [`Files.copy(...)`](https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#copy-java.io.InputStream-java.nio.file.Path-java.nio.file.CopyOption...-) method: @@ -528,53 +525,101 @@ The SDK throws custom unchecked exception types: ## Pagination -For methods that return a paginated list of results, this library provides convenient ways access the results either one page at a time, or item-by-item across all pages. +The SDK defines methods that return a paginated lists of results. It provides convenient ways to access the results either one page at a time or item-by-item across all pages. ### Auto-pagination -To iterate through all results across all pages, you can use `autoPager`, which automatically handles fetching more pages for you: +To iterate through all results across all pages, use the `autoPager()` method, which automatically fetches more pages as needed. -### Synchronous +When using the synchronous client, the method returns an [`Iterable`](https://docs.oracle.com/javase/8/docs/api/java/lang/Iterable.html) ```java import com.openai.models.finetuning.jobs.FineTuningJob; import com.openai.models.finetuning.jobs.JobListPage; -// As an Iterable: -JobListPage page = client.fineTuning().jobs().list(params); +JobListPage page = client.fineTuning().jobs().list(); + +// Process as an Iterable for (FineTuningJob job : page.autoPager()) { System.out.println(job); -}; +} -// As a Stream: -client.fineTuning().jobs().list(params).autoPager().stream() +// Process as a Stream +page.autoPager() + .stream() .limit(50) .forEach(job -> System.out.println(job)); ``` -### Asynchronous +When using the asynchronous client, the method returns an [`AsyncStreamResponse`](openai-java-core/src/main/kotlin/com/openai/core/http/AsyncStreamResponse.kt): ```java -// Using forEach, which returns CompletableFuture: -asyncClient.fineTuning().jobs().list(params).autoPager() - .forEach(job -> System.out.println(job), executor); +import com.openai.core.http.AsyncStreamResponse; +import com.openai.models.finetuning.jobs.FineTuningJob; +import com.openai.models.finetuning.jobs.JobListPageAsync; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; + +CompletableFuture pageFuture = client.async().fineTuning().jobs().list(); + +pageFuture.thenRun(page -> page.autoPager().subscribe(job -> { + System.out.println(job); +})); + +// If you need to handle errors or completion of the stream +pageFuture.thenRun(page -> page.autoPager().subscribe(new AsyncStreamResponse.Handler<>() { + @Override + public void onNext(FineTuningJob job) { + System.out.println(job); + } + + @Override + public void onComplete(Optional error) { + if (error.isPresent()) { + System.out.println("Something went wrong!"); + throw new RuntimeException(error.get()); + } else { + System.out.println("No more!"); + } + } +})); + +// Or use futures +pageFuture.thenRun(page -> page.autoPager() + .subscribe(job -> { + System.out.println(job); + }) + .onCompleteFuture() + .whenComplete((unused, error) -> { + if (error != null) { + System.out.println("Something went wrong!"); + throw new RuntimeException(error); + } else { + System.out.println("No more!"); + } + })); ``` ### Manual pagination -If none of the above helpers meet your needs, you can also manually request pages one-by-one. A page of results has a `data()` method to fetch the list of objects, as well as top-level `response` and other methods to fetch top-level data about the page. It also has methods `hasNextPage`, `getNextPage`, and `getNextPageParams` methods to help with pagination. +To access individual page items and manually request the next page, use the `items()`, +`hasNextPage()`, and `nextPage()` methods: ```java import com.openai.models.finetuning.jobs.FineTuningJob; import com.openai.models.finetuning.jobs.JobListPage; -JobListPage page = client.fineTuning().jobs().list(params); -while (page != null) { - for (FineTuningJob job : page.data()) { +JobListPage page = client.fineTuning().jobs().list(); +while (true) { + for (FineTuningJob job : page.items()) { System.out.println(job); } - page = page.getNextPage().orElse(null); + if (!page.hasNextPage()) { + break; + } + + page = page.nextPage(); } ``` @@ -657,9 +702,7 @@ Requests time out after 10 minutes by default. To set a custom timeout, configure the method call using the `timeout` method: ```java -import com.openai.models.ChatModel; import com.openai.models.chat.completions.ChatCompletion; -import com.openai.models.chat.completions.ChatCompletionCreateParams; ChatCompletion chatCompletion = client.chat().completions().create( params, RequestOptions.builder().timeout(Duration.ofSeconds(30)).build() @@ -775,11 +818,12 @@ To set a documented parameter or property to an undocumented or not yet supporte ```java import com.openai.core.JsonValue; +import com.openai.models.ChatModel; import com.openai.models.chat.completions.ChatCompletionCreateParams; ChatCompletionCreateParams params = ChatCompletionCreateParams.builder() - .addUserMessage("Say this is a test") - .model(JsonValue.from(42)) + .messages(JsonValue.from(42)) + .model(ChatModel.GPT_4_1) .build(); ``` @@ -909,9 +953,7 @@ ChatCompletion chatCompletion = client.chat().completions().create(params).valid Or configure the method call to validate the response using the `responseValidation` method: ```java -import com.openai.models.ChatModel; import com.openai.models.chat.completions.ChatCompletion; -import com.openai.models.chat.completions.ChatCompletionCreateParams; ChatCompletion chatCompletion = client.chat().completions().create( params, RequestOptions.builder().responseValidation(true).build() diff --git a/build.gradle.kts b/build.gradle.kts index 47de6d33..581930ee 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ repositories { allprojects { group = "com.openai" - version = "1.6.1" // x-release-please-version + version = "2.0.0" // x-release-please-version } subprojects { diff --git a/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClient.kt b/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClient.kt index 3995c9ea..e990bc66 100644 --- a/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClient.kt +++ b/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClient.kt @@ -11,6 +11,7 @@ import com.openai.services.blocking.EmbeddingService import com.openai.services.blocking.EvalService import com.openai.services.blocking.FileService import com.openai.services.blocking.FineTuningService +import com.openai.services.blocking.GraderService import com.openai.services.blocking.ImageService import com.openai.services.blocking.ModelService import com.openai.services.blocking.ModerationService @@ -65,6 +66,8 @@ interface OpenAIClient { fun fineTuning(): FineTuningService + fun graders(): GraderService + fun vectorStores(): VectorStoreService fun beta(): BetaService @@ -111,6 +114,8 @@ interface OpenAIClient { fun fineTuning(): FineTuningService.WithRawResponse + fun graders(): GraderService.WithRawResponse + fun vectorStores(): VectorStoreService.WithRawResponse fun beta(): BetaService.WithRawResponse diff --git a/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientAsync.kt b/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientAsync.kt index 2a2d5894..aff5f61e 100644 --- a/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientAsync.kt @@ -11,6 +11,7 @@ import com.openai.services.async.EmbeddingServiceAsync import com.openai.services.async.EvalServiceAsync import com.openai.services.async.FileServiceAsync import com.openai.services.async.FineTuningServiceAsync +import com.openai.services.async.GraderServiceAsync import com.openai.services.async.ImageServiceAsync import com.openai.services.async.ModelServiceAsync import com.openai.services.async.ModerationServiceAsync @@ -65,6 +66,8 @@ interface OpenAIClientAsync { fun fineTuning(): FineTuningServiceAsync + fun graders(): GraderServiceAsync + fun vectorStores(): VectorStoreServiceAsync fun beta(): BetaServiceAsync @@ -111,6 +114,8 @@ interface OpenAIClientAsync { fun fineTuning(): FineTuningServiceAsync.WithRawResponse + fun graders(): GraderServiceAsync.WithRawResponse + fun vectorStores(): VectorStoreServiceAsync.WithRawResponse fun beta(): BetaServiceAsync.WithRawResponse diff --git a/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientAsyncImpl.kt index 2bbeb00b..5e2719a6 100644 --- a/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientAsyncImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientAsyncImpl.kt @@ -22,6 +22,8 @@ import com.openai.services.async.FileServiceAsync import com.openai.services.async.FileServiceAsyncImpl import com.openai.services.async.FineTuningServiceAsync import com.openai.services.async.FineTuningServiceAsyncImpl +import com.openai.services.async.GraderServiceAsync +import com.openai.services.async.GraderServiceAsyncImpl import com.openai.services.async.ImageServiceAsync import com.openai.services.async.ImageServiceAsyncImpl import com.openai.services.async.ModelServiceAsync @@ -84,6 +86,10 @@ class OpenAIClientAsyncImpl(private val clientOptions: ClientOptions) : OpenAICl FineTuningServiceAsyncImpl(clientOptionsWithUserAgent) } + private val graders: GraderServiceAsync by lazy { + GraderServiceAsyncImpl(clientOptionsWithUserAgent) + } + private val vectorStores: VectorStoreServiceAsync by lazy { VectorStoreServiceAsyncImpl(clientOptionsWithUserAgent) } @@ -126,6 +132,8 @@ class OpenAIClientAsyncImpl(private val clientOptions: ClientOptions) : OpenAICl override fun fineTuning(): FineTuningServiceAsync = fineTuning + override fun graders(): GraderServiceAsync = graders + override fun vectorStores(): VectorStoreServiceAsync = vectorStores override fun beta(): BetaServiceAsync = beta @@ -179,6 +187,10 @@ class OpenAIClientAsyncImpl(private val clientOptions: ClientOptions) : OpenAICl FineTuningServiceAsyncImpl.WithRawResponseImpl(clientOptions) } + private val graders: GraderServiceAsync.WithRawResponse by lazy { + GraderServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + private val vectorStores: VectorStoreServiceAsync.WithRawResponse by lazy { VectorStoreServiceAsyncImpl.WithRawResponseImpl(clientOptions) } @@ -221,6 +233,8 @@ class OpenAIClientAsyncImpl(private val clientOptions: ClientOptions) : OpenAICl override fun fineTuning(): FineTuningServiceAsync.WithRawResponse = fineTuning + override fun graders(): GraderServiceAsync.WithRawResponse = graders + override fun vectorStores(): VectorStoreServiceAsync.WithRawResponse = vectorStores override fun beta(): BetaServiceAsync.WithRawResponse = beta diff --git a/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientImpl.kt b/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientImpl.kt index 17ad13b4..c79edfec 100644 --- a/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientImpl.kt @@ -22,6 +22,8 @@ import com.openai.services.blocking.FileService import com.openai.services.blocking.FileServiceImpl import com.openai.services.blocking.FineTuningService import com.openai.services.blocking.FineTuningServiceImpl +import com.openai.services.blocking.GraderService +import com.openai.services.blocking.GraderServiceImpl import com.openai.services.blocking.ImageService import com.openai.services.blocking.ImageServiceImpl import com.openai.services.blocking.ModelService @@ -78,6 +80,8 @@ class OpenAIClientImpl(private val clientOptions: ClientOptions) : OpenAIClient FineTuningServiceImpl(clientOptionsWithUserAgent) } + private val graders: GraderService by lazy { GraderServiceImpl(clientOptionsWithUserAgent) } + private val vectorStores: VectorStoreService by lazy { VectorStoreServiceImpl(clientOptionsWithUserAgent) } @@ -116,6 +120,8 @@ class OpenAIClientImpl(private val clientOptions: ClientOptions) : OpenAIClient override fun fineTuning(): FineTuningService = fineTuning + override fun graders(): GraderService = graders + override fun vectorStores(): VectorStoreService = vectorStores override fun beta(): BetaService = beta @@ -169,6 +175,10 @@ class OpenAIClientImpl(private val clientOptions: ClientOptions) : OpenAIClient FineTuningServiceImpl.WithRawResponseImpl(clientOptions) } + private val graders: GraderService.WithRawResponse by lazy { + GraderServiceImpl.WithRawResponseImpl(clientOptions) + } + private val vectorStores: VectorStoreService.WithRawResponse by lazy { VectorStoreServiceImpl.WithRawResponseImpl(clientOptions) } @@ -211,6 +221,8 @@ class OpenAIClientImpl(private val clientOptions: ClientOptions) : OpenAIClient override fun fineTuning(): FineTuningService.WithRawResponse = fineTuning + override fun graders(): GraderService.WithRawResponse = graders + override fun vectorStores(): VectorStoreService.WithRawResponse = vectorStores override fun beta(): BetaService.WithRawResponse = beta diff --git a/openai-java-core/src/main/kotlin/com/openai/core/AutoPager.kt b/openai-java-core/src/main/kotlin/com/openai/core/AutoPager.kt new file mode 100644 index 00000000..888fd034 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/core/AutoPager.kt @@ -0,0 +1,21 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.core + +import java.util.stream.Stream +import java.util.stream.StreamSupport + +class AutoPager private constructor(private val firstPage: Page) : Iterable { + + companion object { + + fun from(firstPage: Page): AutoPager = AutoPager(firstPage) + } + + override fun iterator(): Iterator = + generateSequence(firstPage) { if (it.hasNextPage()) it.nextPage() else null } + .flatMap { it.items() } + .iterator() + + fun stream(): Stream = StreamSupport.stream(spliterator(), false) +} diff --git a/openai-java-core/src/main/kotlin/com/openai/core/AutoPagerAsync.kt b/openai-java-core/src/main/kotlin/com/openai/core/AutoPagerAsync.kt new file mode 100644 index 00000000..649be47c --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/core/AutoPagerAsync.kt @@ -0,0 +1,88 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.core + +import com.openai.core.http.AsyncStreamResponse +import java.util.Optional +import java.util.concurrent.CompletableFuture +import java.util.concurrent.CompletionException +import java.util.concurrent.Executor +import java.util.concurrent.atomic.AtomicReference + +class AutoPagerAsync +private constructor(private val firstPage: PageAsync, private val defaultExecutor: Executor) : + AsyncStreamResponse { + + companion object { + + fun from(firstPage: PageAsync, defaultExecutor: Executor): AutoPagerAsync = + AutoPagerAsync(firstPage, defaultExecutor) + } + + private val onCompleteFuture = CompletableFuture() + private val state = AtomicReference(State.NEW) + + override fun subscribe(handler: AsyncStreamResponse.Handler): AsyncStreamResponse = + subscribe(handler, defaultExecutor) + + override fun subscribe( + handler: AsyncStreamResponse.Handler, + executor: Executor, + ): AsyncStreamResponse = apply { + // TODO(JDK): Use `compareAndExchange` once targeting JDK 9. + check(state.compareAndSet(State.NEW, State.SUBSCRIBED)) { + if (state.get() == State.SUBSCRIBED) "Cannot subscribe more than once" + else "Cannot subscribe after the response is closed" + } + + fun PageAsync.handle(): CompletableFuture { + if (state.get() == State.CLOSED) { + return CompletableFuture.completedFuture(null) + } + + items().forEach { handler.onNext(it) } + return if (hasNextPage()) nextPage().thenCompose { it.handle() } + else CompletableFuture.completedFuture(null) + } + + executor.execute { + firstPage.handle().whenComplete { _, error -> + val actualError = + if (error is CompletionException && error.cause != null) error.cause else error + try { + handler.onComplete(Optional.ofNullable(actualError)) + } finally { + try { + if (actualError == null) { + onCompleteFuture.complete(null) + } else { + onCompleteFuture.completeExceptionally(actualError) + } + } finally { + close() + } + } + } + } + } + + override fun onCompleteFuture(): CompletableFuture = onCompleteFuture + + override fun close() { + val previousState = state.getAndSet(State.CLOSED) + if (previousState == State.CLOSED) { + return + } + + // When the stream is closed, we should always consider it closed. If it closed due + // to an error, then we will have already completed the future earlier, and this + // will be a no-op. + onCompleteFuture.complete(null) + } +} + +private enum class State { + NEW, + SUBSCRIBED, + CLOSED, +} diff --git a/openai-java-core/src/main/kotlin/com/openai/core/Check.kt b/openai-java-core/src/main/kotlin/com/openai/core/Check.kt index dc411d75..53b3b919 100644 --- a/openai-java-core/src/main/kotlin/com/openai/core/Check.kt +++ b/openai-java-core/src/main/kotlin/com/openai/core/Check.kt @@ -5,6 +5,9 @@ package com.openai.core import com.fasterxml.jackson.core.Version import com.fasterxml.jackson.core.util.VersionUtil +fun checkRequired(name: String, condition: Boolean) = + check(condition) { "`$name` is required, but was not set" } + fun checkRequired(name: String, value: T?): T = checkNotNull(value) { "`$name` is required, but was not set" } diff --git a/openai-java-core/src/main/kotlin/com/openai/core/Page.kt b/openai-java-core/src/main/kotlin/com/openai/core/Page.kt new file mode 100644 index 00000000..9c9560b4 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/core/Page.kt @@ -0,0 +1,33 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.core + +/** + * An interface representing a single page, with items of type [T], from a paginated endpoint + * response. + * + * Implementations of this interface are expected to request additional pages synchronously. For + * asynchronous pagination, see the [PageAsync] interface. + */ +interface Page { + + /** + * Returns whether there's another page after this one. + * + * The method generally doesn't make requests so the result depends entirely on the data in this + * page. If a significant amount of time has passed between requesting this page and calling + * this method, then the result could be stale. + */ + fun hasNextPage(): Boolean + + /** + * Returns the page after this one by making another request. + * + * @throws IllegalStateException if it's impossible to get the next page. This exception is + * avoidable by calling [hasNextPage] first. + */ + fun nextPage(): Page + + /** Returns the items in this page. */ + fun items(): List +} diff --git a/openai-java-core/src/main/kotlin/com/openai/core/PageAsync.kt b/openai-java-core/src/main/kotlin/com/openai/core/PageAsync.kt new file mode 100644 index 00000000..c67ff791 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/core/PageAsync.kt @@ -0,0 +1,35 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.core + +import java.util.concurrent.CompletableFuture + +/** + * An interface representing a single page, with items of type [T], from a paginated endpoint + * response. + * + * Implementations of this interface are expected to request additional pages asynchronously. For + * synchronous pagination, see the [Page] interface. + */ +interface PageAsync { + + /** + * Returns whether there's another page after this one. + * + * The method generally doesn't make requests so the result depends entirely on the data in this + * page. If a significant amount of time has passed between requesting this page and calling + * this method, then the result could be stale. + */ + fun hasNextPage(): Boolean + + /** + * Returns the page after this one by making another request. + * + * @throws IllegalStateException if it's impossible to get the next page. This exception is + * avoidable by calling [hasNextPage] first. + */ + fun nextPage(): CompletableFuture> + + /** Returns the items in this page. */ + fun items(): List +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/audio/transcriptions/TranscriptionSegment.kt b/openai-java-core/src/main/kotlin/com/openai/models/audio/transcriptions/TranscriptionSegment.kt index ffd5f56d..c2de7f04 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/audio/transcriptions/TranscriptionSegment.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/audio/transcriptions/TranscriptionSegment.kt @@ -21,13 +21,13 @@ import kotlin.jvm.optionals.getOrNull class TranscriptionSegment private constructor( private val id: JsonField, - private val avgLogprob: JsonField, - private val compressionRatio: JsonField, - private val end: JsonField, - private val noSpeechProb: JsonField, + private val avgLogprob: JsonField, + private val compressionRatio: JsonField, + private val end: JsonField, + private val noSpeechProb: JsonField, private val seek: JsonField, - private val start: JsonField, - private val temperature: JsonField, + private val start: JsonField, + private val temperature: JsonField, private val text: JsonField, private val tokens: JsonField>, private val additionalProperties: MutableMap, @@ -38,19 +38,19 @@ private constructor( @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), @JsonProperty("avg_logprob") @ExcludeMissing - avgLogprob: JsonField = JsonMissing.of(), + avgLogprob: JsonField = JsonMissing.of(), @JsonProperty("compression_ratio") @ExcludeMissing - compressionRatio: JsonField = JsonMissing.of(), - @JsonProperty("end") @ExcludeMissing end: JsonField = JsonMissing.of(), + compressionRatio: JsonField = JsonMissing.of(), + @JsonProperty("end") @ExcludeMissing end: JsonField = JsonMissing.of(), @JsonProperty("no_speech_prob") @ExcludeMissing - noSpeechProb: JsonField = JsonMissing.of(), + noSpeechProb: JsonField = JsonMissing.of(), @JsonProperty("seek") @ExcludeMissing seek: JsonField = JsonMissing.of(), - @JsonProperty("start") @ExcludeMissing start: JsonField = JsonMissing.of(), + @JsonProperty("start") @ExcludeMissing start: JsonField = JsonMissing.of(), @JsonProperty("temperature") @ExcludeMissing - temperature: JsonField = JsonMissing.of(), + temperature: JsonField = JsonMissing.of(), @JsonProperty("text") @ExcludeMissing text: JsonField = JsonMissing.of(), @JsonProperty("tokens") @ExcludeMissing tokens: JsonField> = JsonMissing.of(), ) : this( @@ -81,7 +81,7 @@ private constructor( * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected value). */ - fun avgLogprob(): Double = avgLogprob.getRequired("avg_logprob") + fun avgLogprob(): Float = avgLogprob.getRequired("avg_logprob") /** * Compression ratio of the segment. If the value is greater than 2.4, consider the compression @@ -90,7 +90,7 @@ private constructor( * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected value). */ - fun compressionRatio(): Double = compressionRatio.getRequired("compression_ratio") + fun compressionRatio(): Float = compressionRatio.getRequired("compression_ratio") /** * End time of the segment in seconds. @@ -98,7 +98,7 @@ private constructor( * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected value). */ - fun end(): Double = end.getRequired("end") + fun end(): Float = end.getRequired("end") /** * Probability of no speech in the segment. If the value is higher than 1.0 and the @@ -107,7 +107,7 @@ private constructor( * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected value). */ - fun noSpeechProb(): Double = noSpeechProb.getRequired("no_speech_prob") + fun noSpeechProb(): Float = noSpeechProb.getRequired("no_speech_prob") /** * Seek offset of the segment. @@ -123,7 +123,7 @@ private constructor( * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected value). */ - fun start(): Double = start.getRequired("start") + fun start(): Float = start.getRequired("start") /** * Temperature parameter used for generating the segment. @@ -131,7 +131,7 @@ private constructor( * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected value). */ - fun temperature(): Double = temperature.getRequired("temperature") + fun temperature(): Float = temperature.getRequired("temperature") /** * Text content of the segment. @@ -161,7 +161,7 @@ private constructor( * * Unlike [avgLogprob], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("avg_logprob") @ExcludeMissing fun _avgLogprob(): JsonField = avgLogprob + @JsonProperty("avg_logprob") @ExcludeMissing fun _avgLogprob(): JsonField = avgLogprob /** * Returns the raw JSON value of [compressionRatio]. @@ -171,14 +171,14 @@ private constructor( */ @JsonProperty("compression_ratio") @ExcludeMissing - fun _compressionRatio(): JsonField = compressionRatio + fun _compressionRatio(): JsonField = compressionRatio /** * Returns the raw JSON value of [end]. * * Unlike [end], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("end") @ExcludeMissing fun _end(): JsonField = end + @JsonProperty("end") @ExcludeMissing fun _end(): JsonField = end /** * Returns the raw JSON value of [noSpeechProb]. @@ -187,7 +187,7 @@ private constructor( */ @JsonProperty("no_speech_prob") @ExcludeMissing - fun _noSpeechProb(): JsonField = noSpeechProb + fun _noSpeechProb(): JsonField = noSpeechProb /** * Returns the raw JSON value of [seek]. @@ -201,14 +201,14 @@ private constructor( * * Unlike [start], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("start") @ExcludeMissing fun _start(): JsonField = start + @JsonProperty("start") @ExcludeMissing fun _start(): JsonField = start /** * Returns the raw JSON value of [temperature]. * * Unlike [temperature], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("temperature") @ExcludeMissing fun _temperature(): JsonField = temperature + @JsonProperty("temperature") @ExcludeMissing fun _temperature(): JsonField = temperature /** * Returns the raw JSON value of [text]. @@ -262,13 +262,13 @@ private constructor( class Builder internal constructor() { private var id: JsonField? = null - private var avgLogprob: JsonField? = null - private var compressionRatio: JsonField? = null - private var end: JsonField? = null - private var noSpeechProb: JsonField? = null + private var avgLogprob: JsonField? = null + private var compressionRatio: JsonField? = null + private var end: JsonField? = null + private var noSpeechProb: JsonField? = null private var seek: JsonField? = null - private var start: JsonField? = null - private var temperature: JsonField? = null + private var start: JsonField? = null + private var temperature: JsonField? = null private var text: JsonField? = null private var tokens: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @@ -303,60 +303,60 @@ private constructor( * Average logprob of the segment. If the value is lower than -1, consider the logprobs * failed. */ - fun avgLogprob(avgLogprob: Double) = avgLogprob(JsonField.of(avgLogprob)) + fun avgLogprob(avgLogprob: Float) = avgLogprob(JsonField.of(avgLogprob)) /** * Sets [Builder.avgLogprob] to an arbitrary JSON value. * - * You should usually call [Builder.avgLogprob] with a well-typed [Double] value instead. + * You should usually call [Builder.avgLogprob] with a well-typed [Float] value instead. * This method is primarily for setting the field to an undocumented or not yet supported * value. */ - fun avgLogprob(avgLogprob: JsonField) = apply { this.avgLogprob = avgLogprob } + fun avgLogprob(avgLogprob: JsonField) = apply { this.avgLogprob = avgLogprob } /** * Compression ratio of the segment. If the value is greater than 2.4, consider the * compression failed. */ - fun compressionRatio(compressionRatio: Double) = + fun compressionRatio(compressionRatio: Float) = compressionRatio(JsonField.of(compressionRatio)) /** * Sets [Builder.compressionRatio] to an arbitrary JSON value. * - * You should usually call [Builder.compressionRatio] with a well-typed [Double] value + * You should usually call [Builder.compressionRatio] with a well-typed [Float] value * instead. This method is primarily for setting the field to an undocumented or not yet * supported value. */ - fun compressionRatio(compressionRatio: JsonField) = apply { + fun compressionRatio(compressionRatio: JsonField) = apply { this.compressionRatio = compressionRatio } /** End time of the segment in seconds. */ - fun end(end: Double) = end(JsonField.of(end)) + fun end(end: Float) = end(JsonField.of(end)) /** * Sets [Builder.end] to an arbitrary JSON value. * - * You should usually call [Builder.end] with a well-typed [Double] value instead. This + * You should usually call [Builder.end] with a well-typed [Float] value instead. This * method is primarily for setting the field to an undocumented or not yet supported value. */ - fun end(end: JsonField) = apply { this.end = end } + fun end(end: JsonField) = apply { this.end = end } /** * Probability of no speech in the segment. If the value is higher than 1.0 and the * `avg_logprob` is below -1, consider this segment silent. */ - fun noSpeechProb(noSpeechProb: Double) = noSpeechProb(JsonField.of(noSpeechProb)) + fun noSpeechProb(noSpeechProb: Float) = noSpeechProb(JsonField.of(noSpeechProb)) /** * Sets [Builder.noSpeechProb] to an arbitrary JSON value. * - * You should usually call [Builder.noSpeechProb] with a well-typed [Double] value instead. + * You should usually call [Builder.noSpeechProb] with a well-typed [Float] value instead. * This method is primarily for setting the field to an undocumented or not yet supported * value. */ - fun noSpeechProb(noSpeechProb: JsonField) = apply { + fun noSpeechProb(noSpeechProb: JsonField) = apply { this.noSpeechProb = noSpeechProb } @@ -372,27 +372,27 @@ private constructor( fun seek(seek: JsonField) = apply { this.seek = seek } /** Start time of the segment in seconds. */ - fun start(start: Double) = start(JsonField.of(start)) + fun start(start: Float) = start(JsonField.of(start)) /** * Sets [Builder.start] to an arbitrary JSON value. * - * You should usually call [Builder.start] with a well-typed [Double] value instead. This + * You should usually call [Builder.start] with a well-typed [Float] value instead. This * method is primarily for setting the field to an undocumented or not yet supported value. */ - fun start(start: JsonField) = apply { this.start = start } + fun start(start: JsonField) = apply { this.start = start } /** Temperature parameter used for generating the segment. */ - fun temperature(temperature: Double) = temperature(JsonField.of(temperature)) + fun temperature(temperature: Float) = temperature(JsonField.of(temperature)) /** * Sets [Builder.temperature] to an arbitrary JSON value. * - * You should usually call [Builder.temperature] with a well-typed [Double] value instead. + * You should usually call [Builder.temperature] with a well-typed [Float] value instead. * This method is primarily for setting the field to an undocumented or not yet supported * value. */ - fun temperature(temperature: JsonField) = apply { this.temperature = temperature } + fun temperature(temperature: JsonField) = apply { this.temperature = temperature } /** Text content of the segment. */ fun text(text: String) = text(JsonField.of(text)) diff --git a/openai-java-core/src/main/kotlin/com/openai/models/audio/transcriptions/TranscriptionWord.kt b/openai-java-core/src/main/kotlin/com/openai/models/audio/transcriptions/TranscriptionWord.kt index e17f2505..2ebd3c15 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/audio/transcriptions/TranscriptionWord.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/audio/transcriptions/TranscriptionWord.kt @@ -17,16 +17,16 @@ import java.util.Objects class TranscriptionWord private constructor( - private val end: JsonField, - private val start: JsonField, + private val end: JsonField, + private val start: JsonField, private val word: JsonField, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( - @JsonProperty("end") @ExcludeMissing end: JsonField = JsonMissing.of(), - @JsonProperty("start") @ExcludeMissing start: JsonField = JsonMissing.of(), + @JsonProperty("end") @ExcludeMissing end: JsonField = JsonMissing.of(), + @JsonProperty("start") @ExcludeMissing start: JsonField = JsonMissing.of(), @JsonProperty("word") @ExcludeMissing word: JsonField = JsonMissing.of(), ) : this(end, start, word, mutableMapOf()) @@ -36,7 +36,7 @@ private constructor( * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected value). */ - fun end(): Double = end.getRequired("end") + fun end(): Float = end.getRequired("end") /** * Start time of the word in seconds. @@ -44,7 +44,7 @@ private constructor( * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected value). */ - fun start(): Double = start.getRequired("start") + fun start(): Float = start.getRequired("start") /** * The text content of the word. @@ -59,14 +59,14 @@ private constructor( * * Unlike [end], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("end") @ExcludeMissing fun _end(): JsonField = end + @JsonProperty("end") @ExcludeMissing fun _end(): JsonField = end /** * Returns the raw JSON value of [start]. * * Unlike [start], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("start") @ExcludeMissing fun _start(): JsonField = start + @JsonProperty("start") @ExcludeMissing fun _start(): JsonField = start /** * Returns the raw JSON value of [word]. @@ -105,8 +105,8 @@ private constructor( /** A builder for [TranscriptionWord]. */ class Builder internal constructor() { - private var end: JsonField? = null - private var start: JsonField? = null + private var end: JsonField? = null + private var start: JsonField? = null private var word: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @@ -119,26 +119,26 @@ private constructor( } /** End time of the word in seconds. */ - fun end(end: Double) = end(JsonField.of(end)) + fun end(end: Float) = end(JsonField.of(end)) /** * Sets [Builder.end] to an arbitrary JSON value. * - * You should usually call [Builder.end] with a well-typed [Double] value instead. This + * You should usually call [Builder.end] with a well-typed [Float] value instead. This * method is primarily for setting the field to an undocumented or not yet supported value. */ - fun end(end: JsonField) = apply { this.end = end } + fun end(end: JsonField) = apply { this.end = end } /** Start time of the word in seconds. */ - fun start(start: Double) = start(JsonField.of(start)) + fun start(start: Float) = start(JsonField.of(start)) /** * Sets [Builder.start] to an arbitrary JSON value. * - * You should usually call [Builder.start] with a well-typed [Double] value instead. This + * You should usually call [Builder.start] with a well-typed [Float] value instead. This * method is primarily for setting the field to an undocumented or not yet supported value. */ - fun start(start: JsonField) = apply { this.start = start } + fun start(start: JsonField) = apply { this.start = start } /** The text content of the word. */ fun word(word: String) = word(JsonField.of(word)) diff --git a/openai-java-core/src/main/kotlin/com/openai/models/batches/BatchCancelParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/batches/BatchCancelParams.kt index c9a0e725..4fd0d88f 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/batches/BatchCancelParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/batches/BatchCancelParams.kt @@ -4,12 +4,12 @@ package com.openai.models.batches import com.openai.core.JsonValue import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import com.openai.core.toImmutable import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** * Cancels an in-progress batch. The batch will be in status `cancelling` for up to 10 minutes, @@ -18,13 +18,13 @@ import java.util.Optional */ class BatchCancelParams private constructor( - private val batchId: String, + private val batchId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, ) : Params { - fun batchId(): String = batchId + fun batchId(): Optional = Optional.ofNullable(batchId) fun _additionalBodyProperties(): Map = additionalBodyProperties @@ -36,14 +36,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [BatchCancelParams]. - * - * The following fields are required: - * ```java - * .batchId() - * ``` - */ + @JvmStatic fun none(): BatchCancelParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [BatchCancelParams]. */ @JvmStatic fun builder() = Builder() } @@ -63,7 +58,10 @@ private constructor( additionalBodyProperties = batchCancelParams.additionalBodyProperties.toMutableMap() } - fun batchId(batchId: String) = apply { this.batchId = batchId } + fun batchId(batchId: String?) = apply { this.batchId = batchId } + + /** Alias for calling [Builder.batchId] with `batchId.orElse(null)`. */ + fun batchId(batchId: Optional) = batchId(batchId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -189,17 +187,10 @@ private constructor( * Returns an immutable instance of [BatchCancelParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .batchId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): BatchCancelParams = BatchCancelParams( - checkRequired("batchId", batchId), + batchId, additionalHeaders.build(), additionalQueryParams.build(), additionalBodyProperties.toImmutable(), @@ -211,7 +202,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> batchId + 0 -> batchId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/batches/BatchListPage.kt b/openai-java-core/src/main/kotlin/com/openai/models/batches/BatchListPage.kt index 35c7aa3f..d591ebcc 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/batches/BatchListPage.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/batches/BatchListPage.kt @@ -2,12 +2,12 @@ package com.openai.models.batches +import com.openai.core.AutoPager +import com.openai.core.Page import com.openai.core.checkRequired import com.openai.services.blocking.BatchService import java.util.Objects import java.util.Optional -import java.util.stream.Stream -import java.util.stream.StreamSupport import kotlin.jvm.optionals.getOrNull /** @see [BatchService.list] */ @@ -16,7 +16,7 @@ private constructor( private val service: BatchService, private val params: BatchListParams, private val response: BatchListPageResponse, -) { +) : Page { /** * Delegates to [BatchListPageResponse], but gracefully handles missing data. @@ -32,19 +32,16 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): BatchListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): Optional = getNextPageParams().map { service.list(it) } + override fun nextPage(): BatchListPage = service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPager = AutoPager.from(this) /** The parameters that were used to request this page. */ fun params(): BatchListParams = params @@ -113,25 +110,6 @@ private constructor( ) } - class AutoPager(private val firstPage: BatchListPage) : Iterable { - - override fun iterator(): Iterator = iterator { - var page = firstPage - var index = 0 - while (true) { - while (index < page.data().size) { - yield(page.data()[index++]) - } - page = page.getNextPage().getOrNull() ?: break - index = 0 - } - } - - fun stream(): Stream { - return StreamSupport.stream(spliterator(), false) - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/openai-java-core/src/main/kotlin/com/openai/models/batches/BatchListPageAsync.kt b/openai-java-core/src/main/kotlin/com/openai/models/batches/BatchListPageAsync.kt index 61612712..0b36c622 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/batches/BatchListPageAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/batches/BatchListPageAsync.kt @@ -2,22 +2,24 @@ package com.openai.models.batches +import com.openai.core.AutoPagerAsync +import com.openai.core.PageAsync import com.openai.core.checkRequired import com.openai.services.async.BatchServiceAsync import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor -import java.util.function.Predicate import kotlin.jvm.optionals.getOrNull /** @see [BatchServiceAsync.list] */ class BatchListPageAsync private constructor( private val service: BatchServiceAsync, + private val streamHandlerExecutor: Executor, private val params: BatchListParams, private val response: BatchListPageResponse, -) { +) : PageAsync { /** * Delegates to [BatchListPageResponse], but gracefully handles missing data. @@ -33,22 +35,16 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): BatchListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): CompletableFuture> = - getNextPageParams() - .map { service.list(it).thenApply { Optional.of(it) } } - .orElseGet { CompletableFuture.completedFuture(Optional.empty()) } + override fun nextPage(): CompletableFuture = service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPagerAsync = AutoPagerAsync.from(this, streamHandlerExecutor) /** The parameters that were used to request this page. */ fun params(): BatchListParams = params @@ -66,6 +62,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -77,18 +74,24 @@ private constructor( class Builder internal constructor() { private var service: BatchServiceAsync? = null + private var streamHandlerExecutor: Executor? = null private var params: BatchListParams? = null private var response: BatchListPageResponse? = null @JvmSynthetic internal fun from(batchListPageAsync: BatchListPageAsync) = apply { service = batchListPageAsync.service + streamHandlerExecutor = batchListPageAsync.streamHandlerExecutor params = batchListPageAsync.params response = batchListPageAsync.response } fun service(service: BatchServiceAsync) = apply { this.service = service } + fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply { + this.streamHandlerExecutor = streamHandlerExecutor + } + /** The parameters that were used to request this page. */ fun params(params: BatchListParams) = apply { this.params = params } @@ -103,6 +106,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -112,47 +116,22 @@ private constructor( fun build(): BatchListPageAsync = BatchListPageAsync( checkRequired("service", service), + checkRequired("streamHandlerExecutor", streamHandlerExecutor), checkRequired("params", params), checkRequired("response", response), ) } - class AutoPager(private val firstPage: BatchListPageAsync) { - - fun forEach(action: Predicate, executor: Executor): CompletableFuture { - fun CompletableFuture>.forEach( - action: (Batch) -> Boolean, - executor: Executor, - ): CompletableFuture = - thenComposeAsync( - { page -> - page - .filter { it.data().all(action) } - .map { it.getNextPage().forEach(action, executor) } - .orElseGet { CompletableFuture.completedFuture(null) } - }, - executor, - ) - return CompletableFuture.completedFuture(Optional.of(firstPage)) - .forEach(action::test, executor) - } - - fun toList(executor: Executor): CompletableFuture> { - val values = mutableListOf() - return forEach(values::add, executor).thenApply { values } - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return /* spotless:off */ other is BatchListPageAsync && service == other.service && params == other.params && response == other.response /* spotless:on */ + return /* spotless:off */ other is BatchListPageAsync && service == other.service && streamHandlerExecutor == other.streamHandlerExecutor && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, params, response) /* spotless:on */ + override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, streamHandlerExecutor, params, response) /* spotless:on */ override fun toString() = - "BatchListPageAsync{service=$service, params=$params, response=$response}" + "BatchListPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, response=$response}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/batches/BatchRetrieveParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/batches/BatchRetrieveParams.kt index 94571a8a..d1667cc1 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/batches/BatchRetrieveParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/batches/BatchRetrieveParams.kt @@ -3,20 +3,21 @@ package com.openai.models.batches import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** Retrieves a batch. */ class BatchRetrieveParams private constructor( - private val batchId: String, + private val batchId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun batchId(): String = batchId + fun batchId(): Optional = Optional.ofNullable(batchId) fun _additionalHeaders(): Headers = additionalHeaders @@ -26,14 +27,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [BatchRetrieveParams]. - * - * The following fields are required: - * ```java - * .batchId() - * ``` - */ + @JvmStatic fun none(): BatchRetrieveParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [BatchRetrieveParams]. */ @JvmStatic fun builder() = Builder() } @@ -51,7 +47,10 @@ private constructor( additionalQueryParams = batchRetrieveParams.additionalQueryParams.toBuilder() } - fun batchId(batchId: String) = apply { this.batchId = batchId } + fun batchId(batchId: String?) = apply { this.batchId = batchId } + + /** Alias for calling [Builder.batchId] with `batchId.orElse(null)`. */ + fun batchId(batchId: Optional) = batchId(batchId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -155,25 +154,14 @@ private constructor( * Returns an immutable instance of [BatchRetrieveParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .batchId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): BatchRetrieveParams = - BatchRetrieveParams( - checkRequired("batchId", batchId), - additionalHeaders.build(), - additionalQueryParams.build(), - ) + BatchRetrieveParams(batchId, additionalHeaders.build(), additionalQueryParams.build()) } fun _pathParam(index: Int): String = when (index) { - 0 -> batchId + 0 -> batchId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/assistants/AssistantDeleteParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/assistants/AssistantDeleteParams.kt index f0c6d40f..b5df03cb 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/assistants/AssistantDeleteParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/assistants/AssistantDeleteParams.kt @@ -4,23 +4,23 @@ package com.openai.models.beta.assistants import com.openai.core.JsonValue import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import com.openai.core.toImmutable import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** Delete an assistant. */ class AssistantDeleteParams private constructor( - private val assistantId: String, + private val assistantId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, ) : Params { - fun assistantId(): String = assistantId + fun assistantId(): Optional = Optional.ofNullable(assistantId) fun _additionalBodyProperties(): Map = additionalBodyProperties @@ -32,14 +32,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [AssistantDeleteParams]. - * - * The following fields are required: - * ```java - * .assistantId() - * ``` - */ + @JvmStatic fun none(): AssistantDeleteParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [AssistantDeleteParams]. */ @JvmStatic fun builder() = Builder() } @@ -59,7 +54,10 @@ private constructor( additionalBodyProperties = assistantDeleteParams.additionalBodyProperties.toMutableMap() } - fun assistantId(assistantId: String) = apply { this.assistantId = assistantId } + fun assistantId(assistantId: String?) = apply { this.assistantId = assistantId } + + /** Alias for calling [Builder.assistantId] with `assistantId.orElse(null)`. */ + fun assistantId(assistantId: Optional) = assistantId(assistantId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -185,17 +183,10 @@ private constructor( * Returns an immutable instance of [AssistantDeleteParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .assistantId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): AssistantDeleteParams = AssistantDeleteParams( - checkRequired("assistantId", assistantId), + assistantId, additionalHeaders.build(), additionalQueryParams.build(), additionalBodyProperties.toImmutable(), @@ -207,7 +198,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> assistantId + 0 -> assistantId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/assistants/AssistantListPage.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/assistants/AssistantListPage.kt index c852b6fe..596b6fa6 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/assistants/AssistantListPage.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/assistants/AssistantListPage.kt @@ -2,12 +2,12 @@ package com.openai.models.beta.assistants +import com.openai.core.AutoPager +import com.openai.core.Page import com.openai.core.checkRequired import com.openai.services.blocking.beta.AssistantService import java.util.Objects import java.util.Optional -import java.util.stream.Stream -import java.util.stream.StreamSupport import kotlin.jvm.optionals.getOrNull /** @see [AssistantService.list] */ @@ -16,7 +16,7 @@ private constructor( private val service: AssistantService, private val params: AssistantListParams, private val response: AssistantListPageResponse, -) { +) : Page { /** * Delegates to [AssistantListPageResponse], but gracefully handles missing data. @@ -32,19 +32,16 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): AssistantListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): Optional = getNextPageParams().map { service.list(it) } + override fun nextPage(): AssistantListPage = service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPager = AutoPager.from(this) /** The parameters that were used to request this page. */ fun params(): AssistantListParams = params @@ -113,25 +110,6 @@ private constructor( ) } - class AutoPager(private val firstPage: AssistantListPage) : Iterable { - - override fun iterator(): Iterator = iterator { - var page = firstPage - var index = 0 - while (true) { - while (index < page.data().size) { - yield(page.data()[index++]) - } - page = page.getNextPage().getOrNull() ?: break - index = 0 - } - } - - fun stream(): Stream { - return StreamSupport.stream(spliterator(), false) - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/assistants/AssistantListPageAsync.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/assistants/AssistantListPageAsync.kt index 0e90b27c..ce42fb78 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/assistants/AssistantListPageAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/assistants/AssistantListPageAsync.kt @@ -2,22 +2,24 @@ package com.openai.models.beta.assistants +import com.openai.core.AutoPagerAsync +import com.openai.core.PageAsync import com.openai.core.checkRequired import com.openai.services.async.beta.AssistantServiceAsync import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor -import java.util.function.Predicate import kotlin.jvm.optionals.getOrNull /** @see [AssistantServiceAsync.list] */ class AssistantListPageAsync private constructor( private val service: AssistantServiceAsync, + private val streamHandlerExecutor: Executor, private val params: AssistantListParams, private val response: AssistantListPageResponse, -) { +) : PageAsync { /** * Delegates to [AssistantListPageResponse], but gracefully handles missing data. @@ -33,22 +35,17 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): AssistantListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): CompletableFuture> = - getNextPageParams() - .map { service.list(it).thenApply { Optional.of(it) } } - .orElseGet { CompletableFuture.completedFuture(Optional.empty()) } + override fun nextPage(): CompletableFuture = + service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPagerAsync = AutoPagerAsync.from(this, streamHandlerExecutor) /** The parameters that were used to request this page. */ fun params(): AssistantListParams = params @@ -66,6 +63,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -77,18 +75,24 @@ private constructor( class Builder internal constructor() { private var service: AssistantServiceAsync? = null + private var streamHandlerExecutor: Executor? = null private var params: AssistantListParams? = null private var response: AssistantListPageResponse? = null @JvmSynthetic internal fun from(assistantListPageAsync: AssistantListPageAsync) = apply { service = assistantListPageAsync.service + streamHandlerExecutor = assistantListPageAsync.streamHandlerExecutor params = assistantListPageAsync.params response = assistantListPageAsync.response } fun service(service: AssistantServiceAsync) = apply { this.service = service } + fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply { + this.streamHandlerExecutor = streamHandlerExecutor + } + /** The parameters that were used to request this page. */ fun params(params: AssistantListParams) = apply { this.params = params } @@ -103,6 +107,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -112,47 +117,22 @@ private constructor( fun build(): AssistantListPageAsync = AssistantListPageAsync( checkRequired("service", service), + checkRequired("streamHandlerExecutor", streamHandlerExecutor), checkRequired("params", params), checkRequired("response", response), ) } - class AutoPager(private val firstPage: AssistantListPageAsync) { - - fun forEach(action: Predicate, executor: Executor): CompletableFuture { - fun CompletableFuture>.forEach( - action: (Assistant) -> Boolean, - executor: Executor, - ): CompletableFuture = - thenComposeAsync( - { page -> - page - .filter { it.data().all(action) } - .map { it.getNextPage().forEach(action, executor) } - .orElseGet { CompletableFuture.completedFuture(null) } - }, - executor, - ) - return CompletableFuture.completedFuture(Optional.of(firstPage)) - .forEach(action::test, executor) - } - - fun toList(executor: Executor): CompletableFuture> { - val values = mutableListOf() - return forEach(values::add, executor).thenApply { values } - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return /* spotless:off */ other is AssistantListPageAsync && service == other.service && params == other.params && response == other.response /* spotless:on */ + return /* spotless:off */ other is AssistantListPageAsync && service == other.service && streamHandlerExecutor == other.streamHandlerExecutor && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, params, response) /* spotless:on */ + override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, streamHandlerExecutor, params, response) /* spotless:on */ override fun toString() = - "AssistantListPageAsync{service=$service, params=$params, response=$response}" + "AssistantListPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, response=$response}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/assistants/AssistantRetrieveParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/assistants/AssistantRetrieveParams.kt index 5ded97d8..7b9b0792 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/assistants/AssistantRetrieveParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/assistants/AssistantRetrieveParams.kt @@ -3,20 +3,21 @@ package com.openai.models.beta.assistants import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** Retrieves an assistant. */ class AssistantRetrieveParams private constructor( - private val assistantId: String, + private val assistantId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun assistantId(): String = assistantId + fun assistantId(): Optional = Optional.ofNullable(assistantId) fun _additionalHeaders(): Headers = additionalHeaders @@ -26,14 +27,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [AssistantRetrieveParams]. - * - * The following fields are required: - * ```java - * .assistantId() - * ``` - */ + @JvmStatic fun none(): AssistantRetrieveParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [AssistantRetrieveParams]. */ @JvmStatic fun builder() = Builder() } @@ -51,7 +47,10 @@ private constructor( additionalQueryParams = assistantRetrieveParams.additionalQueryParams.toBuilder() } - fun assistantId(assistantId: String) = apply { this.assistantId = assistantId } + fun assistantId(assistantId: String?) = apply { this.assistantId = assistantId } + + /** Alias for calling [Builder.assistantId] with `assistantId.orElse(null)`. */ + fun assistantId(assistantId: Optional) = assistantId(assistantId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -155,17 +154,10 @@ private constructor( * Returns an immutable instance of [AssistantRetrieveParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .assistantId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): AssistantRetrieveParams = AssistantRetrieveParams( - checkRequired("assistantId", assistantId), + assistantId, additionalHeaders.build(), additionalQueryParams.build(), ) @@ -173,7 +165,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> assistantId + 0 -> assistantId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/assistants/AssistantUpdateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/assistants/AssistantUpdateParams.kt index 92fcba31..24ae8550 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/assistants/AssistantUpdateParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/assistants/AssistantUpdateParams.kt @@ -13,7 +13,6 @@ import com.openai.core.JsonMissing import com.openai.core.JsonValue import com.openai.core.Params import com.openai.core.checkKnown -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import com.openai.core.toImmutable @@ -32,13 +31,13 @@ import kotlin.jvm.optionals.getOrNull /** Modifies an assistant. */ class AssistantUpdateParams private constructor( - private val assistantId: String, + private val assistantId: String?, private val body: Body, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun assistantId(): String = assistantId + fun assistantId(): Optional = Optional.ofNullable(assistantId) /** * The description of the assistant. The maximum length is 512 characters. @@ -253,14 +252,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [AssistantUpdateParams]. - * - * The following fields are required: - * ```java - * .assistantId() - * ``` - */ + @JvmStatic fun none(): AssistantUpdateParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [AssistantUpdateParams]. */ @JvmStatic fun builder() = Builder() } @@ -280,7 +274,10 @@ private constructor( additionalQueryParams = assistantUpdateParams.additionalQueryParams.toBuilder() } - fun assistantId(assistantId: String) = apply { this.assistantId = assistantId } + fun assistantId(assistantId: String?) = apply { this.assistantId = assistantId } + + /** Alias for calling [Builder.assistantId] with `assistantId.orElse(null)`. */ + fun assistantId(assistantId: Optional) = assistantId(assistantId.getOrNull()) /** * Sets the entire request body. @@ -723,17 +720,10 @@ private constructor( * Returns an immutable instance of [AssistantUpdateParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .assistantId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): AssistantUpdateParams = AssistantUpdateParams( - checkRequired("assistantId", assistantId), + assistantId, body.build(), additionalHeaders.build(), additionalQueryParams.build(), @@ -744,7 +734,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> assistantId + 0 -> assistantId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/ThreadDeleteParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/ThreadDeleteParams.kt index fd960288..637a5853 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/ThreadDeleteParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/ThreadDeleteParams.kt @@ -4,23 +4,23 @@ package com.openai.models.beta.threads import com.openai.core.JsonValue import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import com.openai.core.toImmutable import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** Delete a thread. */ class ThreadDeleteParams private constructor( - private val threadId: String, + private val threadId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, ) : Params { - fun threadId(): String = threadId + fun threadId(): Optional = Optional.ofNullable(threadId) fun _additionalBodyProperties(): Map = additionalBodyProperties @@ -32,14 +32,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [ThreadDeleteParams]. - * - * The following fields are required: - * ```java - * .threadId() - * ``` - */ + @JvmStatic fun none(): ThreadDeleteParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [ThreadDeleteParams]. */ @JvmStatic fun builder() = Builder() } @@ -59,7 +54,10 @@ private constructor( additionalBodyProperties = threadDeleteParams.additionalBodyProperties.toMutableMap() } - fun threadId(threadId: String) = apply { this.threadId = threadId } + fun threadId(threadId: String?) = apply { this.threadId = threadId } + + /** Alias for calling [Builder.threadId] with `threadId.orElse(null)`. */ + fun threadId(threadId: Optional) = threadId(threadId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -185,17 +183,10 @@ private constructor( * Returns an immutable instance of [ThreadDeleteParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .threadId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): ThreadDeleteParams = ThreadDeleteParams( - checkRequired("threadId", threadId), + threadId, additionalHeaders.build(), additionalQueryParams.build(), additionalBodyProperties.toImmutable(), @@ -207,7 +198,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> threadId + 0 -> threadId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/ThreadRetrieveParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/ThreadRetrieveParams.kt index 1d5bb1ae..2ee637c6 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/ThreadRetrieveParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/ThreadRetrieveParams.kt @@ -3,20 +3,21 @@ package com.openai.models.beta.threads import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** Retrieves a thread. */ class ThreadRetrieveParams private constructor( - private val threadId: String, + private val threadId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun threadId(): String = threadId + fun threadId(): Optional = Optional.ofNullable(threadId) fun _additionalHeaders(): Headers = additionalHeaders @@ -26,14 +27,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [ThreadRetrieveParams]. - * - * The following fields are required: - * ```java - * .threadId() - * ``` - */ + @JvmStatic fun none(): ThreadRetrieveParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [ThreadRetrieveParams]. */ @JvmStatic fun builder() = Builder() } @@ -51,7 +47,10 @@ private constructor( additionalQueryParams = threadRetrieveParams.additionalQueryParams.toBuilder() } - fun threadId(threadId: String) = apply { this.threadId = threadId } + fun threadId(threadId: String?) = apply { this.threadId = threadId } + + /** Alias for calling [Builder.threadId] with `threadId.orElse(null)`. */ + fun threadId(threadId: Optional) = threadId(threadId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -155,25 +154,14 @@ private constructor( * Returns an immutable instance of [ThreadRetrieveParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .threadId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): ThreadRetrieveParams = - ThreadRetrieveParams( - checkRequired("threadId", threadId), - additionalHeaders.build(), - additionalQueryParams.build(), - ) + ThreadRetrieveParams(threadId, additionalHeaders.build(), additionalQueryParams.build()) } fun _pathParam(index: Int): String = when (index) { - 0 -> threadId + 0 -> threadId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/ThreadUpdateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/ThreadUpdateParams.kt index 3afece77..d6d639af 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/ThreadUpdateParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/ThreadUpdateParams.kt @@ -12,7 +12,6 @@ import com.openai.core.JsonMissing import com.openai.core.JsonValue import com.openai.core.Params import com.openai.core.checkKnown -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import com.openai.core.toImmutable @@ -25,13 +24,13 @@ import kotlin.jvm.optionals.getOrNull /** Modifies a thread. */ class ThreadUpdateParams private constructor( - private val threadId: String, + private val threadId: String?, private val body: Body, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun threadId(): String = threadId + fun threadId(): Optional = Optional.ofNullable(threadId) /** * Set of 16 key-value pairs that can be attached to an object. This can be useful for storing @@ -80,14 +79,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [ThreadUpdateParams]. - * - * The following fields are required: - * ```java - * .threadId() - * ``` - */ + @JvmStatic fun none(): ThreadUpdateParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [ThreadUpdateParams]. */ @JvmStatic fun builder() = Builder() } @@ -107,7 +101,10 @@ private constructor( additionalQueryParams = threadUpdateParams.additionalQueryParams.toBuilder() } - fun threadId(threadId: String) = apply { this.threadId = threadId } + fun threadId(threadId: String?) = apply { this.threadId = threadId } + + /** Alias for calling [Builder.threadId] with `threadId.orElse(null)`. */ + fun threadId(threadId: Optional) = threadId(threadId.getOrNull()) /** * Sets the entire request body. @@ -287,17 +284,10 @@ private constructor( * Returns an immutable instance of [ThreadUpdateParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .threadId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): ThreadUpdateParams = ThreadUpdateParams( - checkRequired("threadId", threadId), + threadId, body.build(), additionalHeaders.build(), additionalQueryParams.build(), @@ -308,7 +298,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> threadId + 0 -> threadId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/messages/MessageCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/messages/MessageCreateParams.kt index 6bf8f054..caca9be5 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/messages/MessageCreateParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/messages/MessageCreateParams.kt @@ -38,13 +38,13 @@ import kotlin.jvm.optionals.getOrNull /** Create a message. */ class MessageCreateParams private constructor( - private val threadId: String, + private val threadId: String?, private val body: Body, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun threadId(): String = threadId + fun threadId(): Optional = Optional.ofNullable(threadId) /** * The text contents of the message. @@ -130,7 +130,6 @@ private constructor( * * The following fields are required: * ```java - * .threadId() * .content() * .role() * ``` @@ -154,7 +153,10 @@ private constructor( additionalQueryParams = messageCreateParams.additionalQueryParams.toBuilder() } - fun threadId(threadId: String) = apply { this.threadId = threadId } + fun threadId(threadId: String?) = apply { this.threadId = threadId } + + /** Alias for calling [Builder.threadId] with `threadId.orElse(null)`. */ + fun threadId(threadId: Optional) = threadId(threadId.getOrNull()) /** * Sets the entire request body. @@ -378,7 +380,6 @@ private constructor( * * The following fields are required: * ```java - * .threadId() * .content() * .role() * ``` @@ -387,7 +388,7 @@ private constructor( */ fun build(): MessageCreateParams = MessageCreateParams( - checkRequired("threadId", threadId), + threadId, body.build(), additionalHeaders.build(), additionalQueryParams.build(), @@ -398,7 +399,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> threadId + 0 -> threadId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/messages/MessageDeleteParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/messages/MessageDeleteParams.kt index e2022510..9c79b7b3 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/messages/MessageDeleteParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/messages/MessageDeleteParams.kt @@ -10,12 +10,13 @@ import com.openai.core.http.QueryParams import com.openai.core.toImmutable import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** Deletes a message. */ class MessageDeleteParams private constructor( private val threadId: String, - private val messageId: String, + private val messageId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, @@ -23,7 +24,7 @@ private constructor( fun threadId(): String = threadId - fun messageId(): String = messageId + fun messageId(): Optional = Optional.ofNullable(messageId) fun _additionalBodyProperties(): Map = additionalBodyProperties @@ -41,7 +42,6 @@ private constructor( * The following fields are required: * ```java * .threadId() - * .messageId() * ``` */ @JvmStatic fun builder() = Builder() @@ -67,7 +67,10 @@ private constructor( fun threadId(threadId: String) = apply { this.threadId = threadId } - fun messageId(messageId: String) = apply { this.messageId = messageId } + fun messageId(messageId: String?) = apply { this.messageId = messageId } + + /** Alias for calling [Builder.messageId] with `messageId.orElse(null)`. */ + fun messageId(messageId: Optional) = messageId(messageId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -197,7 +200,6 @@ private constructor( * The following fields are required: * ```java * .threadId() - * .messageId() * ``` * * @throws IllegalStateException if any required field is unset. @@ -205,7 +207,7 @@ private constructor( fun build(): MessageDeleteParams = MessageDeleteParams( checkRequired("threadId", threadId), - checkRequired("messageId", messageId), + messageId, additionalHeaders.build(), additionalQueryParams.build(), additionalBodyProperties.toImmutable(), @@ -218,7 +220,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { 0 -> threadId - 1 -> messageId + 1 -> messageId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/messages/MessageListPage.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/messages/MessageListPage.kt index 14a9a44d..560ff950 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/messages/MessageListPage.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/messages/MessageListPage.kt @@ -2,12 +2,12 @@ package com.openai.models.beta.threads.messages +import com.openai.core.AutoPager +import com.openai.core.Page import com.openai.core.checkRequired import com.openai.services.blocking.beta.threads.MessageService import java.util.Objects import java.util.Optional -import java.util.stream.Stream -import java.util.stream.StreamSupport import kotlin.jvm.optionals.getOrNull /** @see [MessageService.list] */ @@ -16,7 +16,7 @@ private constructor( private val service: MessageService, private val params: MessageListParams, private val response: MessageListPageResponse, -) { +) : Page { /** * Delegates to [MessageListPageResponse], but gracefully handles missing data. @@ -32,19 +32,16 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): MessageListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): Optional = getNextPageParams().map { service.list(it) } + override fun nextPage(): MessageListPage = service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPager = AutoPager.from(this) /** The parameters that were used to request this page. */ fun params(): MessageListParams = params @@ -113,25 +110,6 @@ private constructor( ) } - class AutoPager(private val firstPage: MessageListPage) : Iterable { - - override fun iterator(): Iterator = iterator { - var page = firstPage - var index = 0 - while (true) { - while (index < page.data().size) { - yield(page.data()[index++]) - } - page = page.getNextPage().getOrNull() ?: break - index = 0 - } - } - - fun stream(): Stream { - return StreamSupport.stream(spliterator(), false) - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/messages/MessageListPageAsync.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/messages/MessageListPageAsync.kt index fd1595e3..8b6a0d4e 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/messages/MessageListPageAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/messages/MessageListPageAsync.kt @@ -2,22 +2,24 @@ package com.openai.models.beta.threads.messages +import com.openai.core.AutoPagerAsync +import com.openai.core.PageAsync import com.openai.core.checkRequired import com.openai.services.async.beta.threads.MessageServiceAsync import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor -import java.util.function.Predicate import kotlin.jvm.optionals.getOrNull /** @see [MessageServiceAsync.list] */ class MessageListPageAsync private constructor( private val service: MessageServiceAsync, + private val streamHandlerExecutor: Executor, private val params: MessageListParams, private val response: MessageListPageResponse, -) { +) : PageAsync { /** * Delegates to [MessageListPageResponse], but gracefully handles missing data. @@ -33,22 +35,17 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): MessageListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): CompletableFuture> = - getNextPageParams() - .map { service.list(it).thenApply { Optional.of(it) } } - .orElseGet { CompletableFuture.completedFuture(Optional.empty()) } + override fun nextPage(): CompletableFuture = + service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPagerAsync = AutoPagerAsync.from(this, streamHandlerExecutor) /** The parameters that were used to request this page. */ fun params(): MessageListParams = params @@ -66,6 +63,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -77,18 +75,24 @@ private constructor( class Builder internal constructor() { private var service: MessageServiceAsync? = null + private var streamHandlerExecutor: Executor? = null private var params: MessageListParams? = null private var response: MessageListPageResponse? = null @JvmSynthetic internal fun from(messageListPageAsync: MessageListPageAsync) = apply { service = messageListPageAsync.service + streamHandlerExecutor = messageListPageAsync.streamHandlerExecutor params = messageListPageAsync.params response = messageListPageAsync.response } fun service(service: MessageServiceAsync) = apply { this.service = service } + fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply { + this.streamHandlerExecutor = streamHandlerExecutor + } + /** The parameters that were used to request this page. */ fun params(params: MessageListParams) = apply { this.params = params } @@ -103,6 +107,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -112,47 +117,22 @@ private constructor( fun build(): MessageListPageAsync = MessageListPageAsync( checkRequired("service", service), + checkRequired("streamHandlerExecutor", streamHandlerExecutor), checkRequired("params", params), checkRequired("response", response), ) } - class AutoPager(private val firstPage: MessageListPageAsync) { - - fun forEach(action: Predicate, executor: Executor): CompletableFuture { - fun CompletableFuture>.forEach( - action: (Message) -> Boolean, - executor: Executor, - ): CompletableFuture = - thenComposeAsync( - { page -> - page - .filter { it.data().all(action) } - .map { it.getNextPage().forEach(action, executor) } - .orElseGet { CompletableFuture.completedFuture(null) } - }, - executor, - ) - return CompletableFuture.completedFuture(Optional.of(firstPage)) - .forEach(action::test, executor) - } - - fun toList(executor: Executor): CompletableFuture> { - val values = mutableListOf() - return forEach(values::add, executor).thenApply { values } - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return /* spotless:off */ other is MessageListPageAsync && service == other.service && params == other.params && response == other.response /* spotless:on */ + return /* spotless:off */ other is MessageListPageAsync && service == other.service && streamHandlerExecutor == other.streamHandlerExecutor && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, params, response) /* spotless:on */ + override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, streamHandlerExecutor, params, response) /* spotless:on */ override fun toString() = - "MessageListPageAsync{service=$service, params=$params, response=$response}" + "MessageListPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, response=$response}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/messages/MessageListParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/messages/MessageListParams.kt index 0a1f8bbb..add2694a 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/messages/MessageListParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/messages/MessageListParams.kt @@ -6,7 +6,6 @@ import com.fasterxml.jackson.annotation.JsonCreator import com.openai.core.Enum import com.openai.core.JsonField import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import com.openai.errors.OpenAIInvalidDataException @@ -17,7 +16,7 @@ import kotlin.jvm.optionals.getOrNull /** Returns a list of messages for a given thread. */ class MessageListParams private constructor( - private val threadId: String, + private val threadId: String?, private val after: String?, private val before: String?, private val limit: Long?, @@ -27,7 +26,7 @@ private constructor( private val additionalQueryParams: QueryParams, ) : Params { - fun threadId(): String = threadId + fun threadId(): Optional = Optional.ofNullable(threadId) /** * A cursor for use in pagination. `after` is an object ID that defines your place in the list. @@ -66,14 +65,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [MessageListParams]. - * - * The following fields are required: - * ```java - * .threadId() - * ``` - */ + @JvmStatic fun none(): MessageListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [MessageListParams]. */ @JvmStatic fun builder() = Builder() } @@ -101,7 +95,10 @@ private constructor( additionalQueryParams = messageListParams.additionalQueryParams.toBuilder() } - fun threadId(threadId: String) = apply { this.threadId = threadId } + fun threadId(threadId: String?) = apply { this.threadId = threadId } + + /** Alias for calling [Builder.threadId] with `threadId.orElse(null)`. */ + fun threadId(threadId: Optional) = threadId(threadId.getOrNull()) /** * A cursor for use in pagination. `after` is an object ID that defines your place in the @@ -258,17 +255,10 @@ private constructor( * Returns an immutable instance of [MessageListParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .threadId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): MessageListParams = MessageListParams( - checkRequired("threadId", threadId), + threadId, after, before, limit, @@ -281,7 +271,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> threadId + 0 -> threadId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/messages/MessageRetrieveParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/messages/MessageRetrieveParams.kt index fc521fbf..4c9cb093 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/messages/MessageRetrieveParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/messages/MessageRetrieveParams.kt @@ -7,19 +7,21 @@ import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** Retrieve a message. */ class MessageRetrieveParams private constructor( private val threadId: String, - private val messageId: String, + private val messageId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { fun threadId(): String = threadId - fun messageId(): String = messageId + fun messageId(): Optional = Optional.ofNullable(messageId) fun _additionalHeaders(): Headers = additionalHeaders @@ -35,7 +37,6 @@ private constructor( * The following fields are required: * ```java * .threadId() - * .messageId() * ``` */ @JvmStatic fun builder() = Builder() @@ -59,7 +60,10 @@ private constructor( fun threadId(threadId: String) = apply { this.threadId = threadId } - fun messageId(messageId: String) = apply { this.messageId = messageId } + fun messageId(messageId: String?) = apply { this.messageId = messageId } + + /** Alias for calling [Builder.messageId] with `messageId.orElse(null)`. */ + fun messageId(messageId: Optional) = messageId(messageId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -167,7 +171,6 @@ private constructor( * The following fields are required: * ```java * .threadId() - * .messageId() * ``` * * @throws IllegalStateException if any required field is unset. @@ -175,7 +178,7 @@ private constructor( fun build(): MessageRetrieveParams = MessageRetrieveParams( checkRequired("threadId", threadId), - checkRequired("messageId", messageId), + messageId, additionalHeaders.build(), additionalQueryParams.build(), ) @@ -184,7 +187,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { 0 -> threadId - 1 -> messageId + 1 -> messageId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/messages/MessageUpdateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/messages/MessageUpdateParams.kt index de35e85e..30271871 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/messages/MessageUpdateParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/messages/MessageUpdateParams.kt @@ -25,7 +25,7 @@ import kotlin.jvm.optionals.getOrNull class MessageUpdateParams private constructor( private val threadId: String, - private val messageId: String, + private val messageId: String?, private val body: Body, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, @@ -33,7 +33,7 @@ private constructor( fun threadId(): String = threadId - fun messageId(): String = messageId + fun messageId(): Optional = Optional.ofNullable(messageId) /** * Set of 16 key-value pairs that can be attached to an object. This can be useful for storing @@ -71,7 +71,6 @@ private constructor( * The following fields are required: * ```java * .threadId() - * .messageId() * ``` */ @JvmStatic fun builder() = Builder() @@ -97,7 +96,10 @@ private constructor( fun threadId(threadId: String) = apply { this.threadId = threadId } - fun messageId(messageId: String) = apply { this.messageId = messageId } + fun messageId(messageId: String?) = apply { this.messageId = messageId } + + /** Alias for calling [Builder.messageId] with `messageId.orElse(null)`. */ + fun messageId(messageId: Optional) = messageId(messageId.getOrNull()) /** * Sets the entire request body. @@ -255,7 +257,6 @@ private constructor( * The following fields are required: * ```java * .threadId() - * .messageId() * ``` * * @throws IllegalStateException if any required field is unset. @@ -263,7 +264,7 @@ private constructor( fun build(): MessageUpdateParams = MessageUpdateParams( checkRequired("threadId", threadId), - checkRequired("messageId", messageId), + messageId, body.build(), additionalHeaders.build(), additionalQueryParams.build(), @@ -275,7 +276,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { 0 -> threadId - 1 -> messageId + 1 -> messageId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunCancelParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunCancelParams.kt index cf442b6c..ccb81100 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunCancelParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunCancelParams.kt @@ -10,12 +10,13 @@ import com.openai.core.http.QueryParams import com.openai.core.toImmutable import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** Cancels a run that is `in_progress`. */ class RunCancelParams private constructor( private val threadId: String, - private val runId: String, + private val runId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, @@ -23,7 +24,7 @@ private constructor( fun threadId(): String = threadId - fun runId(): String = runId + fun runId(): Optional = Optional.ofNullable(runId) fun _additionalBodyProperties(): Map = additionalBodyProperties @@ -41,7 +42,6 @@ private constructor( * The following fields are required: * ```java * .threadId() - * .runId() * ``` */ @JvmStatic fun builder() = Builder() @@ -67,7 +67,10 @@ private constructor( fun threadId(threadId: String) = apply { this.threadId = threadId } - fun runId(runId: String) = apply { this.runId = runId } + fun runId(runId: String?) = apply { this.runId = runId } + + /** Alias for calling [Builder.runId] with `runId.orElse(null)`. */ + fun runId(runId: Optional) = runId(runId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -197,7 +200,6 @@ private constructor( * The following fields are required: * ```java * .threadId() - * .runId() * ``` * * @throws IllegalStateException if any required field is unset. @@ -205,7 +207,7 @@ private constructor( fun build(): RunCancelParams = RunCancelParams( checkRequired("threadId", threadId), - checkRequired("runId", runId), + runId, additionalHeaders.build(), additionalQueryParams.build(), additionalBodyProperties.toImmutable(), @@ -218,7 +220,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { 0 -> threadId - 1 -> runId + 1 -> runId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunCreateParams.kt index 3d44da70..02f16270 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunCreateParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunCreateParams.kt @@ -52,14 +52,14 @@ import kotlin.jvm.optionals.getOrNull /** Create a run. */ class RunCreateParams private constructor( - private val threadId: String, + private val threadId: String?, private val include: List?, private val body: Body, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun threadId(): String = threadId + fun threadId(): Optional = Optional.ofNullable(threadId) /** * A list of additional fields to include in the response. Currently the only supported value is @@ -385,7 +385,6 @@ private constructor( * * The following fields are required: * ```java - * .threadId() * .assistantId() * ``` */ @@ -410,7 +409,10 @@ private constructor( additionalQueryParams = runCreateParams.additionalQueryParams.toBuilder() } - fun threadId(threadId: String) = apply { this.threadId = threadId } + fun threadId(threadId: String?) = apply { this.threadId = threadId } + + /** Alias for calling [Builder.threadId] with `threadId.orElse(null)`. */ + fun threadId(threadId: Optional) = threadId(threadId.getOrNull()) /** * A list of additional fields to include in the response. Currently the only supported @@ -1057,7 +1059,6 @@ private constructor( * * The following fields are required: * ```java - * .threadId() * .assistantId() * ``` * @@ -1065,7 +1066,7 @@ private constructor( */ fun build(): RunCreateParams = RunCreateParams( - checkRequired("threadId", threadId), + threadId, include?.toImmutable(), body.build(), additionalHeaders.build(), @@ -1077,7 +1078,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> threadId + 0 -> threadId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunListPage.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunListPage.kt index 108f1287..206a0e6a 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunListPage.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunListPage.kt @@ -2,12 +2,12 @@ package com.openai.models.beta.threads.runs +import com.openai.core.AutoPager +import com.openai.core.Page import com.openai.core.checkRequired import com.openai.services.blocking.beta.threads.RunService import java.util.Objects import java.util.Optional -import java.util.stream.Stream -import java.util.stream.StreamSupport import kotlin.jvm.optionals.getOrNull /** @see [RunService.list] */ @@ -16,7 +16,7 @@ private constructor( private val service: RunService, private val params: RunListParams, private val response: RunListPageResponse, -) { +) : Page { /** * Delegates to [RunListPageResponse], but gracefully handles missing data. @@ -32,19 +32,16 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): RunListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): Optional = getNextPageParams().map { service.list(it) } + override fun nextPage(): RunListPage = service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPager = AutoPager.from(this) /** The parameters that were used to request this page. */ fun params(): RunListParams = params @@ -113,25 +110,6 @@ private constructor( ) } - class AutoPager(private val firstPage: RunListPage) : Iterable { - - override fun iterator(): Iterator = iterator { - var page = firstPage - var index = 0 - while (true) { - while (index < page.data().size) { - yield(page.data()[index++]) - } - page = page.getNextPage().getOrNull() ?: break - index = 0 - } - } - - fun stream(): Stream { - return StreamSupport.stream(spliterator(), false) - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunListPageAsync.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunListPageAsync.kt index ca329d17..e5e70466 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunListPageAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunListPageAsync.kt @@ -2,22 +2,24 @@ package com.openai.models.beta.threads.runs +import com.openai.core.AutoPagerAsync +import com.openai.core.PageAsync import com.openai.core.checkRequired import com.openai.services.async.beta.threads.RunServiceAsync import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor -import java.util.function.Predicate import kotlin.jvm.optionals.getOrNull /** @see [RunServiceAsync.list] */ class RunListPageAsync private constructor( private val service: RunServiceAsync, + private val streamHandlerExecutor: Executor, private val params: RunListParams, private val response: RunListPageResponse, -) { +) : PageAsync { /** * Delegates to [RunListPageResponse], but gracefully handles missing data. @@ -33,22 +35,16 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): RunListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): CompletableFuture> = - getNextPageParams() - .map { service.list(it).thenApply { Optional.of(it) } } - .orElseGet { CompletableFuture.completedFuture(Optional.empty()) } + override fun nextPage(): CompletableFuture = service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPagerAsync = AutoPagerAsync.from(this, streamHandlerExecutor) /** The parameters that were used to request this page. */ fun params(): RunListParams = params @@ -66,6 +62,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -77,18 +74,24 @@ private constructor( class Builder internal constructor() { private var service: RunServiceAsync? = null + private var streamHandlerExecutor: Executor? = null private var params: RunListParams? = null private var response: RunListPageResponse? = null @JvmSynthetic internal fun from(runListPageAsync: RunListPageAsync) = apply { service = runListPageAsync.service + streamHandlerExecutor = runListPageAsync.streamHandlerExecutor params = runListPageAsync.params response = runListPageAsync.response } fun service(service: RunServiceAsync) = apply { this.service = service } + fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply { + this.streamHandlerExecutor = streamHandlerExecutor + } + /** The parameters that were used to request this page. */ fun params(params: RunListParams) = apply { this.params = params } @@ -103,6 +106,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -112,47 +116,22 @@ private constructor( fun build(): RunListPageAsync = RunListPageAsync( checkRequired("service", service), + checkRequired("streamHandlerExecutor", streamHandlerExecutor), checkRequired("params", params), checkRequired("response", response), ) } - class AutoPager(private val firstPage: RunListPageAsync) { - - fun forEach(action: Predicate, executor: Executor): CompletableFuture { - fun CompletableFuture>.forEach( - action: (Run) -> Boolean, - executor: Executor, - ): CompletableFuture = - thenComposeAsync( - { page -> - page - .filter { it.data().all(action) } - .map { it.getNextPage().forEach(action, executor) } - .orElseGet { CompletableFuture.completedFuture(null) } - }, - executor, - ) - return CompletableFuture.completedFuture(Optional.of(firstPage)) - .forEach(action::test, executor) - } - - fun toList(executor: Executor): CompletableFuture> { - val values = mutableListOf() - return forEach(values::add, executor).thenApply { values } - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return /* spotless:off */ other is RunListPageAsync && service == other.service && params == other.params && response == other.response /* spotless:on */ + return /* spotless:off */ other is RunListPageAsync && service == other.service && streamHandlerExecutor == other.streamHandlerExecutor && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, params, response) /* spotless:on */ + override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, streamHandlerExecutor, params, response) /* spotless:on */ override fun toString() = - "RunListPageAsync{service=$service, params=$params, response=$response}" + "RunListPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, response=$response}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunListParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunListParams.kt index 22d96714..cd4e0d5d 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunListParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunListParams.kt @@ -6,7 +6,6 @@ import com.fasterxml.jackson.annotation.JsonCreator import com.openai.core.Enum import com.openai.core.JsonField import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import com.openai.errors.OpenAIInvalidDataException @@ -17,7 +16,7 @@ import kotlin.jvm.optionals.getOrNull /** Returns a list of runs belonging to a thread. */ class RunListParams private constructor( - private val threadId: String, + private val threadId: String?, private val after: String?, private val before: String?, private val limit: Long?, @@ -26,7 +25,7 @@ private constructor( private val additionalQueryParams: QueryParams, ) : Params { - fun threadId(): String = threadId + fun threadId(): Optional = Optional.ofNullable(threadId) /** * A cursor for use in pagination. `after` is an object ID that defines your place in the list. @@ -62,14 +61,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [RunListParams]. - * - * The following fields are required: - * ```java - * .threadId() - * ``` - */ + @JvmStatic fun none(): RunListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [RunListParams]. */ @JvmStatic fun builder() = Builder() } @@ -95,7 +89,10 @@ private constructor( additionalQueryParams = runListParams.additionalQueryParams.toBuilder() } - fun threadId(threadId: String) = apply { this.threadId = threadId } + fun threadId(threadId: String?) = apply { this.threadId = threadId } + + /** Alias for calling [Builder.threadId] with `threadId.orElse(null)`. */ + fun threadId(threadId: Optional) = threadId(threadId.getOrNull()) /** * A cursor for use in pagination. `after` is an object ID that defines your place in the @@ -246,17 +243,10 @@ private constructor( * Returns an immutable instance of [RunListParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .threadId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): RunListParams = RunListParams( - checkRequired("threadId", threadId), + threadId, after, before, limit, @@ -268,7 +258,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> threadId + 0 -> threadId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunRetrieveParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunRetrieveParams.kt index 850f086c..1ffc8e41 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunRetrieveParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunRetrieveParams.kt @@ -7,19 +7,21 @@ import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** Retrieves a run. */ class RunRetrieveParams private constructor( private val threadId: String, - private val runId: String, + private val runId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { fun threadId(): String = threadId - fun runId(): String = runId + fun runId(): Optional = Optional.ofNullable(runId) fun _additionalHeaders(): Headers = additionalHeaders @@ -35,7 +37,6 @@ private constructor( * The following fields are required: * ```java * .threadId() - * .runId() * ``` */ @JvmStatic fun builder() = Builder() @@ -59,7 +60,10 @@ private constructor( fun threadId(threadId: String) = apply { this.threadId = threadId } - fun runId(runId: String) = apply { this.runId = runId } + fun runId(runId: String?) = apply { this.runId = runId } + + /** Alias for calling [Builder.runId] with `runId.orElse(null)`. */ + fun runId(runId: Optional) = runId(runId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -167,7 +171,6 @@ private constructor( * The following fields are required: * ```java * .threadId() - * .runId() * ``` * * @throws IllegalStateException if any required field is unset. @@ -175,7 +178,7 @@ private constructor( fun build(): RunRetrieveParams = RunRetrieveParams( checkRequired("threadId", threadId), - checkRequired("runId", runId), + runId, additionalHeaders.build(), additionalQueryParams.build(), ) @@ -184,7 +187,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { 0 -> threadId - 1 -> runId + 1 -> runId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunSubmitToolOutputsParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunSubmitToolOutputsParams.kt index 38e05998..8b23d6c9 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunSubmitToolOutputsParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunSubmitToolOutputsParams.kt @@ -30,7 +30,7 @@ import kotlin.jvm.optionals.getOrNull class RunSubmitToolOutputsParams private constructor( private val threadId: String, - private val runId: String, + private val runId: String?, private val body: Body, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, @@ -38,7 +38,7 @@ private constructor( fun threadId(): String = threadId - fun runId(): String = runId + fun runId(): Optional = Optional.ofNullable(runId) /** * A list of tools for which the outputs are being submitted. @@ -71,7 +71,6 @@ private constructor( * The following fields are required: * ```java * .threadId() - * .runId() * .toolOutputs() * ``` */ @@ -98,7 +97,10 @@ private constructor( fun threadId(threadId: String) = apply { this.threadId = threadId } - fun runId(runId: String) = apply { this.runId = runId } + fun runId(runId: String?) = apply { this.runId = runId } + + /** Alias for calling [Builder.runId] with `runId.orElse(null)`. */ + fun runId(runId: Optional) = runId(runId.getOrNull()) /** * Sets the entire request body. @@ -255,7 +257,6 @@ private constructor( * The following fields are required: * ```java * .threadId() - * .runId() * .toolOutputs() * ``` * @@ -264,7 +265,7 @@ private constructor( fun build(): RunSubmitToolOutputsParams = RunSubmitToolOutputsParams( checkRequired("threadId", threadId), - checkRequired("runId", runId), + runId, body.build(), additionalHeaders.build(), additionalQueryParams.build(), @@ -276,7 +277,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { 0 -> threadId - 1 -> runId + 1 -> runId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunUpdateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunUpdateParams.kt index b93a1235..21ecf31a 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunUpdateParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/RunUpdateParams.kt @@ -25,7 +25,7 @@ import kotlin.jvm.optionals.getOrNull class RunUpdateParams private constructor( private val threadId: String, - private val runId: String, + private val runId: String?, private val body: Body, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, @@ -33,7 +33,7 @@ private constructor( fun threadId(): String = threadId - fun runId(): String = runId + fun runId(): Optional = Optional.ofNullable(runId) /** * Set of 16 key-value pairs that can be attached to an object. This can be useful for storing @@ -71,7 +71,6 @@ private constructor( * The following fields are required: * ```java * .threadId() - * .runId() * ``` */ @JvmStatic fun builder() = Builder() @@ -97,7 +96,10 @@ private constructor( fun threadId(threadId: String) = apply { this.threadId = threadId } - fun runId(runId: String) = apply { this.runId = runId } + fun runId(runId: String?) = apply { this.runId = runId } + + /** Alias for calling [Builder.runId] with `runId.orElse(null)`. */ + fun runId(runId: Optional) = runId(runId.getOrNull()) /** * Sets the entire request body. @@ -255,7 +257,6 @@ private constructor( * The following fields are required: * ```java * .threadId() - * .runId() * ``` * * @throws IllegalStateException if any required field is unset. @@ -263,7 +264,7 @@ private constructor( fun build(): RunUpdateParams = RunUpdateParams( checkRequired("threadId", threadId), - checkRequired("runId", runId), + runId, body.build(), additionalHeaders.build(), additionalQueryParams.build(), @@ -275,7 +276,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { 0 -> threadId - 1 -> runId + 1 -> runId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/steps/StepListPage.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/steps/StepListPage.kt index b9740fab..353febb1 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/steps/StepListPage.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/steps/StepListPage.kt @@ -2,12 +2,12 @@ package com.openai.models.beta.threads.runs.steps +import com.openai.core.AutoPager +import com.openai.core.Page import com.openai.core.checkRequired import com.openai.services.blocking.beta.threads.runs.StepService import java.util.Objects import java.util.Optional -import java.util.stream.Stream -import java.util.stream.StreamSupport import kotlin.jvm.optionals.getOrNull /** @see [StepService.list] */ @@ -16,7 +16,7 @@ private constructor( private val service: StepService, private val params: StepListParams, private val response: StepListPageResponse, -) { +) : Page { /** * Delegates to [StepListPageResponse], but gracefully handles missing data. @@ -32,19 +32,16 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): StepListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): Optional = getNextPageParams().map { service.list(it) } + override fun nextPage(): StepListPage = service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPager = AutoPager.from(this) /** The parameters that were used to request this page. */ fun params(): StepListParams = params @@ -113,25 +110,6 @@ private constructor( ) } - class AutoPager(private val firstPage: StepListPage) : Iterable { - - override fun iterator(): Iterator = iterator { - var page = firstPage - var index = 0 - while (true) { - while (index < page.data().size) { - yield(page.data()[index++]) - } - page = page.getNextPage().getOrNull() ?: break - index = 0 - } - } - - fun stream(): Stream { - return StreamSupport.stream(spliterator(), false) - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/steps/StepListPageAsync.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/steps/StepListPageAsync.kt index a753633e..8e5b3009 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/steps/StepListPageAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/steps/StepListPageAsync.kt @@ -2,22 +2,24 @@ package com.openai.models.beta.threads.runs.steps +import com.openai.core.AutoPagerAsync +import com.openai.core.PageAsync import com.openai.core.checkRequired import com.openai.services.async.beta.threads.runs.StepServiceAsync import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor -import java.util.function.Predicate import kotlin.jvm.optionals.getOrNull /** @see [StepServiceAsync.list] */ class StepListPageAsync private constructor( private val service: StepServiceAsync, + private val streamHandlerExecutor: Executor, private val params: StepListParams, private val response: StepListPageResponse, -) { +) : PageAsync { /** * Delegates to [StepListPageResponse], but gracefully handles missing data. @@ -33,22 +35,16 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): StepListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): CompletableFuture> = - getNextPageParams() - .map { service.list(it).thenApply { Optional.of(it) } } - .orElseGet { CompletableFuture.completedFuture(Optional.empty()) } + override fun nextPage(): CompletableFuture = service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPagerAsync = AutoPagerAsync.from(this, streamHandlerExecutor) /** The parameters that were used to request this page. */ fun params(): StepListParams = params @@ -66,6 +62,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -77,18 +74,24 @@ private constructor( class Builder internal constructor() { private var service: StepServiceAsync? = null + private var streamHandlerExecutor: Executor? = null private var params: StepListParams? = null private var response: StepListPageResponse? = null @JvmSynthetic internal fun from(stepListPageAsync: StepListPageAsync) = apply { service = stepListPageAsync.service + streamHandlerExecutor = stepListPageAsync.streamHandlerExecutor params = stepListPageAsync.params response = stepListPageAsync.response } fun service(service: StepServiceAsync) = apply { this.service = service } + fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply { + this.streamHandlerExecutor = streamHandlerExecutor + } + /** The parameters that were used to request this page. */ fun params(params: StepListParams) = apply { this.params = params } @@ -103,6 +106,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -112,47 +116,22 @@ private constructor( fun build(): StepListPageAsync = StepListPageAsync( checkRequired("service", service), + checkRequired("streamHandlerExecutor", streamHandlerExecutor), checkRequired("params", params), checkRequired("response", response), ) } - class AutoPager(private val firstPage: StepListPageAsync) { - - fun forEach(action: Predicate, executor: Executor): CompletableFuture { - fun CompletableFuture>.forEach( - action: (RunStep) -> Boolean, - executor: Executor, - ): CompletableFuture = - thenComposeAsync( - { page -> - page - .filter { it.data().all(action) } - .map { it.getNextPage().forEach(action, executor) } - .orElseGet { CompletableFuture.completedFuture(null) } - }, - executor, - ) - return CompletableFuture.completedFuture(Optional.of(firstPage)) - .forEach(action::test, executor) - } - - fun toList(executor: Executor): CompletableFuture> { - val values = mutableListOf() - return forEach(values::add, executor).thenApply { values } - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return /* spotless:off */ other is StepListPageAsync && service == other.service && params == other.params && response == other.response /* spotless:on */ + return /* spotless:off */ other is StepListPageAsync && service == other.service && streamHandlerExecutor == other.streamHandlerExecutor && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, params, response) /* spotless:on */ + override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, streamHandlerExecutor, params, response) /* spotless:on */ override fun toString() = - "StepListPageAsync{service=$service, params=$params, response=$response}" + "StepListPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, response=$response}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/steps/StepListParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/steps/StepListParams.kt index ca18dea9..c88cb3ef 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/steps/StepListParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/steps/StepListParams.kt @@ -19,7 +19,7 @@ import kotlin.jvm.optionals.getOrNull class StepListParams private constructor( private val threadId: String, - private val runId: String, + private val runId: String?, private val after: String?, private val before: String?, private val include: List?, @@ -31,7 +31,7 @@ private constructor( fun threadId(): String = threadId - fun runId(): String = runId + fun runId(): Optional = Optional.ofNullable(runId) /** * A cursor for use in pagination. `after` is an object ID that defines your place in the list. @@ -84,7 +84,6 @@ private constructor( * The following fields are required: * ```java * .threadId() - * .runId() * ``` */ @JvmStatic fun builder() = Builder() @@ -118,7 +117,10 @@ private constructor( fun threadId(threadId: String) = apply { this.threadId = threadId } - fun runId(runId: String) = apply { this.runId = runId } + fun runId(runId: String?) = apply { this.runId = runId } + + /** Alias for calling [Builder.runId] with `runId.orElse(null)`. */ + fun runId(runId: Optional) = runId(runId.getOrNull()) /** * A cursor for use in pagination. `after` is an object ID that defines your place in the @@ -298,7 +300,6 @@ private constructor( * The following fields are required: * ```java * .threadId() - * .runId() * ``` * * @throws IllegalStateException if any required field is unset. @@ -306,7 +307,7 @@ private constructor( fun build(): StepListParams = StepListParams( checkRequired("threadId", threadId), - checkRequired("runId", runId), + runId, after, before, include?.toImmutable(), @@ -320,7 +321,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { 0 -> threadId - 1 -> runId + 1 -> runId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/steps/StepRetrieveParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/steps/StepRetrieveParams.kt index 15275de5..c42a51a5 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/steps/StepRetrieveParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/threads/runs/steps/StepRetrieveParams.kt @@ -16,7 +16,7 @@ class StepRetrieveParams private constructor( private val threadId: String, private val runId: String, - private val stepId: String, + private val stepId: String?, private val include: List?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, @@ -26,7 +26,7 @@ private constructor( fun runId(): String = runId - fun stepId(): String = stepId + fun stepId(): Optional = Optional.ofNullable(stepId) /** * A list of additional fields to include in the response. Currently the only supported value is @@ -54,7 +54,6 @@ private constructor( * ```java * .threadId() * .runId() - * .stepId() * ``` */ @JvmStatic fun builder() = Builder() @@ -84,7 +83,10 @@ private constructor( fun runId(runId: String) = apply { this.runId = runId } - fun stepId(stepId: String) = apply { this.stepId = stepId } + fun stepId(stepId: String?) = apply { this.stepId = stepId } + + /** Alias for calling [Builder.stepId] with `stepId.orElse(null)`. */ + fun stepId(stepId: Optional) = stepId(stepId.getOrNull()) /** * A list of additional fields to include in the response. Currently the only supported @@ -218,7 +220,6 @@ private constructor( * ```java * .threadId() * .runId() - * .stepId() * ``` * * @throws IllegalStateException if any required field is unset. @@ -227,7 +228,7 @@ private constructor( StepRetrieveParams( checkRequired("threadId", threadId), checkRequired("runId", runId), - checkRequired("stepId", stepId), + stepId, include?.toImmutable(), additionalHeaders.build(), additionalQueryParams.build(), @@ -238,7 +239,7 @@ private constructor( when (index) { 0 -> threadId 1 -> runId - 2 -> stepId + 2 -> stepId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/ChatCompletionDeleteParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/ChatCompletionDeleteParams.kt index 0cd4d7fa..64f6792e 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/ChatCompletionDeleteParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/ChatCompletionDeleteParams.kt @@ -4,12 +4,12 @@ package com.openai.models.chat.completions import com.openai.core.JsonValue import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import com.openai.core.toImmutable import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** * Delete a stored chat completion. Only Chat Completions that have been created with the `store` @@ -17,13 +17,13 @@ import java.util.Optional */ class ChatCompletionDeleteParams private constructor( - private val completionId: String, + private val completionId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, ) : Params { - fun completionId(): String = completionId + fun completionId(): Optional = Optional.ofNullable(completionId) fun _additionalBodyProperties(): Map = additionalBodyProperties @@ -35,13 +35,10 @@ private constructor( companion object { + @JvmStatic fun none(): ChatCompletionDeleteParams = builder().build() + /** * Returns a mutable builder for constructing an instance of [ChatCompletionDeleteParams]. - * - * The following fields are required: - * ```java - * .completionId() - * ``` */ @JvmStatic fun builder() = Builder() } @@ -63,7 +60,10 @@ private constructor( chatCompletionDeleteParams.additionalBodyProperties.toMutableMap() } - fun completionId(completionId: String) = apply { this.completionId = completionId } + fun completionId(completionId: String?) = apply { this.completionId = completionId } + + /** Alias for calling [Builder.completionId] with `completionId.orElse(null)`. */ + fun completionId(completionId: Optional) = completionId(completionId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -189,17 +189,10 @@ private constructor( * Returns an immutable instance of [ChatCompletionDeleteParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .completionId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): ChatCompletionDeleteParams = ChatCompletionDeleteParams( - checkRequired("completionId", completionId), + completionId, additionalHeaders.build(), additionalQueryParams.build(), additionalBodyProperties.toImmutable(), @@ -211,7 +204,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> completionId + 0 -> completionId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/ChatCompletionListPage.kt b/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/ChatCompletionListPage.kt index 6c807633..a0c72474 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/ChatCompletionListPage.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/ChatCompletionListPage.kt @@ -2,12 +2,12 @@ package com.openai.models.chat.completions +import com.openai.core.AutoPager +import com.openai.core.Page import com.openai.core.checkRequired import com.openai.services.blocking.chat.ChatCompletionService import java.util.Objects import java.util.Optional -import java.util.stream.Stream -import java.util.stream.StreamSupport import kotlin.jvm.optionals.getOrNull /** @see [ChatCompletionService.list] */ @@ -16,7 +16,7 @@ private constructor( private val service: ChatCompletionService, private val params: ChatCompletionListParams, private val response: ChatCompletionListPageResponse, -) { +) : Page { /** * Delegates to [ChatCompletionListPageResponse], but gracefully handles missing data. @@ -33,20 +33,16 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): ChatCompletionListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): Optional = - getNextPageParams().map { service.list(it) } + override fun nextPage(): ChatCompletionListPage = service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPager = AutoPager.from(this) /** The parameters that were used to request this page. */ fun params(): ChatCompletionListParams = params @@ -115,25 +111,6 @@ private constructor( ) } - class AutoPager(private val firstPage: ChatCompletionListPage) : Iterable { - - override fun iterator(): Iterator = iterator { - var page = firstPage - var index = 0 - while (true) { - while (index < page.data().size) { - yield(page.data()[index++]) - } - page = page.getNextPage().getOrNull() ?: break - index = 0 - } - } - - fun stream(): Stream { - return StreamSupport.stream(spliterator(), false) - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/ChatCompletionListPageAsync.kt b/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/ChatCompletionListPageAsync.kt index 87bef9ed..ebd91537 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/ChatCompletionListPageAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/ChatCompletionListPageAsync.kt @@ -2,22 +2,24 @@ package com.openai.models.chat.completions +import com.openai.core.AutoPagerAsync +import com.openai.core.PageAsync import com.openai.core.checkRequired import com.openai.services.async.chat.ChatCompletionServiceAsync import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor -import java.util.function.Predicate import kotlin.jvm.optionals.getOrNull /** @see [ChatCompletionServiceAsync.list] */ class ChatCompletionListPageAsync private constructor( private val service: ChatCompletionServiceAsync, + private val streamHandlerExecutor: Executor, private val params: ChatCompletionListParams, private val response: ChatCompletionListPageResponse, -) { +) : PageAsync { /** * Delegates to [ChatCompletionListPageResponse], but gracefully handles missing data. @@ -34,22 +36,18 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): ChatCompletionListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): CompletableFuture> = - getNextPageParams() - .map { service.list(it).thenApply { Optional.of(it) } } - .orElseGet { CompletableFuture.completedFuture(Optional.empty()) } + override fun nextPage(): CompletableFuture = + service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPagerAsync = + AutoPagerAsync.from(this, streamHandlerExecutor) /** The parameters that were used to request this page. */ fun params(): ChatCompletionListParams = params @@ -67,6 +65,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -78,18 +77,24 @@ private constructor( class Builder internal constructor() { private var service: ChatCompletionServiceAsync? = null + private var streamHandlerExecutor: Executor? = null private var params: ChatCompletionListParams? = null private var response: ChatCompletionListPageResponse? = null @JvmSynthetic internal fun from(chatCompletionListPageAsync: ChatCompletionListPageAsync) = apply { service = chatCompletionListPageAsync.service + streamHandlerExecutor = chatCompletionListPageAsync.streamHandlerExecutor params = chatCompletionListPageAsync.params response = chatCompletionListPageAsync.response } fun service(service: ChatCompletionServiceAsync) = apply { this.service = service } + fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply { + this.streamHandlerExecutor = streamHandlerExecutor + } + /** The parameters that were used to request this page. */ fun params(params: ChatCompletionListParams) = apply { this.params = params } @@ -104,6 +109,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -113,50 +119,22 @@ private constructor( fun build(): ChatCompletionListPageAsync = ChatCompletionListPageAsync( checkRequired("service", service), + checkRequired("streamHandlerExecutor", streamHandlerExecutor), checkRequired("params", params), checkRequired("response", response), ) } - class AutoPager(private val firstPage: ChatCompletionListPageAsync) { - - fun forEach( - action: Predicate, - executor: Executor, - ): CompletableFuture { - fun CompletableFuture>.forEach( - action: (ChatCompletion) -> Boolean, - executor: Executor, - ): CompletableFuture = - thenComposeAsync( - { page -> - page - .filter { it.data().all(action) } - .map { it.getNextPage().forEach(action, executor) } - .orElseGet { CompletableFuture.completedFuture(null) } - }, - executor, - ) - return CompletableFuture.completedFuture(Optional.of(firstPage)) - .forEach(action::test, executor) - } - - fun toList(executor: Executor): CompletableFuture> { - val values = mutableListOf() - return forEach(values::add, executor).thenApply { values } - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return /* spotless:off */ other is ChatCompletionListPageAsync && service == other.service && params == other.params && response == other.response /* spotless:on */ + return /* spotless:off */ other is ChatCompletionListPageAsync && service == other.service && streamHandlerExecutor == other.streamHandlerExecutor && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, params, response) /* spotless:on */ + override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, streamHandlerExecutor, params, response) /* spotless:on */ override fun toString() = - "ChatCompletionListPageAsync{service=$service, params=$params, response=$response}" + "ChatCompletionListPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, response=$response}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/ChatCompletionRetrieveParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/ChatCompletionRetrieveParams.kt index adf67c89..5254f338 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/ChatCompletionRetrieveParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/ChatCompletionRetrieveParams.kt @@ -3,10 +3,11 @@ package com.openai.models.chat.completions import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** * Get a stored chat completion. Only Chat Completions that have been created with the `store` @@ -14,12 +15,12 @@ import java.util.Objects */ class ChatCompletionRetrieveParams private constructor( - private val completionId: String, + private val completionId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun completionId(): String = completionId + fun completionId(): Optional = Optional.ofNullable(completionId) fun _additionalHeaders(): Headers = additionalHeaders @@ -29,13 +30,10 @@ private constructor( companion object { + @JvmStatic fun none(): ChatCompletionRetrieveParams = builder().build() + /** * Returns a mutable builder for constructing an instance of [ChatCompletionRetrieveParams]. - * - * The following fields are required: - * ```java - * .completionId() - * ``` */ @JvmStatic fun builder() = Builder() } @@ -54,7 +52,10 @@ private constructor( additionalQueryParams = chatCompletionRetrieveParams.additionalQueryParams.toBuilder() } - fun completionId(completionId: String) = apply { this.completionId = completionId } + fun completionId(completionId: String?) = apply { this.completionId = completionId } + + /** Alias for calling [Builder.completionId] with `completionId.orElse(null)`. */ + fun completionId(completionId: Optional) = completionId(completionId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -158,17 +159,10 @@ private constructor( * Returns an immutable instance of [ChatCompletionRetrieveParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .completionId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): ChatCompletionRetrieveParams = ChatCompletionRetrieveParams( - checkRequired("completionId", completionId), + completionId, additionalHeaders.build(), additionalQueryParams.build(), ) @@ -176,7 +170,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> completionId + 0 -> completionId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/ChatCompletionUpdateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/ChatCompletionUpdateParams.kt index 95329885..6468e4e7 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/ChatCompletionUpdateParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/ChatCompletionUpdateParams.kt @@ -28,13 +28,13 @@ import kotlin.jvm.optionals.getOrNull */ class ChatCompletionUpdateParams private constructor( - private val completionId: String, + private val completionId: String?, private val body: Body, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun completionId(): String = completionId + fun completionId(): Optional = Optional.ofNullable(completionId) /** * Set of 16 key-value pairs that can be attached to an object. This can be useful for storing @@ -71,7 +71,6 @@ private constructor( * * The following fields are required: * ```java - * .completionId() * .metadata() * ``` */ @@ -94,7 +93,10 @@ private constructor( additionalQueryParams = chatCompletionUpdateParams.additionalQueryParams.toBuilder() } - fun completionId(completionId: String) = apply { this.completionId = completionId } + fun completionId(completionId: String?) = apply { this.completionId = completionId } + + /** Alias for calling [Builder.completionId] with `completionId.orElse(null)`. */ + fun completionId(completionId: Optional) = completionId(completionId.getOrNull()) /** * Sets the entire request body. @@ -251,7 +253,6 @@ private constructor( * * The following fields are required: * ```java - * .completionId() * .metadata() * ``` * @@ -259,7 +260,7 @@ private constructor( */ fun build(): ChatCompletionUpdateParams = ChatCompletionUpdateParams( - checkRequired("completionId", completionId), + completionId, body.build(), additionalHeaders.build(), additionalQueryParams.build(), @@ -270,7 +271,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> completionId + 0 -> completionId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/messages/MessageListPage.kt b/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/messages/MessageListPage.kt index 4088b3ef..bc6f6aa6 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/messages/MessageListPage.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/messages/MessageListPage.kt @@ -2,13 +2,13 @@ package com.openai.models.chat.completions.messages +import com.openai.core.AutoPager +import com.openai.core.Page import com.openai.core.checkRequired import com.openai.models.chat.completions.ChatCompletionStoreMessage import com.openai.services.blocking.chat.completions.MessageService import java.util.Objects import java.util.Optional -import java.util.stream.Stream -import java.util.stream.StreamSupport import kotlin.jvm.optionals.getOrNull /** @see [MessageService.list] */ @@ -17,7 +17,7 @@ private constructor( private val service: MessageService, private val params: MessageListParams, private val response: MessageListPageResponse, -) { +) : Page { /** * Delegates to [MessageListPageResponse], but gracefully handles missing data. @@ -34,19 +34,16 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): MessageListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): Optional = getNextPageParams().map { service.list(it) } + override fun nextPage(): MessageListPage = service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPager = AutoPager.from(this) /** The parameters that were used to request this page. */ fun params(): MessageListParams = params @@ -115,25 +112,6 @@ private constructor( ) } - class AutoPager(private val firstPage: MessageListPage) : Iterable { - - override fun iterator(): Iterator = iterator { - var page = firstPage - var index = 0 - while (true) { - while (index < page.data().size) { - yield(page.data()[index++]) - } - page = page.getNextPage().getOrNull() ?: break - index = 0 - } - } - - fun stream(): Stream { - return StreamSupport.stream(spliterator(), false) - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/messages/MessageListPageAsync.kt b/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/messages/MessageListPageAsync.kt index d013eff2..7baa95a6 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/messages/MessageListPageAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/messages/MessageListPageAsync.kt @@ -2,6 +2,8 @@ package com.openai.models.chat.completions.messages +import com.openai.core.AutoPagerAsync +import com.openai.core.PageAsync import com.openai.core.checkRequired import com.openai.models.chat.completions.ChatCompletionStoreMessage import com.openai.services.async.chat.completions.MessageServiceAsync @@ -9,16 +11,16 @@ import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor -import java.util.function.Predicate import kotlin.jvm.optionals.getOrNull /** @see [MessageServiceAsync.list] */ class MessageListPageAsync private constructor( private val service: MessageServiceAsync, + private val streamHandlerExecutor: Executor, private val params: MessageListParams, private val response: MessageListPageResponse, -) { +) : PageAsync { /** * Delegates to [MessageListPageResponse], but gracefully handles missing data. @@ -35,22 +37,18 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): MessageListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): CompletableFuture> = - getNextPageParams() - .map { service.list(it).thenApply { Optional.of(it) } } - .orElseGet { CompletableFuture.completedFuture(Optional.empty()) } + override fun nextPage(): CompletableFuture = + service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPagerAsync = + AutoPagerAsync.from(this, streamHandlerExecutor) /** The parameters that were used to request this page. */ fun params(): MessageListParams = params @@ -68,6 +66,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -79,18 +78,24 @@ private constructor( class Builder internal constructor() { private var service: MessageServiceAsync? = null + private var streamHandlerExecutor: Executor? = null private var params: MessageListParams? = null private var response: MessageListPageResponse? = null @JvmSynthetic internal fun from(messageListPageAsync: MessageListPageAsync) = apply { service = messageListPageAsync.service + streamHandlerExecutor = messageListPageAsync.streamHandlerExecutor params = messageListPageAsync.params response = messageListPageAsync.response } fun service(service: MessageServiceAsync) = apply { this.service = service } + fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply { + this.streamHandlerExecutor = streamHandlerExecutor + } + /** The parameters that were used to request this page. */ fun params(params: MessageListParams) = apply { this.params = params } @@ -105,6 +110,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -114,50 +120,22 @@ private constructor( fun build(): MessageListPageAsync = MessageListPageAsync( checkRequired("service", service), + checkRequired("streamHandlerExecutor", streamHandlerExecutor), checkRequired("params", params), checkRequired("response", response), ) } - class AutoPager(private val firstPage: MessageListPageAsync) { - - fun forEach( - action: Predicate, - executor: Executor, - ): CompletableFuture { - fun CompletableFuture>.forEach( - action: (ChatCompletionStoreMessage) -> Boolean, - executor: Executor, - ): CompletableFuture = - thenComposeAsync( - { page -> - page - .filter { it.data().all(action) } - .map { it.getNextPage().forEach(action, executor) } - .orElseGet { CompletableFuture.completedFuture(null) } - }, - executor, - ) - return CompletableFuture.completedFuture(Optional.of(firstPage)) - .forEach(action::test, executor) - } - - fun toList(executor: Executor): CompletableFuture> { - val values = mutableListOf() - return forEach(values::add, executor).thenApply { values } - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return /* spotless:off */ other is MessageListPageAsync && service == other.service && params == other.params && response == other.response /* spotless:on */ + return /* spotless:off */ other is MessageListPageAsync && service == other.service && streamHandlerExecutor == other.streamHandlerExecutor && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, params, response) /* spotless:on */ + override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, streamHandlerExecutor, params, response) /* spotless:on */ override fun toString() = - "MessageListPageAsync{service=$service, params=$params, response=$response}" + "MessageListPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, response=$response}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/messages/MessageListParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/messages/MessageListParams.kt index 0f7c3f25..a60bc6d6 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/messages/MessageListParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/messages/MessageListParams.kt @@ -6,7 +6,6 @@ import com.fasterxml.jackson.annotation.JsonCreator import com.openai.core.Enum import com.openai.core.JsonField import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import com.openai.errors.OpenAIInvalidDataException @@ -20,7 +19,7 @@ import kotlin.jvm.optionals.getOrNull */ class MessageListParams private constructor( - private val completionId: String, + private val completionId: String?, private val after: String?, private val limit: Long?, private val order: Order?, @@ -28,7 +27,7 @@ private constructor( private val additionalQueryParams: QueryParams, ) : Params { - fun completionId(): String = completionId + fun completionId(): Optional = Optional.ofNullable(completionId) /** Identifier for the last message from the previous pagination request. */ fun after(): Optional = Optional.ofNullable(after) @@ -50,14 +49,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [MessageListParams]. - * - * The following fields are required: - * ```java - * .completionId() - * ``` - */ + @JvmStatic fun none(): MessageListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [MessageListParams]. */ @JvmStatic fun builder() = Builder() } @@ -81,7 +75,10 @@ private constructor( additionalQueryParams = messageListParams.additionalQueryParams.toBuilder() } - fun completionId(completionId: String) = apply { this.completionId = completionId } + fun completionId(completionId: String?) = apply { this.completionId = completionId } + + /** Alias for calling [Builder.completionId] with `completionId.orElse(null)`. */ + fun completionId(completionId: Optional) = completionId(completionId.getOrNull()) /** Identifier for the last message from the previous pagination request. */ fun after(after: String?) = apply { this.after = after } @@ -213,17 +210,10 @@ private constructor( * Returns an immutable instance of [MessageListParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .completionId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): MessageListParams = MessageListParams( - checkRequired("completionId", completionId), + completionId, after, limit, order, @@ -234,7 +224,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> completionId + 0 -> completionId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalCreateParams.kt index 08525daa..34c28627 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalCreateParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalCreateParams.kt @@ -29,6 +29,10 @@ import com.openai.core.http.Headers import com.openai.core.http.QueryParams import com.openai.core.toImmutable import com.openai.errors.OpenAIInvalidDataException +import com.openai.models.graders.gradermodels.PythonGrader +import com.openai.models.graders.gradermodels.ScoreModelGrader +import com.openai.models.graders.gradermodels.StringCheckGrader +import com.openai.models.graders.gradermodels.TextSimilarityGrader import com.openai.models.responses.ResponseInputText import java.util.Collections import java.util.Objects @@ -196,8 +200,13 @@ private constructor( body.customDataSourceConfig(itemSchema) } - /** Alias for calling [dataSourceConfig] with `DataSourceConfig.ofLogs(logs)`. */ - fun dataSourceConfig(logs: DataSourceConfig.Logs) = apply { body.dataSourceConfig(logs) } + /** + * Alias for calling [dataSourceConfig] with + * `DataSourceConfig.ofStoredCompletions(storedCompletions)`. + */ + fun dataSourceConfig(storedCompletions: DataSourceConfig.StoredCompletions) = apply { + body.dataSourceConfig(storedCompletions) + } /** A list of graders for all eval runs in this group. */ fun testingCriteria(testingCriteria: List) = apply { @@ -235,7 +244,7 @@ private constructor( * Alias for calling [addTestingCriterion] with * `TestingCriterion.ofStringCheck(stringCheck)`. */ - fun addTestingCriterion(stringCheck: EvalStringCheckGrader) = apply { + fun addTestingCriterion(stringCheck: StringCheckGrader) = apply { body.addTestingCriterion(stringCheck) } @@ -243,7 +252,7 @@ private constructor( * Alias for calling [addTestingCriterion] with * `TestingCriterion.ofTextSimilarity(textSimilarity)`. */ - fun addTestingCriterion(textSimilarity: EvalTextSimilarityGrader) = apply { + fun addTestingCriterion(textSimilarity: TestingCriterion.TextSimilarity) = apply { body.addTestingCriterion(textSimilarity) } @@ -602,9 +611,12 @@ private constructor( fun customDataSourceConfig(itemSchema: DataSourceConfig.Custom.ItemSchema) = dataSourceConfig(DataSourceConfig.Custom.builder().itemSchema(itemSchema).build()) - /** Alias for calling [dataSourceConfig] with `DataSourceConfig.ofLogs(logs)`. */ - fun dataSourceConfig(logs: DataSourceConfig.Logs) = - dataSourceConfig(DataSourceConfig.ofLogs(logs)) + /** + * Alias for calling [dataSourceConfig] with + * `DataSourceConfig.ofStoredCompletions(storedCompletions)`. + */ + fun dataSourceConfig(storedCompletions: DataSourceConfig.StoredCompletions) = + dataSourceConfig(DataSourceConfig.ofStoredCompletions(storedCompletions)) /** A list of graders for all eval runs in this group. */ fun testingCriteria(testingCriteria: List) = @@ -644,14 +656,14 @@ private constructor( * Alias for calling [addTestingCriterion] with * `TestingCriterion.ofStringCheck(stringCheck)`. */ - fun addTestingCriterion(stringCheck: EvalStringCheckGrader) = + fun addTestingCriterion(stringCheck: StringCheckGrader) = addTestingCriterion(TestingCriterion.ofStringCheck(stringCheck)) /** * Alias for calling [addTestingCriterion] with * `TestingCriterion.ofTextSimilarity(textSimilarity)`. */ - fun addTestingCriterion(textSimilarity: EvalTextSimilarityGrader) = + fun addTestingCriterion(textSimilarity: TestingCriterion.TextSimilarity) = addTestingCriterion(TestingCriterion.ofTextSimilarity(textSimilarity)) /** Alias for calling [addTestingCriterion] with `TestingCriterion.ofPython(python)`. */ @@ -800,7 +812,7 @@ private constructor( class DataSourceConfig private constructor( private val custom: Custom? = null, - private val logs: Logs? = null, + private val storedCompletions: StoredCompletions? = null, private val _json: JsonValue? = null, ) { @@ -816,11 +828,12 @@ private constructor( * A data source config which specifies the metadata property of your stored completions * query. This is usually metadata like `usecase=chatbot` or `prompt-version=v2`, etc. */ - fun logs(): Optional = Optional.ofNullable(logs) + fun storedCompletions(): Optional = + Optional.ofNullable(storedCompletions) fun isCustom(): Boolean = custom != null - fun isLogs(): Boolean = logs != null + fun isStoredCompletions(): Boolean = storedCompletions != null /** * A CustomDataSourceConfig object that defines the schema for the data source used for the @@ -834,14 +847,15 @@ private constructor( * A data source config which specifies the metadata property of your stored completions * query. This is usually metadata like `usecase=chatbot` or `prompt-version=v2`, etc. */ - fun asLogs(): Logs = logs.getOrThrow("logs") + fun asStoredCompletions(): StoredCompletions = + storedCompletions.getOrThrow("storedCompletions") fun _json(): Optional = Optional.ofNullable(_json) fun accept(visitor: Visitor): T = when { custom != null -> visitor.visitCustom(custom) - logs != null -> visitor.visitLogs(logs) + storedCompletions != null -> visitor.visitStoredCompletions(storedCompletions) else -> visitor.unknown(_json) } @@ -858,8 +872,8 @@ private constructor( custom.validate() } - override fun visitLogs(logs: Logs) { - logs.validate() + override fun visitStoredCompletions(storedCompletions: StoredCompletions) { + storedCompletions.validate() } } ) @@ -886,7 +900,8 @@ private constructor( object : Visitor { override fun visitCustom(custom: Custom) = custom.validity() - override fun visitLogs(logs: Logs) = logs.validity() + override fun visitStoredCompletions(storedCompletions: StoredCompletions) = + storedCompletions.validity() override fun unknown(json: JsonValue?) = 0 } @@ -897,15 +912,16 @@ private constructor( return true } - return /* spotless:off */ other is DataSourceConfig && custom == other.custom && logs == other.logs /* spotless:on */ + return /* spotless:off */ other is DataSourceConfig && custom == other.custom && storedCompletions == other.storedCompletions /* spotless:on */ } - override fun hashCode(): Int = /* spotless:off */ Objects.hash(custom, logs) /* spotless:on */ + override fun hashCode(): Int = /* spotless:off */ Objects.hash(custom, storedCompletions) /* spotless:on */ override fun toString(): String = when { custom != null -> "DataSourceConfig{custom=$custom}" - logs != null -> "DataSourceConfig{logs=$logs}" + storedCompletions != null -> + "DataSourceConfig{storedCompletions=$storedCompletions}" _json != null -> "DataSourceConfig{_unknown=$_json}" else -> throw IllegalStateException("Invalid DataSourceConfig") } @@ -925,7 +941,9 @@ private constructor( * A data source config which specifies the metadata property of your stored completions * query. This is usually metadata like `usecase=chatbot` or `prompt-version=v2`, etc. */ - @JvmStatic fun ofLogs(logs: Logs) = DataSourceConfig(logs = logs) + @JvmStatic + fun ofStoredCompletions(storedCompletions: StoredCompletions) = + DataSourceConfig(storedCompletions = storedCompletions) } /** @@ -947,7 +965,7 @@ private constructor( * A data source config which specifies the metadata property of your stored completions * query. This is usually metadata like `usecase=chatbot` or `prompt-version=v2`, etc. */ - fun visitLogs(logs: Logs): T + fun visitStoredCompletions(storedCompletions: StoredCompletions): T /** * Maps an unknown variant of [DataSourceConfig] to a value of type [T]. @@ -976,9 +994,9 @@ private constructor( DataSourceConfig(custom = it, _json = json) } ?: DataSourceConfig(_json = json) } - "logs" -> { - return tryDeserialize(node, jacksonTypeRef())?.let { - DataSourceConfig(logs = it, _json = json) + "stored_completions" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + DataSourceConfig(storedCompletions = it, _json = json) } ?: DataSourceConfig(_json = json) } } @@ -996,7 +1014,8 @@ private constructor( ) { when { value.custom != null -> generator.writeObject(value.custom) - value.logs != null -> generator.writeObject(value.logs) + value.storedCompletions != null -> + generator.writeObject(value.storedCompletions) value._json != null -> generator.writeObject(value._json) else -> throw IllegalStateException("Invalid DataSourceConfig") } @@ -1376,7 +1395,7 @@ private constructor( * A data source config which specifies the metadata property of your stored completions * query. This is usually metadata like `usecase=chatbot` or `prompt-version=v2`, etc. */ - class Logs + class StoredCompletions private constructor( private val type: JsonValue, private val metadata: JsonField, @@ -1392,11 +1411,11 @@ private constructor( ) : this(type, metadata, mutableMapOf()) /** - * The type of data source. Always `logs`. + * The type of data source. Always `stored_completions`. * * Expected to always return the following: * ```java - * JsonValue.from("logs") + * JsonValue.from("stored_completions") * ``` * * However, this method can be useful for debugging and logging (e.g. if the server @@ -1405,7 +1424,7 @@ private constructor( @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type /** - * Metadata filters for the logs data source. + * Metadata filters for the stored completions data source. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). @@ -1436,22 +1455,24 @@ private constructor( companion object { - /** Returns a mutable builder for constructing an instance of [Logs]. */ + /** + * Returns a mutable builder for constructing an instance of [StoredCompletions]. + */ @JvmStatic fun builder() = Builder() } - /** A builder for [Logs]. */ + /** A builder for [StoredCompletions]. */ class Builder internal constructor() { - private var type: JsonValue = JsonValue.from("logs") + private var type: JsonValue = JsonValue.from("stored_completions") private var metadata: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(logs: Logs) = apply { - type = logs.type - metadata = logs.metadata - additionalProperties = logs.additionalProperties.toMutableMap() + internal fun from(storedCompletions: StoredCompletions) = apply { + type = storedCompletions.type + metadata = storedCompletions.metadata + additionalProperties = storedCompletions.additionalProperties.toMutableMap() } /** @@ -1460,7 +1481,7 @@ private constructor( * It is usually unnecessary to call this method because the field defaults to the * following: * ```java - * JsonValue.from("logs") + * JsonValue.from("stored_completions") * ``` * * This method is primarily for setting the field to an undocumented or not yet @@ -1468,7 +1489,7 @@ private constructor( */ fun type(type: JsonValue) = apply { this.type = type } - /** Metadata filters for the logs data source. */ + /** Metadata filters for the stored completions data source. */ fun metadata(metadata: Metadata) = metadata(JsonField.of(metadata)) /** @@ -1503,22 +1524,23 @@ private constructor( } /** - * Returns an immutable instance of [Logs]. + * Returns an immutable instance of [StoredCompletions]. * * Further updates to this [Builder] will not mutate the returned instance. */ - fun build(): Logs = Logs(type, metadata, additionalProperties.toMutableMap()) + fun build(): StoredCompletions = + StoredCompletions(type, metadata, additionalProperties.toMutableMap()) } private var validated: Boolean = false - fun validate(): Logs = apply { + fun validate(): StoredCompletions = apply { if (validated) { return@apply } _type().let { - if (it != JsonValue.from("logs")) { + if (it != JsonValue.from("stored_completions")) { throw OpenAIInvalidDataException("'type' is invalid, received $it") } } @@ -1542,10 +1564,10 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - type.let { if (it == JsonValue.from("logs")) 1 else 0 } + + type.let { if (it == JsonValue.from("stored_completions")) 1 else 0 } + (metadata.asKnown().getOrNull()?.validity() ?: 0) - /** Metadata filters for the logs data source. */ + /** Metadata filters for the stored completions data source. */ class Metadata @JsonCreator private constructor( @@ -1657,7 +1679,7 @@ private constructor( return true } - return /* spotless:off */ other is Logs && type == other.type && metadata == other.metadata && additionalProperties == other.additionalProperties /* spotless:on */ + return /* spotless:off */ other is StoredCompletions && type == other.type && metadata == other.metadata && additionalProperties == other.additionalProperties /* spotless:on */ } /* spotless:off */ @@ -1667,7 +1689,7 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "Logs{type=$type, metadata=$metadata, additionalProperties=$additionalProperties}" + "StoredCompletions{type=$type, metadata=$metadata, additionalProperties=$additionalProperties}" } } @@ -1679,8 +1701,8 @@ private constructor( class TestingCriterion private constructor( private val labelModel: LabelModel? = null, - private val stringCheck: EvalStringCheckGrader? = null, - private val textSimilarity: EvalTextSimilarityGrader? = null, + private val stringCheck: StringCheckGrader? = null, + private val textSimilarity: TextSimilarity? = null, private val python: Python? = null, private val scoreModel: ScoreModel? = null, private val _json: JsonValue? = null, @@ -1696,11 +1718,10 @@ private constructor( * A StringCheckGrader object that performs a string comparison between input and reference * using a specified operation. */ - fun stringCheck(): Optional = Optional.ofNullable(stringCheck) + fun stringCheck(): Optional = Optional.ofNullable(stringCheck) /** A TextSimilarityGrader object which grades text based on similarity metrics. */ - fun textSimilarity(): Optional = - Optional.ofNullable(textSimilarity) + fun textSimilarity(): Optional = Optional.ofNullable(textSimilarity) /** A PythonGrader object that runs a python script on the input. */ fun python(): Optional = Optional.ofNullable(python) @@ -1728,11 +1749,10 @@ private constructor( * A StringCheckGrader object that performs a string comparison between input and reference * using a specified operation. */ - fun asStringCheck(): EvalStringCheckGrader = stringCheck.getOrThrow("stringCheck") + fun asStringCheck(): StringCheckGrader = stringCheck.getOrThrow("stringCheck") /** A TextSimilarityGrader object which grades text based on similarity metrics. */ - fun asTextSimilarity(): EvalTextSimilarityGrader = - textSimilarity.getOrThrow("textSimilarity") + fun asTextSimilarity(): TextSimilarity = textSimilarity.getOrThrow("textSimilarity") /** A PythonGrader object that runs a python script on the input. */ fun asPython(): Python = python.getOrThrow("python") @@ -1765,11 +1785,11 @@ private constructor( labelModel.validate() } - override fun visitStringCheck(stringCheck: EvalStringCheckGrader) { + override fun visitStringCheck(stringCheck: StringCheckGrader) { stringCheck.validate() } - override fun visitTextSimilarity(textSimilarity: EvalTextSimilarityGrader) { + override fun visitTextSimilarity(textSimilarity: TextSimilarity) { textSimilarity.validate() } @@ -1805,10 +1825,10 @@ private constructor( object : Visitor { override fun visitLabelModel(labelModel: LabelModel) = labelModel.validity() - override fun visitStringCheck(stringCheck: EvalStringCheckGrader) = + override fun visitStringCheck(stringCheck: StringCheckGrader) = stringCheck.validity() - override fun visitTextSimilarity(textSimilarity: EvalTextSimilarityGrader) = + override fun visitTextSimilarity(textSimilarity: TextSimilarity) = textSimilarity.validity() override fun visitPython(python: Python) = python.validity() @@ -1854,12 +1874,12 @@ private constructor( * reference using a specified operation. */ @JvmStatic - fun ofStringCheck(stringCheck: EvalStringCheckGrader) = + fun ofStringCheck(stringCheck: StringCheckGrader) = TestingCriterion(stringCheck = stringCheck) /** A TextSimilarityGrader object which grades text based on similarity metrics. */ @JvmStatic - fun ofTextSimilarity(textSimilarity: EvalTextSimilarityGrader) = + fun ofTextSimilarity(textSimilarity: TextSimilarity) = TestingCriterion(textSimilarity = textSimilarity) /** A PythonGrader object that runs a python script on the input. */ @@ -1886,10 +1906,10 @@ private constructor( * A StringCheckGrader object that performs a string comparison between input and * reference using a specified operation. */ - fun visitStringCheck(stringCheck: EvalStringCheckGrader): T + fun visitStringCheck(stringCheck: StringCheckGrader): T /** A TextSimilarityGrader object which grades text based on similarity metrics. */ - fun visitTextSimilarity(textSimilarity: EvalTextSimilarityGrader): T + fun visitTextSimilarity(textSimilarity: TextSimilarity): T /** A PythonGrader object that runs a python script on the input. */ fun visitPython(python: Python): T @@ -1925,14 +1945,14 @@ private constructor( } ?: TestingCriterion(_json = json) } "string_check" -> { - return tryDeserialize(node, jacksonTypeRef())?.let { + return tryDeserialize(node, jacksonTypeRef())?.let { TestingCriterion(stringCheck = it, _json = json) } ?: TestingCriterion(_json = json) } "text_similarity" -> { - return tryDeserialize(node, jacksonTypeRef()) - ?.let { TestingCriterion(textSimilarity = it, _json = json) } - ?: TestingCriterion(_json = json) + return tryDeserialize(node, jacksonTypeRef())?.let { + TestingCriterion(textSimilarity = it, _json = json) + } ?: TestingCriterion(_json = json) } "python" -> { return tryDeserialize(node, jacksonTypeRef())?.let { @@ -3819,31 +3839,63 @@ private constructor( "LabelModel{input=$input, labels=$labels, model=$model, name=$name, passingLabels=$passingLabels, type=$type, additionalProperties=$additionalProperties}" } - /** A PythonGrader object that runs a python script on the input. */ - class Python + /** A TextSimilarityGrader object which grades text based on similarity metrics. */ + class TextSimilarity private constructor( + private val evaluationMetric: JsonField, + private val input: JsonField, private val name: JsonField, - private val source: JsonField, + private val reference: JsonField, private val type: JsonValue, - private val imageTag: JsonField, private val passThreshold: JsonField, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( + @JsonProperty("evaluation_metric") + @ExcludeMissing + evaluationMetric: JsonField = + JsonMissing.of(), + @JsonProperty("input") @ExcludeMissing input: JsonField = JsonMissing.of(), @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), - @JsonProperty("source") + @JsonProperty("reference") @ExcludeMissing - source: JsonField = JsonMissing.of(), + reference: JsonField = JsonMissing.of(), @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), - @JsonProperty("image_tag") - @ExcludeMissing - imageTag: JsonField = JsonMissing.of(), @JsonProperty("pass_threshold") @ExcludeMissing passThreshold: JsonField = JsonMissing.of(), - ) : this(name, source, type, imageTag, passThreshold, mutableMapOf()) + ) : this(evaluationMetric, input, name, reference, type, passThreshold, mutableMapOf()) + + fun toTextSimilarityGrader(): TextSimilarityGrader = + TextSimilarityGrader.builder() + .evaluationMetric(evaluationMetric) + .input(input) + .name(name) + .reference(reference) + .type(type) + .build() + + /** + * The evaluation metric to use. One of `fuzzy_match`, `bleu`, `gleu`, `meteor`, + * `rouge_1`, `rouge_2`, `rouge_3`, `rouge_4`, `rouge_5`, or `rouge_l`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun evaluationMetric(): TextSimilarityGrader.EvaluationMetric = + evaluationMetric.getRequired("evaluation_metric") + + /** + * The text being graded. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun input(): String = input.getRequired("input") /** * The name of the grader. @@ -3855,20 +3907,20 @@ private constructor( fun name(): String = name.getRequired("name") /** - * The source code of the python script. + * The text being graded against. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected * value). */ - fun source(): String = source.getRequired("source") + fun reference(): String = reference.getRequired("reference") /** - * The object type, which is always `python`. + * The type of grader. * * Expected to always return the following: * ```java - * JsonValue.from("python") + * JsonValue.from("text_similarity") * ``` * * However, this method can be useful for debugging and logging (e.g. if the server @@ -3877,42 +3929,48 @@ private constructor( @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type /** - * The image tag to use for the python script. + * The threshold for the score. * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). */ - fun imageTag(): Optional = imageTag.getOptional("image_tag") + fun passThreshold(): Double = passThreshold.getRequired("pass_threshold") /** - * The threshold for the score. + * Returns the raw JSON value of [evaluationMetric]. * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). + * Unlike [evaluationMetric], this method doesn't throw if the JSON field has an + * unexpected type. */ - fun passThreshold(): Optional = passThreshold.getOptional("pass_threshold") + @JsonProperty("evaluation_metric") + @ExcludeMissing + fun _evaluationMetric(): JsonField = + evaluationMetric /** - * Returns the raw JSON value of [name]. + * Returns the raw JSON value of [input]. * - * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [input], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + @JsonProperty("input") @ExcludeMissing fun _input(): JsonField = input /** - * Returns the raw JSON value of [source]. + * Returns the raw JSON value of [name]. * - * Unlike [source], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("source") @ExcludeMissing fun _source(): JsonField = source + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name /** - * Returns the raw JSON value of [imageTag]. + * Returns the raw JSON value of [reference]. * - * Unlike [imageTag], this method doesn't throw if the JSON field has an unexpected + * Unlike [reference], this method doesn't throw if the JSON field has an unexpected * type. */ - @JsonProperty("image_tag") @ExcludeMissing fun _imageTag(): JsonField = imageTag + @JsonProperty("reference") + @ExcludeMissing + fun _reference(): JsonField = reference /** * Returns the raw JSON value of [passThreshold]. @@ -3939,37 +3997,73 @@ private constructor( companion object { /** - * Returns a mutable builder for constructing an instance of [Python]. + * Returns a mutable builder for constructing an instance of [TextSimilarity]. * * The following fields are required: * ```java + * .evaluationMetric() + * .input() * .name() - * .source() + * .reference() + * .passThreshold() * ``` */ @JvmStatic fun builder() = Builder() } - /** A builder for [Python]. */ + /** A builder for [TextSimilarity]. */ class Builder internal constructor() { + private var evaluationMetric: JsonField? = + null + private var input: JsonField? = null private var name: JsonField? = null - private var source: JsonField? = null - private var type: JsonValue = JsonValue.from("python") - private var imageTag: JsonField = JsonMissing.of() - private var passThreshold: JsonField = JsonMissing.of() + private var reference: JsonField? = null + private var type: JsonValue = JsonValue.from("text_similarity") + private var passThreshold: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(python: Python) = apply { - name = python.name - source = python.source - type = python.type - imageTag = python.imageTag - passThreshold = python.passThreshold - additionalProperties = python.additionalProperties.toMutableMap() + internal fun from(textSimilarity: TextSimilarity) = apply { + evaluationMetric = textSimilarity.evaluationMetric + input = textSimilarity.input + name = textSimilarity.name + reference = textSimilarity.reference + type = textSimilarity.type + passThreshold = textSimilarity.passThreshold + additionalProperties = textSimilarity.additionalProperties.toMutableMap() } + /** + * The evaluation metric to use. One of `fuzzy_match`, `bleu`, `gleu`, `meteor`, + * `rouge_1`, `rouge_2`, `rouge_3`, `rouge_4`, `rouge_5`, or `rouge_l`. + */ + fun evaluationMetric(evaluationMetric: TextSimilarityGrader.EvaluationMetric) = + evaluationMetric(JsonField.of(evaluationMetric)) + + /** + * Sets [Builder.evaluationMetric] to an arbitrary JSON value. + * + * You should usually call [Builder.evaluationMetric] with a well-typed + * [TextSimilarityGrader.EvaluationMetric] value instead. This method is primarily + * for setting the field to an undocumented or not yet supported value. + */ + fun evaluationMetric( + evaluationMetric: JsonField + ) = apply { this.evaluationMetric = evaluationMetric } + + /** The text being graded. */ + fun input(input: String) = input(JsonField.of(input)) + + /** + * Sets [Builder.input] to an arbitrary JSON value. + * + * You should usually call [Builder.input] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun input(input: JsonField) = apply { this.input = input } + /** The name of the grader. */ fun name(name: String) = name(JsonField.of(name)) @@ -3982,17 +4076,17 @@ private constructor( */ fun name(name: JsonField) = apply { this.name = name } - /** The source code of the python script. */ - fun source(source: String) = source(JsonField.of(source)) + /** The text being graded against. */ + fun reference(reference: String) = reference(JsonField.of(reference)) /** - * Sets [Builder.source] to an arbitrary JSON value. + * Sets [Builder.reference] to an arbitrary JSON value. * - * You should usually call [Builder.source] with a well-typed [String] value + * You should usually call [Builder.reference] with a well-typed [String] value * instead. This method is primarily for setting the field to an undocumented or not * yet supported value. */ - fun source(source: JsonField) = apply { this.source = source } + fun reference(reference: JsonField) = apply { this.reference = reference } /** * Sets the field to an arbitrary JSON value. @@ -4000,7 +4094,7 @@ private constructor( * It is usually unnecessary to call this method because the field defaults to the * following: * ```java - * JsonValue.from("python") + * JsonValue.from("text_similarity") * ``` * * This method is primarily for setting the field to an undocumented or not yet @@ -4008,18 +4102,6 @@ private constructor( */ fun type(type: JsonValue) = apply { this.type = type } - /** The image tag to use for the python script. */ - fun imageTag(imageTag: String) = imageTag(JsonField.of(imageTag)) - - /** - * Sets [Builder.imageTag] to an arbitrary JSON value. - * - * You should usually call [Builder.imageTag] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun imageTag(imageTag: JsonField) = apply { this.imageTag = imageTag } - /** The threshold for the score. */ fun passThreshold(passThreshold: Double) = passThreshold(JsonField.of(passThreshold)) @@ -4058,44 +4140,49 @@ private constructor( } /** - * Returns an immutable instance of [Python]. + * Returns an immutable instance of [TextSimilarity]. * * Further updates to this [Builder] will not mutate the returned instance. * * The following fields are required: * ```java + * .evaluationMetric() + * .input() * .name() - * .source() + * .reference() + * .passThreshold() * ``` * * @throws IllegalStateException if any required field is unset. */ - fun build(): Python = - Python( + fun build(): TextSimilarity = + TextSimilarity( + checkRequired("evaluationMetric", evaluationMetric), + checkRequired("input", input), checkRequired("name", name), - checkRequired("source", source), + checkRequired("reference", reference), type, - imageTag, - passThreshold, + checkRequired("passThreshold", passThreshold), additionalProperties.toMutableMap(), ) } private var validated: Boolean = false - fun validate(): Python = apply { + fun validate(): TextSimilarity = apply { if (validated) { return@apply } + evaluationMetric().validate() + input() name() - source() + reference() _type().let { - if (it != JsonValue.from("python")) { + if (it != JsonValue.from("text_similarity")) { throw OpenAIInvalidDataException("'type' is invalid, received $it") } } - imageTag() passThreshold() validated = true } @@ -4116,10 +4203,11 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (if (name.asKnown().isPresent) 1 else 0) + - (if (source.asKnown().isPresent) 1 else 0) + - type.let { if (it == JsonValue.from("python")) 1 else 0 } + - (if (imageTag.asKnown().isPresent) 1 else 0) + + (evaluationMetric.asKnown().getOrNull()?.validity() ?: 0) + + (if (input.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (if (reference.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("text_similarity")) 1 else 0 } + (if (passThreshold.asKnown().isPresent) 1 else 0) override fun equals(other: Any?): Boolean { @@ -4127,84 +4215,77 @@ private constructor( return true } - return /* spotless:off */ other is Python && name == other.name && source == other.source && type == other.type && imageTag == other.imageTag && passThreshold == other.passThreshold && additionalProperties == other.additionalProperties /* spotless:on */ + return /* spotless:off */ other is TextSimilarity && evaluationMetric == other.evaluationMetric && input == other.input && name == other.name && reference == other.reference && type == other.type && passThreshold == other.passThreshold && additionalProperties == other.additionalProperties /* spotless:on */ } /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(name, source, type, imageTag, passThreshold, additionalProperties) } + private val hashCode: Int by lazy { Objects.hash(evaluationMetric, input, name, reference, type, passThreshold, additionalProperties) } /* spotless:on */ override fun hashCode(): Int = hashCode override fun toString() = - "Python{name=$name, source=$source, type=$type, imageTag=$imageTag, passThreshold=$passThreshold, additionalProperties=$additionalProperties}" + "TextSimilarity{evaluationMetric=$evaluationMetric, input=$input, name=$name, reference=$reference, type=$type, passThreshold=$passThreshold, additionalProperties=$additionalProperties}" } - /** A ScoreModelGrader object that uses a model to assign a score to the input. */ - class ScoreModel + /** A PythonGrader object that runs a python script on the input. */ + class Python private constructor( - private val input: JsonField>, - private val model: JsonField, private val name: JsonField, + private val source: JsonField, private val type: JsonValue, + private val imageTag: JsonField, private val passThreshold: JsonField, - private val range: JsonField>, - private val samplingParams: JsonValue, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( - @JsonProperty("input") - @ExcludeMissing - input: JsonField> = JsonMissing.of(), - @JsonProperty("model") @ExcludeMissing model: JsonField = JsonMissing.of(), @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("source") + @ExcludeMissing + source: JsonField = JsonMissing.of(), @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + @JsonProperty("image_tag") + @ExcludeMissing + imageTag: JsonField = JsonMissing.of(), @JsonProperty("pass_threshold") @ExcludeMissing passThreshold: JsonField = JsonMissing.of(), - @JsonProperty("range") - @ExcludeMissing - range: JsonField> = JsonMissing.of(), - @JsonProperty("sampling_params") - @ExcludeMissing - samplingParams: JsonValue = JsonMissing.of(), - ) : this(input, model, name, type, passThreshold, range, samplingParams, mutableMapOf()) + ) : this(name, source, type, imageTag, passThreshold, mutableMapOf()) - /** - * The input text. This may include template strings. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected - * value). - */ - fun input(): List = input.getRequired("input") + fun toPythonGrader(): PythonGrader = + PythonGrader.builder() + .name(name) + .source(source) + .type(type) + .imageTag(imageTag) + .build() /** - * The model to use for the evaluation. + * The name of the grader. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected * value). */ - fun model(): String = model.getRequired("model") + fun name(): String = name.getRequired("name") /** - * The name of the grader. + * The source code of the python script. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected * value). */ - fun name(): String = name.getRequired("name") + fun source(): String = source.getRequired("source") /** - * The object type, which is always `score_model`. + * The object type, which is always `python`. * * Expected to always return the following: * ```java - * JsonValue.from("score_model") + * JsonValue.from("python") * ``` * * However, this method can be useful for debugging and logging (e.g. if the server @@ -4213,46 +4294,42 @@ private constructor( @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type /** - * The threshold for the score. + * The image tag to use for the python script. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). */ - fun passThreshold(): Optional = passThreshold.getOptional("pass_threshold") + fun imageTag(): Optional = imageTag.getOptional("image_tag") /** - * The range of the score. Defaults to `[0, 1]`. + * The threshold for the score. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). */ - fun range(): Optional> = range.getOptional("range") - - /** The sampling parameters for the model. */ - @JsonProperty("sampling_params") - @ExcludeMissing - fun _samplingParams(): JsonValue = samplingParams + fun passThreshold(): Optional = passThreshold.getOptional("pass_threshold") /** - * Returns the raw JSON value of [input]. + * Returns the raw JSON value of [name]. * - * Unlike [input], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("input") @ExcludeMissing fun _input(): JsonField> = input + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name /** - * Returns the raw JSON value of [model]. + * Returns the raw JSON value of [source]. * - * Unlike [model], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [source], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("model") @ExcludeMissing fun _model(): JsonField = model + @JsonProperty("source") @ExcludeMissing fun _source(): JsonField = source /** - * Returns the raw JSON value of [name]. + * Returns the raw JSON value of [imageTag]. * - * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [imageTag], this method doesn't throw if the JSON field has an unexpected + * type. */ - @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + @JsonProperty("image_tag") @ExcludeMissing fun _imageTag(): JsonField = imageTag /** * Returns the raw JSON value of [passThreshold]. @@ -4264,13 +4341,6 @@ private constructor( @ExcludeMissing fun _passThreshold(): JsonField = passThreshold - /** - * Returns the raw JSON value of [range]. - * - * Unlike [range], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("range") @ExcludeMissing fun _range(): JsonField> = range - @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { additionalProperties.put(key, value) @@ -4286,80 +4356,37 @@ private constructor( companion object { /** - * Returns a mutable builder for constructing an instance of [ScoreModel]. + * Returns a mutable builder for constructing an instance of [Python]. * * The following fields are required: * ```java - * .input() - * .model() * .name() + * .source() * ``` */ @JvmStatic fun builder() = Builder() } - /** A builder for [ScoreModel]. */ + /** A builder for [Python]. */ class Builder internal constructor() { - private var input: JsonField>? = null - private var model: JsonField? = null private var name: JsonField? = null - private var type: JsonValue = JsonValue.from("score_model") + private var source: JsonField? = null + private var type: JsonValue = JsonValue.from("python") + private var imageTag: JsonField = JsonMissing.of() private var passThreshold: JsonField = JsonMissing.of() - private var range: JsonField>? = null - private var samplingParams: JsonValue = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(scoreModel: ScoreModel) = apply { - input = scoreModel.input.map { it.toMutableList() } - model = scoreModel.model - name = scoreModel.name - type = scoreModel.type - passThreshold = scoreModel.passThreshold - range = scoreModel.range.map { it.toMutableList() } - samplingParams = scoreModel.samplingParams - additionalProperties = scoreModel.additionalProperties.toMutableMap() + internal fun from(python: Python) = apply { + name = python.name + source = python.source + type = python.type + imageTag = python.imageTag + passThreshold = python.passThreshold + additionalProperties = python.additionalProperties.toMutableMap() } - /** The input text. This may include template strings. */ - fun input(input: List) = input(JsonField.of(input)) - - /** - * Sets [Builder.input] to an arbitrary JSON value. - * - * You should usually call [Builder.input] with a well-typed `List` value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun input(input: JsonField>) = apply { - this.input = input.map { it.toMutableList() } - } - - /** - * Adds a single [Input] to [Builder.input]. - * - * @throws IllegalStateException if the field was previously set to a non-list. - */ - fun addInput(input: Input) = apply { - this.input = - (this.input ?: JsonField.of(mutableListOf())).also { - checkKnown("input", it).add(input) - } - } - - /** The model to use for the evaluation. */ - 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) = apply { this.model = model } - /** The name of the grader. */ fun name(name: String) = name(JsonField.of(name)) @@ -4372,13 +4399,25 @@ private constructor( */ fun name(name: JsonField) = apply { this.name = name } + /** The source code of the python script. */ + fun source(source: String) = source(JsonField.of(source)) + + /** + * Sets [Builder.source] to an arbitrary JSON value. + * + * You should usually call [Builder.source] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun source(source: JsonField) = apply { this.source = source } + /** * Sets the field to an arbitrary JSON value. * * It is usually unnecessary to call this method because the field defaults to the * following: * ```java - * JsonValue.from("score_model") + * JsonValue.from("python") * ``` * * This method is primarily for setting the field to an undocumented or not yet @@ -4386,50 +4425,31 @@ private constructor( */ fun type(type: JsonValue) = apply { this.type = type } - /** The threshold for the score. */ - fun passThreshold(passThreshold: Double) = - passThreshold(JsonField.of(passThreshold)) + /** The image tag to use for the python script. */ + fun imageTag(imageTag: String) = imageTag(JsonField.of(imageTag)) /** - * Sets [Builder.passThreshold] to an arbitrary JSON value. + * Sets [Builder.imageTag] to an arbitrary JSON value. * - * You should usually call [Builder.passThreshold] with a well-typed [Double] value + * You should usually call [Builder.imageTag] with a well-typed [String] value * instead. This method is primarily for setting the field to an undocumented or not * yet supported value. */ - fun passThreshold(passThreshold: JsonField) = apply { - this.passThreshold = passThreshold - } + fun imageTag(imageTag: JsonField) = apply { this.imageTag = imageTag } - /** The range of the score. Defaults to `[0, 1]`. */ - fun range(range: List) = range(JsonField.of(range)) + /** The threshold for the score. */ + fun passThreshold(passThreshold: Double) = + passThreshold(JsonField.of(passThreshold)) /** - * Sets [Builder.range] to an arbitrary JSON value. + * Sets [Builder.passThreshold] to an arbitrary JSON value. * - * You should usually call [Builder.range] with a well-typed `List` value + * You should usually call [Builder.passThreshold] with a well-typed [Double] value * instead. This method is primarily for setting the field to an undocumented or not * yet supported value. */ - fun range(range: JsonField>) = apply { - this.range = range.map { it.toMutableList() } - } - - /** - * Adds a single [Double] to [Builder.range]. - * - * @throws IllegalStateException if the field was previously set to a non-list. - */ - fun addRange(range: Double) = apply { - this.range = - (this.range ?: JsonField.of(mutableListOf())).also { - checkKnown("range", it).add(range) - } - } - - /** The sampling parameters for the model. */ - fun samplingParams(samplingParams: JsonValue) = apply { - this.samplingParams = samplingParams + fun passThreshold(passThreshold: JsonField) = apply { + this.passThreshold = passThreshold } fun additionalProperties(additionalProperties: Map) = apply { @@ -4455,49 +4475,45 @@ private constructor( } /** - * Returns an immutable instance of [ScoreModel]. + * Returns an immutable instance of [Python]. * * Further updates to this [Builder] will not mutate the returned instance. * * The following fields are required: * ```java - * .input() - * .model() * .name() + * .source() * ``` * * @throws IllegalStateException if any required field is unset. */ - fun build(): ScoreModel = - ScoreModel( - checkRequired("input", input).map { it.toImmutable() }, - checkRequired("model", model), + fun build(): Python = + Python( checkRequired("name", name), + checkRequired("source", source), type, + imageTag, passThreshold, - (range ?: JsonMissing.of()).map { it.toImmutable() }, - samplingParams, additionalProperties.toMutableMap(), ) } private var validated: Boolean = false - fun validate(): ScoreModel = apply { + fun validate(): Python = apply { if (validated) { return@apply } - input().forEach { it.validate() } - model() name() + source() _type().let { - if (it != JsonValue.from("score_model")) { + if (it != JsonValue.from("python")) { throw OpenAIInvalidDataException("'type' is invalid, received $it") } } + imageTag() passThreshold() - range() validated = true } @@ -4517,1007 +4533,442 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (input.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + - (if (model.asKnown().isPresent) 1 else 0) + - (if (name.asKnown().isPresent) 1 else 0) + - type.let { if (it == JsonValue.from("score_model")) 1 else 0 } + - (if (passThreshold.asKnown().isPresent) 1 else 0) + - (range.asKnown().getOrNull()?.size ?: 0) - - /** - * A message input to the model with a role indicating instruction following hierarchy. - * Instructions given with the `developer` or `system` role take precedence over - * instructions given with the `user` role. Messages with the `assistant` role are - * presumed to have been generated by the model in previous interactions. - */ - class Input - private constructor( - private val content: JsonField, - private val role: JsonField, - private val type: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("content") - @ExcludeMissing - content: JsonField = JsonMissing.of(), - @JsonProperty("role") @ExcludeMissing role: JsonField = JsonMissing.of(), - @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), - ) : this(content, role, type, mutableMapOf()) - - /** - * Text inputs to the model - can contain template strings. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected - * value). - */ - fun content(): Content = content.getRequired("content") + (if (name.asKnown().isPresent) 1 else 0) + + (if (source.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("python")) 1 else 0 } + + (if (imageTag.asKnown().isPresent) 1 else 0) + + (if (passThreshold.asKnown().isPresent) 1 else 0) - /** - * The role of the message input. One of `user`, `assistant`, `system`, or - * `developer`. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected - * value). - */ - fun role(): Role = role.getRequired("role") + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - /** - * The type of the message input. Always `message`. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun type(): Optional = type.getOptional("type") + return /* spotless:off */ other is Python && name == other.name && source == other.source && type == other.type && imageTag == other.imageTag && passThreshold == other.passThreshold && additionalProperties == other.additionalProperties /* spotless:on */ + } - /** - * Returns the raw JSON value of [content]. - * - * Unlike [content], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("content") - @ExcludeMissing - fun _content(): JsonField = content + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, source, type, imageTag, passThreshold, additionalProperties) } + /* spotless:on */ - /** - * Returns the raw JSON value of [role]. - * - * Unlike [role], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("role") @ExcludeMissing fun _role(): JsonField = role + override fun hashCode(): Int = hashCode - /** - * Returns the raw JSON value of [type]. - * - * Unlike [type], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + override fun toString() = + "Python{name=$name, source=$source, type=$type, imageTag=$imageTag, passThreshold=$passThreshold, additionalProperties=$additionalProperties}" + } - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } + /** A ScoreModelGrader object that uses a model to assign a score to the input. */ + class ScoreModel + private constructor( + private val input: JsonField>, + private val model: JsonField, + private val name: JsonField, + private val type: JsonValue, + private val range: JsonField>, + private val samplingParams: JsonValue, + private val passThreshold: JsonField, + private val additionalProperties: MutableMap, + ) { - @JsonAnyGetter + @JsonCreator + private constructor( + @JsonProperty("input") + @ExcludeMissing + input: JsonField> = JsonMissing.of(), + @JsonProperty("model") @ExcludeMissing model: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + @JsonProperty("range") + @ExcludeMissing + range: JsonField> = JsonMissing.of(), + @JsonProperty("sampling_params") + @ExcludeMissing + samplingParams: JsonValue = JsonMissing.of(), + @JsonProperty("pass_threshold") @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) + passThreshold: JsonField = JsonMissing.of(), + ) : this(input, model, name, type, range, samplingParams, passThreshold, mutableMapOf()) + + fun toScoreModelGrader(): ScoreModelGrader = + ScoreModelGrader.builder() + .input(input) + .model(model) + .name(name) + .type(type) + .range(range) + .samplingParams(samplingParams) + .build() - fun toBuilder() = Builder().from(this) + /** + * The input text. This may include template strings. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun input(): List = input.getRequired("input") - companion object { + /** + * The model to use for the evaluation. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun model(): String = model.getRequired("model") - /** - * Returns a mutable builder for constructing an instance of [Input]. - * - * The following fields are required: - * ```java - * .content() - * .role() - * ``` - */ - @JvmStatic fun builder() = Builder() - } + /** + * The name of the grader. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun name(): String = name.getRequired("name") - /** A builder for [Input]. */ - class Builder internal constructor() { + /** + * The object type, which is always `score_model`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("score_model") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type - private var content: JsonField? = null - private var role: JsonField? = null - private var type: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() + /** + * The range of the score. Defaults to `[0, 1]`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun range(): Optional> = range.getOptional("range") - @JvmSynthetic - internal fun from(input: Input) = apply { - content = input.content - role = input.role - type = input.type - additionalProperties = input.additionalProperties.toMutableMap() - } + /** The sampling parameters for the model. */ + @JsonProperty("sampling_params") + @ExcludeMissing + fun _samplingParams(): JsonValue = samplingParams - /** Text inputs to the model - can contain template strings. */ - fun content(content: Content) = content(JsonField.of(content)) - - /** - * Sets [Builder.content] to an arbitrary JSON value. - * - * You should usually call [Builder.content] with a well-typed [Content] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun content(content: JsonField) = apply { this.content = content } + /** + * The threshold for the score. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun passThreshold(): Optional = passThreshold.getOptional("pass_threshold") - /** Alias for calling [content] with `Content.ofTextInput(textInput)`. */ - fun content(textInput: String) = content(Content.ofTextInput(textInput)) + /** + * Returns the raw JSON value of [input]. + * + * Unlike [input], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("input") + @ExcludeMissing + fun _input(): JsonField> = input - /** - * Alias for calling [content] with - * `Content.ofResponseInputText(responseInputText)`. - */ - fun content(responseInputText: ResponseInputText) = - content(Content.ofResponseInputText(responseInputText)) + /** + * 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 = model - /** Alias for calling [content] with `Content.ofOutputText(outputText)`. */ - fun content(outputText: Content.OutputText) = - content(Content.ofOutputText(outputText)) + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name - /** - * The role of the message input. One of `user`, `assistant`, `system`, or - * `developer`. - */ - fun role(role: Role) = role(JsonField.of(role)) + /** + * Returns the raw JSON value of [range]. + * + * Unlike [range], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("range") @ExcludeMissing fun _range(): JsonField> = range - /** - * Sets [Builder.role] to an arbitrary JSON value. - * - * You should usually call [Builder.role] with a well-typed [Role] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun role(role: JsonField) = apply { this.role = role } + /** + * Returns the raw JSON value of [passThreshold]. + * + * Unlike [passThreshold], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("pass_threshold") + @ExcludeMissing + fun _passThreshold(): JsonField = passThreshold - /** The type of the message input. Always `message`. */ - fun type(type: Type) = type(JsonField.of(type)) + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } - /** - * Sets [Builder.type] to an arbitrary JSON value. - * - * You should usually call [Builder.type] with a well-typed [Type] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun type(type: JsonField) = apply { this.type = type } + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } + fun toBuilder() = Builder().from(this) - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } + companion object { - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } + /** + * Returns a mutable builder for constructing an instance of [ScoreModel]. + * + * The following fields are required: + * ```java + * .input() + * .model() + * .name() + * ``` + */ + @JvmStatic fun builder() = Builder() + } - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } + /** A builder for [ScoreModel]. */ + class Builder internal constructor() { - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } + private var input: JsonField>? = null + private var model: JsonField? = null + private var name: JsonField? = null + private var type: JsonValue = JsonValue.from("score_model") + private var range: JsonField>? = null + private var samplingParams: JsonValue = JsonMissing.of() + private var passThreshold: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() - /** - * Returns an immutable instance of [Input]. - * - * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .content() - * .role() - * ``` - * - * @throws IllegalStateException if any required field is unset. - */ - fun build(): Input = - Input( - checkRequired("content", content), - checkRequired("role", role), - type, - additionalProperties.toMutableMap(), - ) + @JvmSynthetic + internal fun from(scoreModel: ScoreModel) = apply { + input = scoreModel.input.map { it.toMutableList() } + model = scoreModel.model + name = scoreModel.name + type = scoreModel.type + range = scoreModel.range.map { it.toMutableList() } + samplingParams = scoreModel.samplingParams + passThreshold = scoreModel.passThreshold + additionalProperties = scoreModel.additionalProperties.toMutableMap() } - private var validated: Boolean = false - - fun validate(): Input = apply { - if (validated) { - return@apply - } + /** The input text. This may include template strings. */ + fun input(input: List) = input(JsonField.of(input)) - content().validate() - role().validate() - type().ifPresent { it.validate() } - validated = true + /** + * Sets [Builder.input] to an arbitrary JSON value. + * + * You should usually call [Builder.input] with a well-typed + * `List` value instead. This method is primarily for + * setting the field to an undocumented or not yet supported value. + */ + fun input(input: JsonField>) = apply { + this.input = input.map { it.toMutableList() } } - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. + * Adds a single [ScoreModelGrader.Input] to [Builder.input]. * - * Used for best match union deserialization. + * @throws IllegalStateException if the field was previously set to a non-list. */ - @JvmSynthetic - internal fun validity(): Int = - (content.asKnown().getOrNull()?.validity() ?: 0) + - (role.asKnown().getOrNull()?.validity() ?: 0) + - (type.asKnown().getOrNull()?.validity() ?: 0) - - /** Text inputs to the model - can contain template strings. */ - @JsonDeserialize(using = Content.Deserializer::class) - @JsonSerialize(using = Content.Serializer::class) - class Content - private constructor( - private val textInput: String? = null, - private val responseInputText: ResponseInputText? = null, - private val outputText: OutputText? = null, - private val _json: JsonValue? = null, - ) { + fun addInput(input: ScoreModelGrader.Input) = apply { + this.input = + (this.input ?: JsonField.of(mutableListOf())).also { + checkKnown("input", it).add(input) + } + } - /** A text input to the model. */ - fun textInput(): Optional = Optional.ofNullable(textInput) + /** The model to use for the evaluation. */ + fun model(model: String) = model(JsonField.of(model)) - /** A text input to the model. */ - fun responseInputText(): Optional = - Optional.ofNullable(responseInputText) + /** + * 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) = apply { this.model = model } - /** A text output from the model. */ - fun outputText(): Optional = Optional.ofNullable(outputText) + /** The name of the grader. */ + fun name(name: String) = name(JsonField.of(name)) - fun isTextInput(): Boolean = textInput != null + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun name(name: JsonField) = apply { this.name = name } - fun isResponseInputText(): Boolean = responseInputText != null + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("score_model") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonValue) = apply { this.type = type } - fun isOutputText(): Boolean = outputText != null + /** The range of the score. Defaults to `[0, 1]`. */ + fun range(range: List) = range(JsonField.of(range)) - /** A text input to the model. */ - fun asTextInput(): String = textInput.getOrThrow("textInput") + /** + * Sets [Builder.range] to an arbitrary JSON value. + * + * You should usually call [Builder.range] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun range(range: JsonField>) = apply { + this.range = range.map { it.toMutableList() } + } - /** A text input to the model. */ - fun asResponseInputText(): ResponseInputText = - responseInputText.getOrThrow("responseInputText") + /** + * Adds a single [Double] to [Builder.range]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addRange(range: Double) = apply { + this.range = + (this.range ?: JsonField.of(mutableListOf())).also { + checkKnown("range", it).add(range) + } + } - /** A text output from the model. */ - fun asOutputText(): OutputText = outputText.getOrThrow("outputText") + /** The sampling parameters for the model. */ + fun samplingParams(samplingParams: JsonValue) = apply { + this.samplingParams = samplingParams + } - fun _json(): Optional = Optional.ofNullable(_json) + /** The threshold for the score. */ + fun passThreshold(passThreshold: Double) = + passThreshold(JsonField.of(passThreshold)) - fun accept(visitor: Visitor): T = - when { - textInput != null -> visitor.visitTextInput(textInput) - responseInputText != null -> - visitor.visitResponseInputText(responseInputText) - outputText != null -> visitor.visitOutputText(outputText) - else -> visitor.unknown(_json) - } + /** + * Sets [Builder.passThreshold] to an arbitrary JSON value. + * + * You should usually call [Builder.passThreshold] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun passThreshold(passThreshold: JsonField) = apply { + this.passThreshold = passThreshold + } - private var validated: Boolean = false + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } - fun validate(): Content = apply { - if (validated) { - return@apply - } + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } - accept( - object : Visitor { - override fun visitTextInput(textInput: String) {} + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } - override fun visitResponseInputText( - responseInputText: ResponseInputText - ) { - responseInputText.validate() - } + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } - override fun visitOutputText(outputText: OutputText) { - outputText.validate() - } - } - ) - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - accept( - object : Visitor { - override fun visitTextInput(textInput: String) = 1 - - override fun visitResponseInputText( - responseInputText: ResponseInputText - ) = responseInputText.validity() - - override fun visitOutputText(outputText: OutputText) = - outputText.validity() - - override fun unknown(json: JsonValue?) = 0 - } - ) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is Content && textInput == other.textInput && responseInputText == other.responseInputText && outputText == other.outputText /* spotless:on */ - } - - override fun hashCode(): Int = /* spotless:off */ Objects.hash(textInput, responseInputText, outputText) /* spotless:on */ - - override fun toString(): String = - when { - textInput != null -> "Content{textInput=$textInput}" - responseInputText != null -> - "Content{responseInputText=$responseInputText}" - outputText != null -> "Content{outputText=$outputText}" - _json != null -> "Content{_unknown=$_json}" - else -> throw IllegalStateException("Invalid Content") - } - - companion object { - - /** A text input to the model. */ - @JvmStatic - fun ofTextInput(textInput: String) = Content(textInput = textInput) - - /** A text input to the model. */ - @JvmStatic - fun ofResponseInputText(responseInputText: ResponseInputText) = - Content(responseInputText = responseInputText) - - /** A text output from the model. */ - @JvmStatic - fun ofOutputText(outputText: OutputText) = Content(outputText = outputText) - } - - /** - * An interface that defines how to map each variant of [Content] to a value of - * type [T]. - */ - interface Visitor { - - /** A text input to the model. */ - fun visitTextInput(textInput: String): T - - /** A text input to the model. */ - fun visitResponseInputText(responseInputText: ResponseInputText): T - - /** A text output from the model. */ - fun visitOutputText(outputText: OutputText): T - - /** - * Maps an unknown variant of [Content] to a value of type [T]. - * - * An instance of [Content] can contain an unknown variant if it was - * deserialized from data that doesn't match any known variant. For example, - * if the SDK is on an older version than the API, then the API may respond - * with new variants that the SDK is unaware of. - * - * @throws OpenAIInvalidDataException in the default implementation. - */ - fun unknown(json: JsonValue?): T { - throw OpenAIInvalidDataException("Unknown Content: $json") - } - } - - internal class Deserializer : BaseDeserializer(Content::class) { - - override fun ObjectCodec.deserialize(node: JsonNode): Content { - val json = JsonValue.fromJsonNode(node) - - val bestMatches = - sequenceOf( - tryDeserialize(node, jacksonTypeRef()) - ?.let { Content(responseInputText = it, _json = json) }, - tryDeserialize(node, jacksonTypeRef())?.let { - Content(outputText = it, _json = json) - }, - tryDeserialize(node, jacksonTypeRef())?.let { - Content(textInput = it, _json = json) - }, - ) - .filterNotNull() - .allMaxBy { it.validity() } - .toList() - return when (bestMatches.size) { - // This can happen if what we're deserializing is completely - // incompatible with all the possible variants (e.g. deserializing - // from array). - 0 -> Content(_json = json) - 1 -> bestMatches.single() - // If there's more than one match with the highest validity, then - // use the first completely valid match, or simply the first match - // if none are completely valid. - else -> - bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() - } - } - } - - internal class Serializer : BaseSerializer(Content::class) { - - override fun serialize( - value: Content, - generator: JsonGenerator, - provider: SerializerProvider, - ) { - when { - value.textInput != null -> generator.writeObject(value.textInput) - value.responseInputText != null -> - generator.writeObject(value.responseInputText) - value.outputText != null -> generator.writeObject(value.outputText) - value._json != null -> generator.writeObject(value._json) - else -> throw IllegalStateException("Invalid Content") - } - } - } - - /** A text output from the model. */ - class OutputText - private constructor( - private val text: JsonField, - private val type: JsonValue, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("text") - @ExcludeMissing - text: JsonField = JsonMissing.of(), - @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), - ) : this(text, type, mutableMapOf()) - - /** - * The text output from the model. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected - * type or is unexpectedly missing or null (e.g. if the server responded - * with an unexpected value). - */ - fun text(): String = text.getRequired("text") - - /** - * The type of the output text. Always `output_text`. - * - * Expected to always return the following: - * ```java - * JsonValue.from("output_text") - * ``` - * - * However, this method can be useful for debugging and logging (e.g. if the - * server responded with an unexpected value). - */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type - - /** - * Returns the raw JSON value of [text]. - * - * Unlike [text], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("text") @ExcludeMissing fun _text(): JsonField = text - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** - * Returns a mutable builder for constructing an instance of - * [OutputText]. - * - * The following fields are required: - * ```java - * .text() - * ``` - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [OutputText]. */ - class Builder internal constructor() { - - private var text: JsonField? = null - private var type: JsonValue = JsonValue.from("output_text") - private var additionalProperties: MutableMap = - mutableMapOf() - - @JvmSynthetic - internal fun from(outputText: OutputText) = apply { - text = outputText.text - type = outputText.type - additionalProperties = - outputText.additionalProperties.toMutableMap() - } - - /** The text output from the model. */ - fun text(text: String) = text(JsonField.of(text)) - - /** - * Sets [Builder.text] to an arbitrary JSON value. - * - * You should usually call [Builder.text] with a well-typed [String] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun text(text: JsonField) = apply { this.text = text } - - /** - * Sets the field to an arbitrary JSON value. - * - * It is usually unnecessary to call this method because the field - * defaults to the following: - * ```java - * JsonValue.from("output_text") - * ``` - * - * This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun type(type: JsonValue) = apply { this.type = type } - - fun additionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties( - additionalProperties: Map - ) = apply { this.additionalProperties.putAll(additionalProperties) } - - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [OutputText]. - * - * Further updates to this [Builder] will not mutate the returned - * instance. - * - * The following fields are required: - * ```java - * .text() - * ``` - * - * @throws IllegalStateException if any required field is unset. - */ - fun build(): OutputText = - OutputText( - checkRequired("text", text), - type, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): OutputText = apply { - if (validated) { - return@apply - } - - text() - _type().let { - if (it != JsonValue.from("output_text")) { - throw OpenAIInvalidDataException( - "'type' is invalid, received $it" - ) - } - } - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this - * object recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (if (text.asKnown().isPresent) 1 else 0) + - type.let { if (it == JsonValue.from("output_text")) 1 else 0 } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is OutputText && text == other.text && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ - } - - /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(text, type, additionalProperties) } - /* spotless:on */ - - override fun hashCode(): Int = hashCode - - override fun toString() = - "OutputText{text=$text, type=$type, additionalProperties=$additionalProperties}" - } - } + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } /** - * The role of the message input. One of `user`, `assistant`, `system`, or - * `developer`. + * Returns an immutable instance of [ScoreModel]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .input() + * .model() + * .name() + * ``` + * + * @throws IllegalStateException if any required field is unset. */ - class Role @JsonCreator private constructor(private val value: JsonField) : - Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that - * doesn't match any known member, and you want to know that value. For example, - * if the SDK is on an older version than the API, then the API may respond with - * new members that the SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue - fun _value(): JsonField = value - - companion object { - - @JvmField val USER = of("user") - - @JvmField val ASSISTANT = of("assistant") - - @JvmField val SYSTEM = of("system") - - @JvmField val DEVELOPER = of("developer") - - @JvmStatic fun of(value: String) = Role(JsonField.of(value)) - } - - /** An enum containing [Role]'s known values. */ - enum class Known { - USER, - ASSISTANT, - SYSTEM, - DEVELOPER, - } - - /** - * An enum containing [Role]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Role] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For - * example, if the SDK is on an older version than the API, then the API may - * respond with new members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - USER, - ASSISTANT, - SYSTEM, - DEVELOPER, - /** - * An enum member indicating that [Role] was instantiated with an unknown - * value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or - * if you want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - USER -> Value.USER - ASSISTANT -> Value.ASSISTANT - SYSTEM -> Value.SYSTEM - DEVELOPER -> Value.DEVELOPER - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known - * and don't want to throw for the unknown case. - * - * @throws OpenAIInvalidDataException if this class instance's value is a not a - * known member. - */ - fun known(): Known = - when (this) { - USER -> Known.USER - ASSISTANT -> Known.ASSISTANT - SYSTEM -> Known.SYSTEM - DEVELOPER -> Known.DEVELOPER - else -> throw OpenAIInvalidDataException("Unknown Role: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for - * debugging and generally doesn't throw. - * - * @throws OpenAIInvalidDataException if this class instance's value does not - * have the expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - OpenAIInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): Role = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is Role && value == other.value /* spotless:on */ - } + fun build(): ScoreModel = + ScoreModel( + checkRequired("input", input).map { it.toImmutable() }, + checkRequired("model", model), + checkRequired("name", name), + type, + (range ?: JsonMissing.of()).map { it.toImmutable() }, + samplingParams, + passThreshold, + additionalProperties.toMutableMap(), + ) + } - override fun hashCode() = value.hashCode() + private var validated: Boolean = false - override fun toString() = value.toString() + fun validate(): ScoreModel = apply { + if (validated) { + return@apply } - /** The type of the message input. Always `message`. */ - class Type @JsonCreator private constructor(private val value: JsonField) : - Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that - * doesn't match any known member, and you want to know that value. For example, - * if the SDK is on an older version than the API, then the API may respond with - * new members that the SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue - fun _value(): JsonField = value - - companion object { - - @JvmField val MESSAGE = of("message") - - @JvmStatic fun of(value: String) = Type(JsonField.of(value)) - } - - /** An enum containing [Type]'s known values. */ - enum class Known { - MESSAGE - } - - /** - * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Type] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For - * example, if the SDK is on an older version than the API, then the API may - * respond with new members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - MESSAGE, - /** - * An enum member indicating that [Type] was instantiated with an unknown - * value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or - * if you want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - MESSAGE -> Value.MESSAGE - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known - * and don't want to throw for the unknown case. - * - * @throws OpenAIInvalidDataException if this class instance's value is a not a - * known member. - */ - fun known(): Known = - when (this) { - MESSAGE -> Known.MESSAGE - else -> throw OpenAIInvalidDataException("Unknown Type: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for - * debugging and generally doesn't throw. - * - * @throws OpenAIInvalidDataException if this class instance's value does not - * have the expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - OpenAIInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): Type = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + input().forEach { it.validate() } + model() + name() + _type().let { + if (it != JsonValue.from("score_model")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() } + range() + passThreshold() + validated = true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is Input && content == other.content && role == other.role && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false } - /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(content, role, type, additionalProperties) } - /* spotless:on */ - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Input{content=$content, role=$role, type=$type, additionalProperties=$additionalProperties}" - } + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (input.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (model.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("score_model")) 1 else 0 } + + (range.asKnown().getOrNull()?.size ?: 0) + + (if (passThreshold.asKnown().isPresent) 1 else 0) override fun equals(other: Any?): Boolean { if (this === other) { return true } - return /* spotless:off */ other is ScoreModel && input == other.input && model == other.model && name == other.name && type == other.type && passThreshold == other.passThreshold && range == other.range && samplingParams == other.samplingParams && additionalProperties == other.additionalProperties /* spotless:on */ + return /* spotless:off */ other is ScoreModel && input == other.input && model == other.model && name == other.name && type == other.type && range == other.range && samplingParams == other.samplingParams && passThreshold == other.passThreshold && additionalProperties == other.additionalProperties /* spotless:on */ } /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(input, model, name, type, passThreshold, range, samplingParams, additionalProperties) } + private val hashCode: Int by lazy { Objects.hash(input, model, name, type, range, samplingParams, passThreshold, additionalProperties) } /* spotless:on */ override fun hashCode(): Int = hashCode override fun toString() = - "ScoreModel{input=$input, model=$model, name=$name, type=$type, passThreshold=$passThreshold, range=$range, samplingParams=$samplingParams, additionalProperties=$additionalProperties}" + "ScoreModel{input=$input, model=$model, name=$name, type=$type, range=$range, samplingParams=$samplingParams, passThreshold=$passThreshold, additionalProperties=$additionalProperties}" } } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalCreateResponse.kt b/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalCreateResponse.kt index 40073b39..0982511f 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalCreateResponse.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalCreateResponse.kt @@ -15,7 +15,6 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import com.openai.core.BaseDeserializer import com.openai.core.BaseSerializer -import com.openai.core.Enum import com.openai.core.ExcludeMissing import com.openai.core.JsonField import com.openai.core.JsonMissing @@ -26,7 +25,11 @@ import com.openai.core.checkRequired import com.openai.core.getOrThrow import com.openai.core.toImmutable import com.openai.errors.OpenAIInvalidDataException -import com.openai.models.responses.ResponseInputText +import com.openai.models.graders.gradermodels.LabelModelGrader +import com.openai.models.graders.gradermodels.PythonGrader +import com.openai.models.graders.gradermodels.ScoreModelGrader +import com.openai.models.graders.gradermodels.StringCheckGrader +import com.openai.models.graders.gradermodels.TextSimilarityGrader import java.util.Collections import java.util.Objects import java.util.Optional @@ -388,34 +391,43 @@ private constructor( } /** - * Alias for calling [addTestingCriterion] with `TestingCriterion.ofLabelModel(labelModel)`. + * Alias for calling [addTestingCriterion] with + * `TestingCriterion.ofLabelModelGrader(labelModelGrader)`. */ - fun addTestingCriterion(labelModel: EvalLabelModelGrader) = - addTestingCriterion(TestingCriterion.ofLabelModel(labelModel)) + fun addTestingCriterion(labelModelGrader: LabelModelGrader) = + addTestingCriterion(TestingCriterion.ofLabelModelGrader(labelModelGrader)) /** * Alias for calling [addTestingCriterion] with - * `TestingCriterion.ofStringCheck(stringCheck)`. + * `TestingCriterion.ofStringCheckGrader(stringCheckGrader)`. */ - fun addTestingCriterion(stringCheck: EvalStringCheckGrader) = - addTestingCriterion(TestingCriterion.ofStringCheck(stringCheck)) + fun addTestingCriterion(stringCheckGrader: StringCheckGrader) = + addTestingCriterion(TestingCriterion.ofStringCheckGrader(stringCheckGrader)) /** * Alias for calling [addTestingCriterion] with - * `TestingCriterion.ofTextSimilarity(textSimilarity)`. + * `TestingCriterion.ofEvalGraderTextSimilarity(evalGraderTextSimilarity)`. */ - fun addTestingCriterion(textSimilarity: EvalTextSimilarityGrader) = - addTestingCriterion(TestingCriterion.ofTextSimilarity(textSimilarity)) + fun addTestingCriterion( + evalGraderTextSimilarity: TestingCriterion.EvalGraderTextSimilarity + ) = + addTestingCriterion( + TestingCriterion.ofEvalGraderTextSimilarity(evalGraderTextSimilarity) + ) - /** Alias for calling [addTestingCriterion] with `TestingCriterion.ofPython(python)`. */ - fun addTestingCriterion(python: TestingCriterion.Python) = - addTestingCriterion(TestingCriterion.ofPython(python)) + /** + * Alias for calling [addTestingCriterion] with + * `TestingCriterion.ofEvalGraderPython(evalGraderPython)`. + */ + fun addTestingCriterion(evalGraderPython: TestingCriterion.EvalGraderPython) = + addTestingCriterion(TestingCriterion.ofEvalGraderPython(evalGraderPython)) /** - * Alias for calling [addTestingCriterion] with `TestingCriterion.ofScoreModel(scoreModel)`. + * Alias for calling [addTestingCriterion] with + * `TestingCriterion.ofEvalGraderScoreModel(evalGraderScoreModel)`. */ - fun addTestingCriterion(scoreModel: TestingCriterion.ScoreModel) = - addTestingCriterion(TestingCriterion.ofScoreModel(scoreModel)) + fun addTestingCriterion(evalGraderScoreModel: TestingCriterion.EvalGraderScoreModel) = + addTestingCriterion(TestingCriterion.ofEvalGraderScoreModel(evalGraderScoreModel)) fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() @@ -860,11 +872,11 @@ private constructor( @JsonSerialize(using = TestingCriterion.Serializer::class) class TestingCriterion private constructor( - private val labelModel: EvalLabelModelGrader? = null, - private val stringCheck: EvalStringCheckGrader? = null, - private val textSimilarity: EvalTextSimilarityGrader? = null, - private val python: Python? = null, - private val scoreModel: ScoreModel? = null, + private val labelModelGrader: LabelModelGrader? = null, + private val stringCheckGrader: StringCheckGrader? = null, + private val evalGraderTextSimilarity: EvalGraderTextSimilarity? = null, + private val evalGraderPython: EvalGraderPython? = null, + private val evalGraderScoreModel: EvalGraderScoreModel? = null, private val _json: JsonValue? = null, ) { @@ -872,65 +884,71 @@ private constructor( * A LabelModelGrader object which uses a model to assign labels to each item in the * evaluation. */ - fun labelModel(): Optional = Optional.ofNullable(labelModel) + fun labelModelGrader(): Optional = Optional.ofNullable(labelModelGrader) /** * A StringCheckGrader object that performs a string comparison between input and reference * using a specified operation. */ - fun stringCheck(): Optional = Optional.ofNullable(stringCheck) + fun stringCheckGrader(): Optional = + Optional.ofNullable(stringCheckGrader) /** A TextSimilarityGrader object which grades text based on similarity metrics. */ - fun textSimilarity(): Optional = - Optional.ofNullable(textSimilarity) + fun evalGraderTextSimilarity(): Optional = + Optional.ofNullable(evalGraderTextSimilarity) /** A PythonGrader object that runs a python script on the input. */ - fun python(): Optional = Optional.ofNullable(python) + fun evalGraderPython(): Optional = Optional.ofNullable(evalGraderPython) /** A ScoreModelGrader object that uses a model to assign a score to the input. */ - fun scoreModel(): Optional = Optional.ofNullable(scoreModel) + fun evalGraderScoreModel(): Optional = + Optional.ofNullable(evalGraderScoreModel) - fun isLabelModel(): Boolean = labelModel != null + fun isLabelModelGrader(): Boolean = labelModelGrader != null - fun isStringCheck(): Boolean = stringCheck != null + fun isStringCheckGrader(): Boolean = stringCheckGrader != null - fun isTextSimilarity(): Boolean = textSimilarity != null + fun isEvalGraderTextSimilarity(): Boolean = evalGraderTextSimilarity != null - fun isPython(): Boolean = python != null + fun isEvalGraderPython(): Boolean = evalGraderPython != null - fun isScoreModel(): Boolean = scoreModel != null + fun isEvalGraderScoreModel(): Boolean = evalGraderScoreModel != null /** * A LabelModelGrader object which uses a model to assign labels to each item in the * evaluation. */ - fun asLabelModel(): EvalLabelModelGrader = labelModel.getOrThrow("labelModel") + fun asLabelModelGrader(): LabelModelGrader = labelModelGrader.getOrThrow("labelModelGrader") /** * A StringCheckGrader object that performs a string comparison between input and reference * using a specified operation. */ - fun asStringCheck(): EvalStringCheckGrader = stringCheck.getOrThrow("stringCheck") + fun asStringCheckGrader(): StringCheckGrader = + stringCheckGrader.getOrThrow("stringCheckGrader") /** A TextSimilarityGrader object which grades text based on similarity metrics. */ - fun asTextSimilarity(): EvalTextSimilarityGrader = - textSimilarity.getOrThrow("textSimilarity") + fun asEvalGraderTextSimilarity(): EvalGraderTextSimilarity = + evalGraderTextSimilarity.getOrThrow("evalGraderTextSimilarity") /** A PythonGrader object that runs a python script on the input. */ - fun asPython(): Python = python.getOrThrow("python") + fun asEvalGraderPython(): EvalGraderPython = evalGraderPython.getOrThrow("evalGraderPython") /** A ScoreModelGrader object that uses a model to assign a score to the input. */ - fun asScoreModel(): ScoreModel = scoreModel.getOrThrow("scoreModel") + fun asEvalGraderScoreModel(): EvalGraderScoreModel = + evalGraderScoreModel.getOrThrow("evalGraderScoreModel") fun _json(): Optional = Optional.ofNullable(_json) fun accept(visitor: Visitor): T = when { - labelModel != null -> visitor.visitLabelModel(labelModel) - stringCheck != null -> visitor.visitStringCheck(stringCheck) - textSimilarity != null -> visitor.visitTextSimilarity(textSimilarity) - python != null -> visitor.visitPython(python) - scoreModel != null -> visitor.visitScoreModel(scoreModel) + labelModelGrader != null -> visitor.visitLabelModelGrader(labelModelGrader) + stringCheckGrader != null -> visitor.visitStringCheckGrader(stringCheckGrader) + evalGraderTextSimilarity != null -> + visitor.visitEvalGraderTextSimilarity(evalGraderTextSimilarity) + evalGraderPython != null -> visitor.visitEvalGraderPython(evalGraderPython) + evalGraderScoreModel != null -> + visitor.visitEvalGraderScoreModel(evalGraderScoreModel) else -> visitor.unknown(_json) } @@ -943,24 +961,28 @@ private constructor( accept( object : Visitor { - override fun visitLabelModel(labelModel: EvalLabelModelGrader) { - labelModel.validate() + override fun visitLabelModelGrader(labelModelGrader: LabelModelGrader) { + labelModelGrader.validate() } - override fun visitStringCheck(stringCheck: EvalStringCheckGrader) { - stringCheck.validate() + override fun visitStringCheckGrader(stringCheckGrader: StringCheckGrader) { + stringCheckGrader.validate() } - override fun visitTextSimilarity(textSimilarity: EvalTextSimilarityGrader) { - textSimilarity.validate() + override fun visitEvalGraderTextSimilarity( + evalGraderTextSimilarity: EvalGraderTextSimilarity + ) { + evalGraderTextSimilarity.validate() } - override fun visitPython(python: Python) { - python.validate() + override fun visitEvalGraderPython(evalGraderPython: EvalGraderPython) { + evalGraderPython.validate() } - override fun visitScoreModel(scoreModel: ScoreModel) { - scoreModel.validate() + override fun visitEvalGraderScoreModel( + evalGraderScoreModel: EvalGraderScoreModel + ) { + evalGraderScoreModel.validate() } } ) @@ -985,18 +1007,22 @@ private constructor( internal fun validity(): Int = accept( object : Visitor { - override fun visitLabelModel(labelModel: EvalLabelModelGrader) = - labelModel.validity() + override fun visitLabelModelGrader(labelModelGrader: LabelModelGrader) = + labelModelGrader.validity() - override fun visitStringCheck(stringCheck: EvalStringCheckGrader) = - stringCheck.validity() + override fun visitStringCheckGrader(stringCheckGrader: StringCheckGrader) = + stringCheckGrader.validity() - override fun visitTextSimilarity(textSimilarity: EvalTextSimilarityGrader) = - textSimilarity.validity() + override fun visitEvalGraderTextSimilarity( + evalGraderTextSimilarity: EvalGraderTextSimilarity + ) = evalGraderTextSimilarity.validity() - override fun visitPython(python: Python) = python.validity() + override fun visitEvalGraderPython(evalGraderPython: EvalGraderPython) = + evalGraderPython.validity() - override fun visitScoreModel(scoreModel: ScoreModel) = scoreModel.validity() + override fun visitEvalGraderScoreModel( + evalGraderScoreModel: EvalGraderScoreModel + ) = evalGraderScoreModel.validity() override fun unknown(json: JsonValue?) = 0 } @@ -1007,18 +1033,21 @@ private constructor( return true } - return /* spotless:off */ other is TestingCriterion && labelModel == other.labelModel && stringCheck == other.stringCheck && textSimilarity == other.textSimilarity && python == other.python && scoreModel == other.scoreModel /* spotless:on */ + return /* spotless:off */ other is TestingCriterion && labelModelGrader == other.labelModelGrader && stringCheckGrader == other.stringCheckGrader && evalGraderTextSimilarity == other.evalGraderTextSimilarity && evalGraderPython == other.evalGraderPython && evalGraderScoreModel == other.evalGraderScoreModel /* spotless:on */ } - override fun hashCode(): Int = /* spotless:off */ Objects.hash(labelModel, stringCheck, textSimilarity, python, scoreModel) /* spotless:on */ + override fun hashCode(): Int = /* spotless:off */ Objects.hash(labelModelGrader, stringCheckGrader, evalGraderTextSimilarity, evalGraderPython, evalGraderScoreModel) /* spotless:on */ override fun toString(): String = when { - labelModel != null -> "TestingCriterion{labelModel=$labelModel}" - stringCheck != null -> "TestingCriterion{stringCheck=$stringCheck}" - textSimilarity != null -> "TestingCriterion{textSimilarity=$textSimilarity}" - python != null -> "TestingCriterion{python=$python}" - scoreModel != null -> "TestingCriterion{scoreModel=$scoreModel}" + labelModelGrader != null -> "TestingCriterion{labelModelGrader=$labelModelGrader}" + stringCheckGrader != null -> + "TestingCriterion{stringCheckGrader=$stringCheckGrader}" + evalGraderTextSimilarity != null -> + "TestingCriterion{evalGraderTextSimilarity=$evalGraderTextSimilarity}" + evalGraderPython != null -> "TestingCriterion{evalGraderPython=$evalGraderPython}" + evalGraderScoreModel != null -> + "TestingCriterion{evalGraderScoreModel=$evalGraderScoreModel}" _json != null -> "TestingCriterion{_unknown=$_json}" else -> throw IllegalStateException("Invalid TestingCriterion") } @@ -1030,28 +1059,31 @@ private constructor( * evaluation. */ @JvmStatic - fun ofLabelModel(labelModel: EvalLabelModelGrader) = - TestingCriterion(labelModel = labelModel) + fun ofLabelModelGrader(labelModelGrader: LabelModelGrader) = + TestingCriterion(labelModelGrader = labelModelGrader) /** * A StringCheckGrader object that performs a string comparison between input and * reference using a specified operation. */ @JvmStatic - fun ofStringCheck(stringCheck: EvalStringCheckGrader) = - TestingCriterion(stringCheck = stringCheck) + fun ofStringCheckGrader(stringCheckGrader: StringCheckGrader) = + TestingCriterion(stringCheckGrader = stringCheckGrader) /** A TextSimilarityGrader object which grades text based on similarity metrics. */ @JvmStatic - fun ofTextSimilarity(textSimilarity: EvalTextSimilarityGrader) = - TestingCriterion(textSimilarity = textSimilarity) + fun ofEvalGraderTextSimilarity(evalGraderTextSimilarity: EvalGraderTextSimilarity) = + TestingCriterion(evalGraderTextSimilarity = evalGraderTextSimilarity) /** A PythonGrader object that runs a python script on the input. */ - @JvmStatic fun ofPython(python: Python) = TestingCriterion(python = python) + @JvmStatic + fun ofEvalGraderPython(evalGraderPython: EvalGraderPython) = + TestingCriterion(evalGraderPython = evalGraderPython) /** A ScoreModelGrader object that uses a model to assign a score to the input. */ @JvmStatic - fun ofScoreModel(scoreModel: ScoreModel) = TestingCriterion(scoreModel = scoreModel) + fun ofEvalGraderScoreModel(evalGraderScoreModel: EvalGraderScoreModel) = + TestingCriterion(evalGraderScoreModel = evalGraderScoreModel) } /** @@ -1064,22 +1096,22 @@ private constructor( * A LabelModelGrader object which uses a model to assign labels to each item in the * evaluation. */ - fun visitLabelModel(labelModel: EvalLabelModelGrader): T + fun visitLabelModelGrader(labelModelGrader: LabelModelGrader): T /** * A StringCheckGrader object that performs a string comparison between input and * reference using a specified operation. */ - fun visitStringCheck(stringCheck: EvalStringCheckGrader): T + fun visitStringCheckGrader(stringCheckGrader: StringCheckGrader): T /** A TextSimilarityGrader object which grades text based on similarity metrics. */ - fun visitTextSimilarity(textSimilarity: EvalTextSimilarityGrader): T + fun visitEvalGraderTextSimilarity(evalGraderTextSimilarity: EvalGraderTextSimilarity): T /** A PythonGrader object that runs a python script on the input. */ - fun visitPython(python: Python): T + fun visitEvalGraderPython(evalGraderPython: EvalGraderPython): T /** A ScoreModelGrader object that uses a model to assign a score to the input. */ - fun visitScoreModel(scoreModel: ScoreModel): T + fun visitEvalGraderScoreModel(evalGraderScoreModel: EvalGraderScoreModel): T /** * Maps an unknown variant of [TestingCriterion] to a value of type [T]. @@ -1100,37 +1132,38 @@ private constructor( override fun ObjectCodec.deserialize(node: JsonNode): TestingCriterion { val json = JsonValue.fromJsonNode(node) - val type = json.asObject().getOrNull()?.get("type")?.asString()?.getOrNull() - when (type) { - "label_model" -> { - return tryDeserialize(node, jacksonTypeRef())?.let { - TestingCriterion(labelModel = it, _json = json) - } ?: TestingCriterion(_json = json) - } - "string_check" -> { - return tryDeserialize(node, jacksonTypeRef())?.let { - TestingCriterion(stringCheck = it, _json = json) - } ?: TestingCriterion(_json = json) - } - "text_similarity" -> { - return tryDeserialize(node, jacksonTypeRef()) - ?.let { TestingCriterion(textSimilarity = it, _json = json) } - ?: TestingCriterion(_json = json) - } - "python" -> { - return tryDeserialize(node, jacksonTypeRef())?.let { - TestingCriterion(python = it, _json = json) - } ?: TestingCriterion(_json = json) - } - "score_model" -> { - return tryDeserialize(node, jacksonTypeRef())?.let { - TestingCriterion(scoreModel = it, _json = json) - } ?: TestingCriterion(_json = json) - } + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + TestingCriterion(labelModelGrader = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + TestingCriterion(stringCheckGrader = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + TestingCriterion(evalGraderTextSimilarity = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + TestingCriterion(evalGraderPython = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + TestingCriterion(evalGraderScoreModel = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with + // all the possible variants (e.g. deserializing from boolean). + 0 -> TestingCriterion(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely + // valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() } - - return TestingCriterion(_json = json) } } @@ -1142,42 +1175,77 @@ private constructor( provider: SerializerProvider, ) { when { - value.labelModel != null -> generator.writeObject(value.labelModel) - value.stringCheck != null -> generator.writeObject(value.stringCheck) - value.textSimilarity != null -> generator.writeObject(value.textSimilarity) - value.python != null -> generator.writeObject(value.python) - value.scoreModel != null -> generator.writeObject(value.scoreModel) + value.labelModelGrader != null -> generator.writeObject(value.labelModelGrader) + value.stringCheckGrader != null -> + generator.writeObject(value.stringCheckGrader) + value.evalGraderTextSimilarity != null -> + generator.writeObject(value.evalGraderTextSimilarity) + value.evalGraderPython != null -> generator.writeObject(value.evalGraderPython) + value.evalGraderScoreModel != null -> + generator.writeObject(value.evalGraderScoreModel) value._json != null -> generator.writeObject(value._json) else -> throw IllegalStateException("Invalid TestingCriterion") } } } - /** A PythonGrader object that runs a python script on the input. */ - class Python + /** A TextSimilarityGrader object which grades text based on similarity metrics. */ + class EvalGraderTextSimilarity private constructor( + private val evaluationMetric: JsonField, + private val input: JsonField, private val name: JsonField, - private val source: JsonField, + private val reference: JsonField, private val type: JsonValue, - private val imageTag: JsonField, private val passThreshold: JsonField, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( + @JsonProperty("evaluation_metric") + @ExcludeMissing + evaluationMetric: JsonField = + JsonMissing.of(), + @JsonProperty("input") @ExcludeMissing input: JsonField = JsonMissing.of(), @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), - @JsonProperty("source") + @JsonProperty("reference") @ExcludeMissing - source: JsonField = JsonMissing.of(), + reference: JsonField = JsonMissing.of(), @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), - @JsonProperty("image_tag") - @ExcludeMissing - imageTag: JsonField = JsonMissing.of(), @JsonProperty("pass_threshold") @ExcludeMissing passThreshold: JsonField = JsonMissing.of(), - ) : this(name, source, type, imageTag, passThreshold, mutableMapOf()) + ) : this(evaluationMetric, input, name, reference, type, passThreshold, mutableMapOf()) + + fun toTextSimilarityGrader(): TextSimilarityGrader = + TextSimilarityGrader.builder() + .evaluationMetric(evaluationMetric) + .input(input) + .name(name) + .reference(reference) + .type(type) + .build() + + /** + * The evaluation metric to use. One of `fuzzy_match`, `bleu`, `gleu`, `meteor`, + * `rouge_1`, `rouge_2`, `rouge_3`, `rouge_4`, `rouge_5`, or `rouge_l`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun evaluationMetric(): TextSimilarityGrader.EvaluationMetric = + evaluationMetric.getRequired("evaluation_metric") + + /** + * The text being graded. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun input(): String = input.getRequired("input") /** * The name of the grader. @@ -1189,20 +1257,20 @@ private constructor( fun name(): String = name.getRequired("name") /** - * The source code of the python script. + * The text being graded against. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected * value). */ - fun source(): String = source.getRequired("source") + fun reference(): String = reference.getRequired("reference") /** - * The object type, which is always `python`. + * The type of grader. * * Expected to always return the following: * ```java - * JsonValue.from("python") + * JsonValue.from("text_similarity") * ``` * * However, this method can be useful for debugging and logging (e.g. if the server @@ -1211,42 +1279,48 @@ private constructor( @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type /** - * The image tag to use for the python script. + * The threshold for the score. * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). */ - fun imageTag(): Optional = imageTag.getOptional("image_tag") + fun passThreshold(): Double = passThreshold.getRequired("pass_threshold") /** - * The threshold for the score. + * Returns the raw JSON value of [evaluationMetric]. * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). + * Unlike [evaluationMetric], this method doesn't throw if the JSON field has an + * unexpected type. */ - fun passThreshold(): Optional = passThreshold.getOptional("pass_threshold") + @JsonProperty("evaluation_metric") + @ExcludeMissing + fun _evaluationMetric(): JsonField = + evaluationMetric /** - * Returns the raw JSON value of [name]. + * Returns the raw JSON value of [input]. * - * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [input], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + @JsonProperty("input") @ExcludeMissing fun _input(): JsonField = input /** - * Returns the raw JSON value of [source]. + * Returns the raw JSON value of [name]. * - * Unlike [source], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("source") @ExcludeMissing fun _source(): JsonField = source + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name /** - * Returns the raw JSON value of [imageTag]. + * Returns the raw JSON value of [reference]. * - * Unlike [imageTag], this method doesn't throw if the JSON field has an unexpected + * Unlike [reference], this method doesn't throw if the JSON field has an unexpected * type. */ - @JsonProperty("image_tag") @ExcludeMissing fun _imageTag(): JsonField = imageTag + @JsonProperty("reference") + @ExcludeMissing + fun _reference(): JsonField = reference /** * Returns the raw JSON value of [passThreshold]. @@ -1273,37 +1347,75 @@ private constructor( companion object { /** - * Returns a mutable builder for constructing an instance of [Python]. + * Returns a mutable builder for constructing an instance of + * [EvalGraderTextSimilarity]. * * The following fields are required: * ```java + * .evaluationMetric() + * .input() * .name() - * .source() + * .reference() + * .passThreshold() * ``` */ @JvmStatic fun builder() = Builder() } - /** A builder for [Python]. */ + /** A builder for [EvalGraderTextSimilarity]. */ class Builder internal constructor() { + private var evaluationMetric: JsonField? = + null + private var input: JsonField? = null private var name: JsonField? = null - private var source: JsonField? = null - private var type: JsonValue = JsonValue.from("python") - private var imageTag: JsonField = JsonMissing.of() - private var passThreshold: JsonField = JsonMissing.of() + private var reference: JsonField? = null + private var type: JsonValue = JsonValue.from("text_similarity") + private var passThreshold: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(python: Python) = apply { - name = python.name - source = python.source - type = python.type - imageTag = python.imageTag - passThreshold = python.passThreshold - additionalProperties = python.additionalProperties.toMutableMap() + internal fun from(evalGraderTextSimilarity: EvalGraderTextSimilarity) = apply { + evaluationMetric = evalGraderTextSimilarity.evaluationMetric + input = evalGraderTextSimilarity.input + name = evalGraderTextSimilarity.name + reference = evalGraderTextSimilarity.reference + type = evalGraderTextSimilarity.type + passThreshold = evalGraderTextSimilarity.passThreshold + additionalProperties = + evalGraderTextSimilarity.additionalProperties.toMutableMap() } + /** + * The evaluation metric to use. One of `fuzzy_match`, `bleu`, `gleu`, `meteor`, + * `rouge_1`, `rouge_2`, `rouge_3`, `rouge_4`, `rouge_5`, or `rouge_l`. + */ + fun evaluationMetric(evaluationMetric: TextSimilarityGrader.EvaluationMetric) = + evaluationMetric(JsonField.of(evaluationMetric)) + + /** + * Sets [Builder.evaluationMetric] to an arbitrary JSON value. + * + * You should usually call [Builder.evaluationMetric] with a well-typed + * [TextSimilarityGrader.EvaluationMetric] value instead. This method is primarily + * for setting the field to an undocumented or not yet supported value. + */ + fun evaluationMetric( + evaluationMetric: JsonField + ) = apply { this.evaluationMetric = evaluationMetric } + + /** The text being graded. */ + fun input(input: String) = input(JsonField.of(input)) + + /** + * Sets [Builder.input] to an arbitrary JSON value. + * + * You should usually call [Builder.input] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun input(input: JsonField) = apply { this.input = input } + /** The name of the grader. */ fun name(name: String) = name(JsonField.of(name)) @@ -1316,17 +1428,17 @@ private constructor( */ fun name(name: JsonField) = apply { this.name = name } - /** The source code of the python script. */ - fun source(source: String) = source(JsonField.of(source)) + /** The text being graded against. */ + fun reference(reference: String) = reference(JsonField.of(reference)) /** - * Sets [Builder.source] to an arbitrary JSON value. + * Sets [Builder.reference] to an arbitrary JSON value. * - * You should usually call [Builder.source] with a well-typed [String] value + * You should usually call [Builder.reference] with a well-typed [String] value * instead. This method is primarily for setting the field to an undocumented or not * yet supported value. */ - fun source(source: JsonField) = apply { this.source = source } + fun reference(reference: JsonField) = apply { this.reference = reference } /** * Sets the field to an arbitrary JSON value. @@ -1334,7 +1446,7 @@ private constructor( * It is usually unnecessary to call this method because the field defaults to the * following: * ```java - * JsonValue.from("python") + * JsonValue.from("text_similarity") * ``` * * This method is primarily for setting the field to an undocumented or not yet @@ -1342,18 +1454,6 @@ private constructor( */ fun type(type: JsonValue) = apply { this.type = type } - /** The image tag to use for the python script. */ - fun imageTag(imageTag: String) = imageTag(JsonField.of(imageTag)) - - /** - * Sets [Builder.imageTag] to an arbitrary JSON value. - * - * You should usually call [Builder.imageTag] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun imageTag(imageTag: JsonField) = apply { this.imageTag = imageTag } - /** The threshold for the score. */ fun passThreshold(passThreshold: Double) = passThreshold(JsonField.of(passThreshold)) @@ -1392,44 +1492,49 @@ private constructor( } /** - * Returns an immutable instance of [Python]. + * Returns an immutable instance of [EvalGraderTextSimilarity]. * * Further updates to this [Builder] will not mutate the returned instance. * * The following fields are required: * ```java + * .evaluationMetric() + * .input() * .name() - * .source() + * .reference() + * .passThreshold() * ``` * * @throws IllegalStateException if any required field is unset. */ - fun build(): Python = - Python( + fun build(): EvalGraderTextSimilarity = + EvalGraderTextSimilarity( + checkRequired("evaluationMetric", evaluationMetric), + checkRequired("input", input), checkRequired("name", name), - checkRequired("source", source), + checkRequired("reference", reference), type, - imageTag, - passThreshold, + checkRequired("passThreshold", passThreshold), additionalProperties.toMutableMap(), ) } private var validated: Boolean = false - fun validate(): Python = apply { + fun validate(): EvalGraderTextSimilarity = apply { if (validated) { return@apply } + evaluationMetric().validate() + input() name() - source() + reference() _type().let { - if (it != JsonValue.from("python")) { + if (it != JsonValue.from("text_similarity")) { throw OpenAIInvalidDataException("'type' is invalid, received $it") } } - imageTag() passThreshold() validated = true } @@ -1450,10 +1555,11 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (if (name.asKnown().isPresent) 1 else 0) + - (if (source.asKnown().isPresent) 1 else 0) + - type.let { if (it == JsonValue.from("python")) 1 else 0 } + - (if (imageTag.asKnown().isPresent) 1 else 0) + + (evaluationMetric.asKnown().getOrNull()?.validity() ?: 0) + + (if (input.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (if (reference.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("text_similarity")) 1 else 0 } + (if (passThreshold.asKnown().isPresent) 1 else 0) override fun equals(other: Any?): Boolean { @@ -1461,84 +1567,77 @@ private constructor( return true } - return /* spotless:off */ other is Python && name == other.name && source == other.source && type == other.type && imageTag == other.imageTag && passThreshold == other.passThreshold && additionalProperties == other.additionalProperties /* spotless:on */ + return /* spotless:off */ other is EvalGraderTextSimilarity && evaluationMetric == other.evaluationMetric && input == other.input && name == other.name && reference == other.reference && type == other.type && passThreshold == other.passThreshold && additionalProperties == other.additionalProperties /* spotless:on */ } /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(name, source, type, imageTag, passThreshold, additionalProperties) } + private val hashCode: Int by lazy { Objects.hash(evaluationMetric, input, name, reference, type, passThreshold, additionalProperties) } /* spotless:on */ override fun hashCode(): Int = hashCode override fun toString() = - "Python{name=$name, source=$source, type=$type, imageTag=$imageTag, passThreshold=$passThreshold, additionalProperties=$additionalProperties}" + "EvalGraderTextSimilarity{evaluationMetric=$evaluationMetric, input=$input, name=$name, reference=$reference, type=$type, passThreshold=$passThreshold, additionalProperties=$additionalProperties}" } - /** A ScoreModelGrader object that uses a model to assign a score to the input. */ - class ScoreModel + /** A PythonGrader object that runs a python script on the input. */ + class EvalGraderPython private constructor( - private val input: JsonField>, - private val model: JsonField, private val name: JsonField, + private val source: JsonField, private val type: JsonValue, + private val imageTag: JsonField, private val passThreshold: JsonField, - private val range: JsonField>, - private val samplingParams: JsonValue, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( - @JsonProperty("input") - @ExcludeMissing - input: JsonField> = JsonMissing.of(), - @JsonProperty("model") @ExcludeMissing model: JsonField = JsonMissing.of(), @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("source") + @ExcludeMissing + source: JsonField = JsonMissing.of(), @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + @JsonProperty("image_tag") + @ExcludeMissing + imageTag: JsonField = JsonMissing.of(), @JsonProperty("pass_threshold") @ExcludeMissing passThreshold: JsonField = JsonMissing.of(), - @JsonProperty("range") - @ExcludeMissing - range: JsonField> = JsonMissing.of(), - @JsonProperty("sampling_params") - @ExcludeMissing - samplingParams: JsonValue = JsonMissing.of(), - ) : this(input, model, name, type, passThreshold, range, samplingParams, mutableMapOf()) + ) : this(name, source, type, imageTag, passThreshold, mutableMapOf()) - /** - * The input text. This may include template strings. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected - * value). - */ - fun input(): List = input.getRequired("input") + fun toPythonGrader(): PythonGrader = + PythonGrader.builder() + .name(name) + .source(source) + .type(type) + .imageTag(imageTag) + .build() /** - * The model to use for the evaluation. + * The name of the grader. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected * value). */ - fun model(): String = model.getRequired("model") + fun name(): String = name.getRequired("name") /** - * The name of the grader. + * The source code of the python script. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected * value). */ - fun name(): String = name.getRequired("name") + fun source(): String = source.getRequired("source") /** - * The object type, which is always `score_model`. + * The object type, which is always `python`. * * Expected to always return the following: * ```java - * JsonValue.from("score_model") + * JsonValue.from("python") * ``` * * However, this method can be useful for debugging and logging (e.g. if the server @@ -1547,46 +1646,42 @@ private constructor( @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type /** - * The threshold for the score. + * The image tag to use for the python script. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). */ - fun passThreshold(): Optional = passThreshold.getOptional("pass_threshold") + fun imageTag(): Optional = imageTag.getOptional("image_tag") /** - * The range of the score. Defaults to `[0, 1]`. + * The threshold for the score. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). */ - fun range(): Optional> = range.getOptional("range") - - /** The sampling parameters for the model. */ - @JsonProperty("sampling_params") - @ExcludeMissing - fun _samplingParams(): JsonValue = samplingParams + fun passThreshold(): Optional = passThreshold.getOptional("pass_threshold") /** - * Returns the raw JSON value of [input]. + * Returns the raw JSON value of [name]. * - * Unlike [input], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("input") @ExcludeMissing fun _input(): JsonField> = input + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name /** - * Returns the raw JSON value of [model]. + * Returns the raw JSON value of [source]. * - * Unlike [model], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [source], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("model") @ExcludeMissing fun _model(): JsonField = model + @JsonProperty("source") @ExcludeMissing fun _source(): JsonField = source /** - * Returns the raw JSON value of [name]. + * Returns the raw JSON value of [imageTag]. * - * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [imageTag], this method doesn't throw if the JSON field has an unexpected + * type. */ - @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + @JsonProperty("image_tag") @ExcludeMissing fun _imageTag(): JsonField = imageTag /** * Returns the raw JSON value of [passThreshold]. @@ -1598,13 +1693,6 @@ private constructor( @ExcludeMissing fun _passThreshold(): JsonField = passThreshold - /** - * Returns the raw JSON value of [range]. - * - * Unlike [range], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("range") @ExcludeMissing fun _range(): JsonField> = range - @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { additionalProperties.put(key, value) @@ -1620,80 +1708,37 @@ private constructor( companion object { /** - * Returns a mutable builder for constructing an instance of [ScoreModel]. + * Returns a mutable builder for constructing an instance of [EvalGraderPython]. * * The following fields are required: * ```java - * .input() - * .model() * .name() + * .source() * ``` */ @JvmStatic fun builder() = Builder() } - /** A builder for [ScoreModel]. */ + /** A builder for [EvalGraderPython]. */ class Builder internal constructor() { - private var input: JsonField>? = null - private var model: JsonField? = null private var name: JsonField? = null - private var type: JsonValue = JsonValue.from("score_model") + private var source: JsonField? = null + private var type: JsonValue = JsonValue.from("python") + private var imageTag: JsonField = JsonMissing.of() private var passThreshold: JsonField = JsonMissing.of() - private var range: JsonField>? = null - private var samplingParams: JsonValue = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(scoreModel: ScoreModel) = apply { - input = scoreModel.input.map { it.toMutableList() } - model = scoreModel.model - name = scoreModel.name - type = scoreModel.type - passThreshold = scoreModel.passThreshold - range = scoreModel.range.map { it.toMutableList() } - samplingParams = scoreModel.samplingParams - additionalProperties = scoreModel.additionalProperties.toMutableMap() - } - - /** The input text. This may include template strings. */ - fun input(input: List) = input(JsonField.of(input)) - - /** - * Sets [Builder.input] to an arbitrary JSON value. - * - * You should usually call [Builder.input] with a well-typed `List` value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun input(input: JsonField>) = apply { - this.input = input.map { it.toMutableList() } - } - - /** - * Adds a single [Input] to [Builder.input]. - * - * @throws IllegalStateException if the field was previously set to a non-list. - */ - fun addInput(input: Input) = apply { - this.input = - (this.input ?: JsonField.of(mutableListOf())).also { - checkKnown("input", it).add(input) - } + internal fun from(evalGraderPython: EvalGraderPython) = apply { + name = evalGraderPython.name + source = evalGraderPython.source + type = evalGraderPython.type + imageTag = evalGraderPython.imageTag + passThreshold = evalGraderPython.passThreshold + additionalProperties = evalGraderPython.additionalProperties.toMutableMap() } - /** The model to use for the evaluation. */ - 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) = apply { this.model = model } - /** The name of the grader. */ fun name(name: String) = name(JsonField.of(name)) @@ -1706,8 +1751,410 @@ private constructor( */ fun name(name: JsonField) = apply { this.name = name } + /** The source code of the python script. */ + fun source(source: String) = source(JsonField.of(source)) + /** - * Sets the field to an arbitrary JSON value. + * Sets [Builder.source] to an arbitrary JSON value. + * + * You should usually call [Builder.source] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun source(source: JsonField) = apply { this.source = source } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("python") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + /** The image tag to use for the python script. */ + fun imageTag(imageTag: String) = imageTag(JsonField.of(imageTag)) + + /** + * Sets [Builder.imageTag] to an arbitrary JSON value. + * + * You should usually call [Builder.imageTag] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun imageTag(imageTag: JsonField) = apply { this.imageTag = imageTag } + + /** The threshold for the score. */ + fun passThreshold(passThreshold: Double) = + passThreshold(JsonField.of(passThreshold)) + + /** + * Sets [Builder.passThreshold] to an arbitrary JSON value. + * + * You should usually call [Builder.passThreshold] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun passThreshold(passThreshold: JsonField) = apply { + this.passThreshold = passThreshold + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [EvalGraderPython]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * .source() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): EvalGraderPython = + EvalGraderPython( + checkRequired("name", name), + checkRequired("source", source), + type, + imageTag, + passThreshold, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): EvalGraderPython = apply { + if (validated) { + return@apply + } + + name() + source() + _type().let { + if (it != JsonValue.from("python")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + imageTag() + passThreshold() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (name.asKnown().isPresent) 1 else 0) + + (if (source.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("python")) 1 else 0 } + + (if (imageTag.asKnown().isPresent) 1 else 0) + + (if (passThreshold.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is EvalGraderPython && name == other.name && source == other.source && type == other.type && imageTag == other.imageTag && passThreshold == other.passThreshold && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, source, type, imageTag, passThreshold, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "EvalGraderPython{name=$name, source=$source, type=$type, imageTag=$imageTag, passThreshold=$passThreshold, additionalProperties=$additionalProperties}" + } + + /** A ScoreModelGrader object that uses a model to assign a score to the input. */ + class EvalGraderScoreModel + private constructor( + private val input: JsonField>, + private val model: JsonField, + private val name: JsonField, + private val type: JsonValue, + private val range: JsonField>, + private val samplingParams: JsonValue, + private val passThreshold: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("input") + @ExcludeMissing + input: JsonField> = JsonMissing.of(), + @JsonProperty("model") @ExcludeMissing model: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + @JsonProperty("range") + @ExcludeMissing + range: JsonField> = JsonMissing.of(), + @JsonProperty("sampling_params") + @ExcludeMissing + samplingParams: JsonValue = JsonMissing.of(), + @JsonProperty("pass_threshold") + @ExcludeMissing + passThreshold: JsonField = JsonMissing.of(), + ) : this(input, model, name, type, range, samplingParams, passThreshold, mutableMapOf()) + + fun toScoreModelGrader(): ScoreModelGrader = + ScoreModelGrader.builder() + .input(input) + .model(model) + .name(name) + .type(type) + .range(range) + .samplingParams(samplingParams) + .build() + + /** + * The input text. This may include template strings. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun input(): List = input.getRequired("input") + + /** + * The model to use for the evaluation. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun model(): String = model.getRequired("model") + + /** + * The name of the grader. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun name(): String = name.getRequired("name") + + /** + * The object type, which is always `score_model`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("score_model") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * The range of the score. Defaults to `[0, 1]`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun range(): Optional> = range.getOptional("range") + + /** The sampling parameters for the model. */ + @JsonProperty("sampling_params") + @ExcludeMissing + fun _samplingParams(): JsonValue = samplingParams + + /** + * The threshold for the score. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun passThreshold(): Optional = passThreshold.getOptional("pass_threshold") + + /** + * Returns the raw JSON value of [input]. + * + * Unlike [input], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("input") + @ExcludeMissing + fun _input(): JsonField> = input + + /** + * 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 = model + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [range]. + * + * Unlike [range], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("range") @ExcludeMissing fun _range(): JsonField> = range + + /** + * Returns the raw JSON value of [passThreshold]. + * + * Unlike [passThreshold], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("pass_threshold") + @ExcludeMissing + fun _passThreshold(): JsonField = passThreshold + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [EvalGraderScoreModel]. + * + * The following fields are required: + * ```java + * .input() + * .model() + * .name() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [EvalGraderScoreModel]. */ + class Builder internal constructor() { + + private var input: JsonField>? = null + private var model: JsonField? = null + private var name: JsonField? = null + private var type: JsonValue = JsonValue.from("score_model") + private var range: JsonField>? = null + private var samplingParams: JsonValue = JsonMissing.of() + private var passThreshold: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(evalGraderScoreModel: EvalGraderScoreModel) = apply { + input = evalGraderScoreModel.input.map { it.toMutableList() } + model = evalGraderScoreModel.model + name = evalGraderScoreModel.name + type = evalGraderScoreModel.type + range = evalGraderScoreModel.range.map { it.toMutableList() } + samplingParams = evalGraderScoreModel.samplingParams + passThreshold = evalGraderScoreModel.passThreshold + additionalProperties = evalGraderScoreModel.additionalProperties.toMutableMap() + } + + /** The input text. This may include template strings. */ + fun input(input: List) = input(JsonField.of(input)) + + /** + * Sets [Builder.input] to an arbitrary JSON value. + * + * You should usually call [Builder.input] with a well-typed + * `List` value instead. This method is primarily for + * setting the field to an undocumented or not yet supported value. + */ + fun input(input: JsonField>) = apply { + this.input = input.map { it.toMutableList() } + } + + /** + * Adds a single [ScoreModelGrader.Input] to [Builder.input]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addInput(input: ScoreModelGrader.Input) = apply { + this.input = + (this.input ?: JsonField.of(mutableListOf())).also { + checkKnown("input", it).add(input) + } + } + + /** The model to use for the evaluation. */ + 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) = apply { this.model = model } + + /** The name of the grader. */ + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** + * Sets the field to an arbitrary JSON value. * * It is usually unnecessary to call this method because the field defaults to the * following: @@ -1720,21 +2167,6 @@ private constructor( */ fun type(type: JsonValue) = apply { this.type = type } - /** The threshold for the score. */ - fun passThreshold(passThreshold: Double) = - passThreshold(JsonField.of(passThreshold)) - - /** - * Sets [Builder.passThreshold] to an arbitrary JSON value. - * - * You should usually call [Builder.passThreshold] with a well-typed [Double] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun passThreshold(passThreshold: JsonField) = apply { - this.passThreshold = passThreshold - } - /** The range of the score. Defaults to `[0, 1]`. */ fun range(range: List) = range(JsonField.of(range)) @@ -1766,6 +2198,21 @@ private constructor( this.samplingParams = samplingParams } + /** The threshold for the score. */ + fun passThreshold(passThreshold: Double) = + passThreshold(JsonField.of(passThreshold)) + + /** + * Sets [Builder.passThreshold] to an arbitrary JSON value. + * + * You should usually call [Builder.passThreshold] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun passThreshold(passThreshold: JsonField) = apply { + this.passThreshold = passThreshold + } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() putAllAdditionalProperties(additionalProperties) @@ -1789,7 +2236,7 @@ private constructor( } /** - * Returns an immutable instance of [ScoreModel]. + * Returns an immutable instance of [EvalGraderScoreModel]. * * Further updates to this [Builder] will not mutate the returned instance. * @@ -1802,22 +2249,22 @@ private constructor( * * @throws IllegalStateException if any required field is unset. */ - fun build(): ScoreModel = - ScoreModel( + fun build(): EvalGraderScoreModel = + EvalGraderScoreModel( checkRequired("input", input).map { it.toImmutable() }, checkRequired("model", model), checkRequired("name", name), type, - passThreshold, (range ?: JsonMissing.of()).map { it.toImmutable() }, samplingParams, + passThreshold, additionalProperties.toMutableMap(), ) } private var validated: Boolean = false - fun validate(): ScoreModel = apply { + fun validate(): EvalGraderScoreModel = apply { if (validated) { return@apply } @@ -1830,8 +2277,8 @@ private constructor( throw OpenAIInvalidDataException("'type' is invalid, received $it") } } - passThreshold() range() + passThreshold() validated = true } @@ -1855,1003 +2302,25 @@ private constructor( (if (model.asKnown().isPresent) 1 else 0) + (if (name.asKnown().isPresent) 1 else 0) + type.let { if (it == JsonValue.from("score_model")) 1 else 0 } + - (if (passThreshold.asKnown().isPresent) 1 else 0) + - (range.asKnown().getOrNull()?.size ?: 0) - - /** - * A message input to the model with a role indicating instruction following hierarchy. - * Instructions given with the `developer` or `system` role take precedence over - * instructions given with the `user` role. Messages with the `assistant` role are - * presumed to have been generated by the model in previous interactions. - */ - class Input - private constructor( - private val content: JsonField, - private val role: JsonField, - private val type: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("content") - @ExcludeMissing - content: JsonField = JsonMissing.of(), - @JsonProperty("role") @ExcludeMissing role: JsonField = JsonMissing.of(), - @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), - ) : this(content, role, type, mutableMapOf()) - - /** - * Text inputs to the model - can contain template strings. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected - * value). - */ - fun content(): Content = content.getRequired("content") - - /** - * The role of the message input. One of `user`, `assistant`, `system`, or - * `developer`. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected - * value). - */ - fun role(): Role = role.getRequired("role") - - /** - * The type of the message input. Always `message`. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun type(): Optional = type.getOptional("type") - - /** - * Returns the raw JSON value of [content]. - * - * Unlike [content], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("content") - @ExcludeMissing - fun _content(): JsonField = content - - /** - * Returns the raw JSON value of [role]. - * - * Unlike [role], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("role") @ExcludeMissing fun _role(): JsonField = role - - /** - * Returns the raw JSON value of [type]. - * - * Unlike [type], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** - * Returns a mutable builder for constructing an instance of [Input]. - * - * The following fields are required: - * ```java - * .content() - * .role() - * ``` - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Input]. */ - class Builder internal constructor() { - - private var content: JsonField? = null - private var role: JsonField? = null - private var type: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(input: Input) = apply { - content = input.content - role = input.role - type = input.type - additionalProperties = input.additionalProperties.toMutableMap() - } - - /** Text inputs to the model - can contain template strings. */ - fun content(content: Content) = content(JsonField.of(content)) - - /** - * Sets [Builder.content] to an arbitrary JSON value. - * - * You should usually call [Builder.content] with a well-typed [Content] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun content(content: JsonField) = apply { this.content = content } - - /** Alias for calling [content] with `Content.ofTextInput(textInput)`. */ - fun content(textInput: String) = content(Content.ofTextInput(textInput)) - - /** - * Alias for calling [content] with - * `Content.ofResponseInputText(responseInputText)`. - */ - fun content(responseInputText: ResponseInputText) = - content(Content.ofResponseInputText(responseInputText)) - - /** Alias for calling [content] with `Content.ofOutputText(outputText)`. */ - fun content(outputText: Content.OutputText) = - content(Content.ofOutputText(outputText)) - - /** - * The role of the message input. One of `user`, `assistant`, `system`, or - * `developer`. - */ - fun role(role: Role) = role(JsonField.of(role)) - - /** - * Sets [Builder.role] to an arbitrary JSON value. - * - * You should usually call [Builder.role] with a well-typed [Role] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun role(role: JsonField) = apply { this.role = role } - - /** The type of the message input. Always `message`. */ - fun type(type: Type) = type(JsonField.of(type)) - - /** - * Sets [Builder.type] to an arbitrary JSON value. - * - * You should usually call [Builder.type] with a well-typed [Type] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun type(type: JsonField) = apply { this.type = type } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [Input]. - * - * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .content() - * .role() - * ``` - * - * @throws IllegalStateException if any required field is unset. - */ - fun build(): Input = - Input( - checkRequired("content", content), - checkRequired("role", role), - type, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): Input = apply { - if (validated) { - return@apply - } - - content().validate() - role().validate() - type().ifPresent { it.validate() } - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (content.asKnown().getOrNull()?.validity() ?: 0) + - (role.asKnown().getOrNull()?.validity() ?: 0) + - (type.asKnown().getOrNull()?.validity() ?: 0) - - /** Text inputs to the model - can contain template strings. */ - @JsonDeserialize(using = Content.Deserializer::class) - @JsonSerialize(using = Content.Serializer::class) - class Content - private constructor( - private val textInput: String? = null, - private val responseInputText: ResponseInputText? = null, - private val outputText: OutputText? = null, - private val _json: JsonValue? = null, - ) { - - /** A text input to the model. */ - fun textInput(): Optional = Optional.ofNullable(textInput) - - /** A text input to the model. */ - fun responseInputText(): Optional = - Optional.ofNullable(responseInputText) - - /** A text output from the model. */ - fun outputText(): Optional = Optional.ofNullable(outputText) - - fun isTextInput(): Boolean = textInput != null - - fun isResponseInputText(): Boolean = responseInputText != null - - fun isOutputText(): Boolean = outputText != null - - /** A text input to the model. */ - fun asTextInput(): String = textInput.getOrThrow("textInput") - - /** A text input to the model. */ - fun asResponseInputText(): ResponseInputText = - responseInputText.getOrThrow("responseInputText") - - /** A text output from the model. */ - fun asOutputText(): OutputText = outputText.getOrThrow("outputText") - - fun _json(): Optional = Optional.ofNullable(_json) - - fun accept(visitor: Visitor): T = - when { - textInput != null -> visitor.visitTextInput(textInput) - responseInputText != null -> - visitor.visitResponseInputText(responseInputText) - outputText != null -> visitor.visitOutputText(outputText) - else -> visitor.unknown(_json) - } - - private var validated: Boolean = false - - fun validate(): Content = apply { - if (validated) { - return@apply - } - - accept( - object : Visitor { - override fun visitTextInput(textInput: String) {} - - override fun visitResponseInputText( - responseInputText: ResponseInputText - ) { - responseInputText.validate() - } - - override fun visitOutputText(outputText: OutputText) { - outputText.validate() - } - } - ) - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - accept( - object : Visitor { - override fun visitTextInput(textInput: String) = 1 - - override fun visitResponseInputText( - responseInputText: ResponseInputText - ) = responseInputText.validity() - - override fun visitOutputText(outputText: OutputText) = - outputText.validity() - - override fun unknown(json: JsonValue?) = 0 - } - ) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is Content && textInput == other.textInput && responseInputText == other.responseInputText && outputText == other.outputText /* spotless:on */ - } - - override fun hashCode(): Int = /* spotless:off */ Objects.hash(textInput, responseInputText, outputText) /* spotless:on */ - - override fun toString(): String = - when { - textInput != null -> "Content{textInput=$textInput}" - responseInputText != null -> - "Content{responseInputText=$responseInputText}" - outputText != null -> "Content{outputText=$outputText}" - _json != null -> "Content{_unknown=$_json}" - else -> throw IllegalStateException("Invalid Content") - } - - companion object { - - /** A text input to the model. */ - @JvmStatic - fun ofTextInput(textInput: String) = Content(textInput = textInput) - - /** A text input to the model. */ - @JvmStatic - fun ofResponseInputText(responseInputText: ResponseInputText) = - Content(responseInputText = responseInputText) - - /** A text output from the model. */ - @JvmStatic - fun ofOutputText(outputText: OutputText) = Content(outputText = outputText) - } - - /** - * An interface that defines how to map each variant of [Content] to a value of - * type [T]. - */ - interface Visitor { - - /** A text input to the model. */ - fun visitTextInput(textInput: String): T - - /** A text input to the model. */ - fun visitResponseInputText(responseInputText: ResponseInputText): T - - /** A text output from the model. */ - fun visitOutputText(outputText: OutputText): T - - /** - * Maps an unknown variant of [Content] to a value of type [T]. - * - * An instance of [Content] can contain an unknown variant if it was - * deserialized from data that doesn't match any known variant. For example, - * if the SDK is on an older version than the API, then the API may respond - * with new variants that the SDK is unaware of. - * - * @throws OpenAIInvalidDataException in the default implementation. - */ - fun unknown(json: JsonValue?): T { - throw OpenAIInvalidDataException("Unknown Content: $json") - } - } - - internal class Deserializer : BaseDeserializer(Content::class) { - - override fun ObjectCodec.deserialize(node: JsonNode): Content { - val json = JsonValue.fromJsonNode(node) - - val bestMatches = - sequenceOf( - tryDeserialize(node, jacksonTypeRef()) - ?.let { Content(responseInputText = it, _json = json) }, - tryDeserialize(node, jacksonTypeRef())?.let { - Content(outputText = it, _json = json) - }, - tryDeserialize(node, jacksonTypeRef())?.let { - Content(textInput = it, _json = json) - }, - ) - .filterNotNull() - .allMaxBy { it.validity() } - .toList() - return when (bestMatches.size) { - // This can happen if what we're deserializing is completely - // incompatible with all the possible variants (e.g. deserializing - // from array). - 0 -> Content(_json = json) - 1 -> bestMatches.single() - // If there's more than one match with the highest validity, then - // use the first completely valid match, or simply the first match - // if none are completely valid. - else -> - bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() - } - } - } - - internal class Serializer : BaseSerializer(Content::class) { - - override fun serialize( - value: Content, - generator: JsonGenerator, - provider: SerializerProvider, - ) { - when { - value.textInput != null -> generator.writeObject(value.textInput) - value.responseInputText != null -> - generator.writeObject(value.responseInputText) - value.outputText != null -> generator.writeObject(value.outputText) - value._json != null -> generator.writeObject(value._json) - else -> throw IllegalStateException("Invalid Content") - } - } - } - - /** A text output from the model. */ - class OutputText - private constructor( - private val text: JsonField, - private val type: JsonValue, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("text") - @ExcludeMissing - text: JsonField = JsonMissing.of(), - @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), - ) : this(text, type, mutableMapOf()) - - /** - * The text output from the model. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected - * type or is unexpectedly missing or null (e.g. if the server responded - * with an unexpected value). - */ - fun text(): String = text.getRequired("text") - - /** - * The type of the output text. Always `output_text`. - * - * Expected to always return the following: - * ```java - * JsonValue.from("output_text") - * ``` - * - * However, this method can be useful for debugging and logging (e.g. if the - * server responded with an unexpected value). - */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type - - /** - * Returns the raw JSON value of [text]. - * - * Unlike [text], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("text") @ExcludeMissing fun _text(): JsonField = text - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** - * Returns a mutable builder for constructing an instance of - * [OutputText]. - * - * The following fields are required: - * ```java - * .text() - * ``` - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [OutputText]. */ - class Builder internal constructor() { - - private var text: JsonField? = null - private var type: JsonValue = JsonValue.from("output_text") - private var additionalProperties: MutableMap = - mutableMapOf() - - @JvmSynthetic - internal fun from(outputText: OutputText) = apply { - text = outputText.text - type = outputText.type - additionalProperties = - outputText.additionalProperties.toMutableMap() - } - - /** The text output from the model. */ - fun text(text: String) = text(JsonField.of(text)) - - /** - * Sets [Builder.text] to an arbitrary JSON value. - * - * You should usually call [Builder.text] with a well-typed [String] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun text(text: JsonField) = apply { this.text = text } - - /** - * Sets the field to an arbitrary JSON value. - * - * It is usually unnecessary to call this method because the field - * defaults to the following: - * ```java - * JsonValue.from("output_text") - * ``` - * - * This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun type(type: JsonValue) = apply { this.type = type } - - fun additionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties( - additionalProperties: Map - ) = apply { this.additionalProperties.putAll(additionalProperties) } - - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [OutputText]. - * - * Further updates to this [Builder] will not mutate the returned - * instance. - * - * The following fields are required: - * ```java - * .text() - * ``` - * - * @throws IllegalStateException if any required field is unset. - */ - fun build(): OutputText = - OutputText( - checkRequired("text", text), - type, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): OutputText = apply { - if (validated) { - return@apply - } - - text() - _type().let { - if (it != JsonValue.from("output_text")) { - throw OpenAIInvalidDataException( - "'type' is invalid, received $it" - ) - } - } - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this - * object recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (if (text.asKnown().isPresent) 1 else 0) + - type.let { if (it == JsonValue.from("output_text")) 1 else 0 } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is OutputText && text == other.text && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ - } - - /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(text, type, additionalProperties) } - /* spotless:on */ - - override fun hashCode(): Int = hashCode - - override fun toString() = - "OutputText{text=$text, type=$type, additionalProperties=$additionalProperties}" - } - } - - /** - * The role of the message input. One of `user`, `assistant`, `system`, or - * `developer`. - */ - class Role @JsonCreator private constructor(private val value: JsonField) : - Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that - * doesn't match any known member, and you want to know that value. For example, - * if the SDK is on an older version than the API, then the API may respond with - * new members that the SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue - fun _value(): JsonField = value - - companion object { - - @JvmField val USER = of("user") - - @JvmField val ASSISTANT = of("assistant") - - @JvmField val SYSTEM = of("system") - - @JvmField val DEVELOPER = of("developer") - - @JvmStatic fun of(value: String) = Role(JsonField.of(value)) - } - - /** An enum containing [Role]'s known values. */ - enum class Known { - USER, - ASSISTANT, - SYSTEM, - DEVELOPER, - } - - /** - * An enum containing [Role]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Role] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For - * example, if the SDK is on an older version than the API, then the API may - * respond with new members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - USER, - ASSISTANT, - SYSTEM, - DEVELOPER, - /** - * An enum member indicating that [Role] was instantiated with an unknown - * value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or - * if you want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - USER -> Value.USER - ASSISTANT -> Value.ASSISTANT - SYSTEM -> Value.SYSTEM - DEVELOPER -> Value.DEVELOPER - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known - * and don't want to throw for the unknown case. - * - * @throws OpenAIInvalidDataException if this class instance's value is a not a - * known member. - */ - fun known(): Known = - when (this) { - USER -> Known.USER - ASSISTANT -> Known.ASSISTANT - SYSTEM -> Known.SYSTEM - DEVELOPER -> Known.DEVELOPER - else -> throw OpenAIInvalidDataException("Unknown Role: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for - * debugging and generally doesn't throw. - * - * @throws OpenAIInvalidDataException if this class instance's value does not - * have the expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - OpenAIInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): Role = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is Role && value == other.value /* spotless:on */ - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - /** The type of the message input. Always `message`. */ - class Type @JsonCreator private constructor(private val value: JsonField) : - Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that - * doesn't match any known member, and you want to know that value. For example, - * if the SDK is on an older version than the API, then the API may respond with - * new members that the SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue - fun _value(): JsonField = value - - companion object { - - @JvmField val MESSAGE = of("message") - - @JvmStatic fun of(value: String) = Type(JsonField.of(value)) - } - - /** An enum containing [Type]'s known values. */ - enum class Known { - MESSAGE - } - - /** - * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Type] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For - * example, if the SDK is on an older version than the API, then the API may - * respond with new members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - MESSAGE, - /** - * An enum member indicating that [Type] was instantiated with an unknown - * value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or - * if you want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - MESSAGE -> Value.MESSAGE - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known - * and don't want to throw for the unknown case. - * - * @throws OpenAIInvalidDataException if this class instance's value is a not a - * known member. - */ - fun known(): Known = - when (this) { - MESSAGE -> Known.MESSAGE - else -> throw OpenAIInvalidDataException("Unknown Type: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for - * debugging and generally doesn't throw. - * - * @throws OpenAIInvalidDataException if this class instance's value does not - * have the expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - OpenAIInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): Type = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is Type && value == other.value /* spotless:on */ - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is Input && content == other.content && role == other.role && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ - } - - /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(content, role, type, additionalProperties) } - /* spotless:on */ - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Input{content=$content, role=$role, type=$type, additionalProperties=$additionalProperties}" - } + (range.asKnown().getOrNull()?.size ?: 0) + + (if (passThreshold.asKnown().isPresent) 1 else 0) override fun equals(other: Any?): Boolean { if (this === other) { return true } - return /* spotless:off */ other is ScoreModel && input == other.input && model == other.model && name == other.name && type == other.type && passThreshold == other.passThreshold && range == other.range && samplingParams == other.samplingParams && additionalProperties == other.additionalProperties /* spotless:on */ + return /* spotless:off */ other is EvalGraderScoreModel && input == other.input && model == other.model && name == other.name && type == other.type && range == other.range && samplingParams == other.samplingParams && passThreshold == other.passThreshold && additionalProperties == other.additionalProperties /* spotless:on */ } /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(input, model, name, type, passThreshold, range, samplingParams, additionalProperties) } + private val hashCode: Int by lazy { Objects.hash(input, model, name, type, range, samplingParams, passThreshold, additionalProperties) } /* spotless:on */ override fun hashCode(): Int = hashCode override fun toString() = - "ScoreModel{input=$input, model=$model, name=$name, type=$type, passThreshold=$passThreshold, range=$range, samplingParams=$samplingParams, additionalProperties=$additionalProperties}" + "EvalGraderScoreModel{input=$input, model=$model, name=$name, type=$type, range=$range, samplingParams=$samplingParams, passThreshold=$passThreshold, additionalProperties=$additionalProperties}" } } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalDeleteParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalDeleteParams.kt index 7220bde2..74f97a4e 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalDeleteParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalDeleteParams.kt @@ -4,23 +4,23 @@ package com.openai.models.evals import com.openai.core.JsonValue import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import com.openai.core.toImmutable import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** Delete an evaluation. */ class EvalDeleteParams private constructor( - private val evalId: String, + private val evalId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, ) : Params { - fun evalId(): String = evalId + fun evalId(): Optional = Optional.ofNullable(evalId) fun _additionalBodyProperties(): Map = additionalBodyProperties @@ -32,14 +32,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [EvalDeleteParams]. - * - * The following fields are required: - * ```java - * .evalId() - * ``` - */ + @JvmStatic fun none(): EvalDeleteParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [EvalDeleteParams]. */ @JvmStatic fun builder() = Builder() } @@ -59,7 +54,10 @@ private constructor( additionalBodyProperties = evalDeleteParams.additionalBodyProperties.toMutableMap() } - fun evalId(evalId: String) = apply { this.evalId = evalId } + fun evalId(evalId: String?) = apply { this.evalId = evalId } + + /** Alias for calling [Builder.evalId] with `evalId.orElse(null)`. */ + fun evalId(evalId: Optional) = evalId(evalId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -185,17 +183,10 @@ private constructor( * Returns an immutable instance of [EvalDeleteParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .evalId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): EvalDeleteParams = EvalDeleteParams( - checkRequired("evalId", evalId), + evalId, additionalHeaders.build(), additionalQueryParams.build(), additionalBodyProperties.toImmutable(), @@ -207,7 +198,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> evalId + 0 -> evalId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalListPage.kt b/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalListPage.kt index aa65e3f9..38d95a84 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalListPage.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalListPage.kt @@ -2,12 +2,12 @@ package com.openai.models.evals +import com.openai.core.AutoPager +import com.openai.core.Page import com.openai.core.checkRequired import com.openai.services.blocking.EvalService import java.util.Objects import java.util.Optional -import java.util.stream.Stream -import java.util.stream.StreamSupport import kotlin.jvm.optionals.getOrNull /** @see [EvalService.list] */ @@ -16,7 +16,7 @@ private constructor( private val service: EvalService, private val params: EvalListParams, private val response: EvalListPageResponse, -) { +) : Page { /** * Delegates to [EvalListPageResponse], but gracefully handles missing data. @@ -33,19 +33,16 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): EvalListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): Optional = getNextPageParams().map { service.list(it) } + override fun nextPage(): EvalListPage = service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPager = AutoPager.from(this) /** The parameters that were used to request this page. */ fun params(): EvalListParams = params @@ -114,25 +111,6 @@ private constructor( ) } - class AutoPager(private val firstPage: EvalListPage) : Iterable { - - override fun iterator(): Iterator = iterator { - var page = firstPage - var index = 0 - while (true) { - while (index < page.data().size) { - yield(page.data()[index++]) - } - page = page.getNextPage().getOrNull() ?: break - index = 0 - } - } - - fun stream(): Stream { - return StreamSupport.stream(spliterator(), false) - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalListPageAsync.kt b/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalListPageAsync.kt index d23299f4..c98e16f5 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalListPageAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalListPageAsync.kt @@ -2,22 +2,24 @@ package com.openai.models.evals +import com.openai.core.AutoPagerAsync +import com.openai.core.PageAsync import com.openai.core.checkRequired import com.openai.services.async.EvalServiceAsync import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor -import java.util.function.Predicate import kotlin.jvm.optionals.getOrNull /** @see [EvalServiceAsync.list] */ class EvalListPageAsync private constructor( private val service: EvalServiceAsync, + private val streamHandlerExecutor: Executor, private val params: EvalListParams, private val response: EvalListPageResponse, -) { +) : PageAsync { /** * Delegates to [EvalListPageResponse], but gracefully handles missing data. @@ -34,22 +36,17 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): EvalListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): CompletableFuture> = - getNextPageParams() - .map { service.list(it).thenApply { Optional.of(it) } } - .orElseGet { CompletableFuture.completedFuture(Optional.empty()) } + override fun nextPage(): CompletableFuture = service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPagerAsync = + AutoPagerAsync.from(this, streamHandlerExecutor) /** The parameters that were used to request this page. */ fun params(): EvalListParams = params @@ -67,6 +64,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -78,18 +76,24 @@ private constructor( class Builder internal constructor() { private var service: EvalServiceAsync? = null + private var streamHandlerExecutor: Executor? = null private var params: EvalListParams? = null private var response: EvalListPageResponse? = null @JvmSynthetic internal fun from(evalListPageAsync: EvalListPageAsync) = apply { service = evalListPageAsync.service + streamHandlerExecutor = evalListPageAsync.streamHandlerExecutor params = evalListPageAsync.params response = evalListPageAsync.response } fun service(service: EvalServiceAsync) = apply { this.service = service } + fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply { + this.streamHandlerExecutor = streamHandlerExecutor + } + /** The parameters that were used to request this page. */ fun params(params: EvalListParams) = apply { this.params = params } @@ -104,6 +108,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -113,50 +118,22 @@ private constructor( fun build(): EvalListPageAsync = EvalListPageAsync( checkRequired("service", service), + checkRequired("streamHandlerExecutor", streamHandlerExecutor), checkRequired("params", params), checkRequired("response", response), ) } - class AutoPager(private val firstPage: EvalListPageAsync) { - - fun forEach( - action: Predicate, - executor: Executor, - ): CompletableFuture { - fun CompletableFuture>.forEach( - action: (EvalListResponse) -> Boolean, - executor: Executor, - ): CompletableFuture = - thenComposeAsync( - { page -> - page - .filter { it.data().all(action) } - .map { it.getNextPage().forEach(action, executor) } - .orElseGet { CompletableFuture.completedFuture(null) } - }, - executor, - ) - return CompletableFuture.completedFuture(Optional.of(firstPage)) - .forEach(action::test, executor) - } - - fun toList(executor: Executor): CompletableFuture> { - val values = mutableListOf() - return forEach(values::add, executor).thenApply { values } - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return /* spotless:off */ other is EvalListPageAsync && service == other.service && params == other.params && response == other.response /* spotless:on */ + return /* spotless:off */ other is EvalListPageAsync && service == other.service && streamHandlerExecutor == other.streamHandlerExecutor && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, params, response) /* spotless:on */ + override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, streamHandlerExecutor, params, response) /* spotless:on */ override fun toString() = - "EvalListPageAsync{service=$service, params=$params, response=$response}" + "EvalListPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, response=$response}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalListResponse.kt b/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalListResponse.kt index 2d3a7b7d..e1009107 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalListResponse.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalListResponse.kt @@ -15,7 +15,6 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import com.openai.core.BaseDeserializer import com.openai.core.BaseSerializer -import com.openai.core.Enum import com.openai.core.ExcludeMissing import com.openai.core.JsonField import com.openai.core.JsonMissing @@ -26,7 +25,11 @@ import com.openai.core.checkRequired import com.openai.core.getOrThrow import com.openai.core.toImmutable import com.openai.errors.OpenAIInvalidDataException -import com.openai.models.responses.ResponseInputText +import com.openai.models.graders.gradermodels.LabelModelGrader +import com.openai.models.graders.gradermodels.PythonGrader +import com.openai.models.graders.gradermodels.ScoreModelGrader +import com.openai.models.graders.gradermodels.StringCheckGrader +import com.openai.models.graders.gradermodels.TextSimilarityGrader import java.util.Collections import java.util.Objects import java.util.Optional @@ -388,34 +391,43 @@ private constructor( } /** - * Alias for calling [addTestingCriterion] with `TestingCriterion.ofLabelModel(labelModel)`. + * Alias for calling [addTestingCriterion] with + * `TestingCriterion.ofLabelModelGrader(labelModelGrader)`. */ - fun addTestingCriterion(labelModel: EvalLabelModelGrader) = - addTestingCriterion(TestingCriterion.ofLabelModel(labelModel)) + fun addTestingCriterion(labelModelGrader: LabelModelGrader) = + addTestingCriterion(TestingCriterion.ofLabelModelGrader(labelModelGrader)) /** * Alias for calling [addTestingCriterion] with - * `TestingCriterion.ofStringCheck(stringCheck)`. + * `TestingCriterion.ofStringCheckGrader(stringCheckGrader)`. */ - fun addTestingCriterion(stringCheck: EvalStringCheckGrader) = - addTestingCriterion(TestingCriterion.ofStringCheck(stringCheck)) + fun addTestingCriterion(stringCheckGrader: StringCheckGrader) = + addTestingCriterion(TestingCriterion.ofStringCheckGrader(stringCheckGrader)) /** * Alias for calling [addTestingCriterion] with - * `TestingCriterion.ofTextSimilarity(textSimilarity)`. + * `TestingCriterion.ofEvalGraderTextSimilarity(evalGraderTextSimilarity)`. */ - fun addTestingCriterion(textSimilarity: EvalTextSimilarityGrader) = - addTestingCriterion(TestingCriterion.ofTextSimilarity(textSimilarity)) + fun addTestingCriterion( + evalGraderTextSimilarity: TestingCriterion.EvalGraderTextSimilarity + ) = + addTestingCriterion( + TestingCriterion.ofEvalGraderTextSimilarity(evalGraderTextSimilarity) + ) - /** Alias for calling [addTestingCriterion] with `TestingCriterion.ofPython(python)`. */ - fun addTestingCriterion(python: TestingCriterion.Python) = - addTestingCriterion(TestingCriterion.ofPython(python)) + /** + * Alias for calling [addTestingCriterion] with + * `TestingCriterion.ofEvalGraderPython(evalGraderPython)`. + */ + fun addTestingCriterion(evalGraderPython: TestingCriterion.EvalGraderPython) = + addTestingCriterion(TestingCriterion.ofEvalGraderPython(evalGraderPython)) /** - * Alias for calling [addTestingCriterion] with `TestingCriterion.ofScoreModel(scoreModel)`. + * Alias for calling [addTestingCriterion] with + * `TestingCriterion.ofEvalGraderScoreModel(evalGraderScoreModel)`. */ - fun addTestingCriterion(scoreModel: TestingCriterion.ScoreModel) = - addTestingCriterion(TestingCriterion.ofScoreModel(scoreModel)) + fun addTestingCriterion(evalGraderScoreModel: TestingCriterion.EvalGraderScoreModel) = + addTestingCriterion(TestingCriterion.ofEvalGraderScoreModel(evalGraderScoreModel)) fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() @@ -860,11 +872,11 @@ private constructor( @JsonSerialize(using = TestingCriterion.Serializer::class) class TestingCriterion private constructor( - private val labelModel: EvalLabelModelGrader? = null, - private val stringCheck: EvalStringCheckGrader? = null, - private val textSimilarity: EvalTextSimilarityGrader? = null, - private val python: Python? = null, - private val scoreModel: ScoreModel? = null, + private val labelModelGrader: LabelModelGrader? = null, + private val stringCheckGrader: StringCheckGrader? = null, + private val evalGraderTextSimilarity: EvalGraderTextSimilarity? = null, + private val evalGraderPython: EvalGraderPython? = null, + private val evalGraderScoreModel: EvalGraderScoreModel? = null, private val _json: JsonValue? = null, ) { @@ -872,65 +884,71 @@ private constructor( * A LabelModelGrader object which uses a model to assign labels to each item in the * evaluation. */ - fun labelModel(): Optional = Optional.ofNullable(labelModel) + fun labelModelGrader(): Optional = Optional.ofNullable(labelModelGrader) /** * A StringCheckGrader object that performs a string comparison between input and reference * using a specified operation. */ - fun stringCheck(): Optional = Optional.ofNullable(stringCheck) + fun stringCheckGrader(): Optional = + Optional.ofNullable(stringCheckGrader) /** A TextSimilarityGrader object which grades text based on similarity metrics. */ - fun textSimilarity(): Optional = - Optional.ofNullable(textSimilarity) + fun evalGraderTextSimilarity(): Optional = + Optional.ofNullable(evalGraderTextSimilarity) /** A PythonGrader object that runs a python script on the input. */ - fun python(): Optional = Optional.ofNullable(python) + fun evalGraderPython(): Optional = Optional.ofNullable(evalGraderPython) /** A ScoreModelGrader object that uses a model to assign a score to the input. */ - fun scoreModel(): Optional = Optional.ofNullable(scoreModel) + fun evalGraderScoreModel(): Optional = + Optional.ofNullable(evalGraderScoreModel) - fun isLabelModel(): Boolean = labelModel != null + fun isLabelModelGrader(): Boolean = labelModelGrader != null - fun isStringCheck(): Boolean = stringCheck != null + fun isStringCheckGrader(): Boolean = stringCheckGrader != null - fun isTextSimilarity(): Boolean = textSimilarity != null + fun isEvalGraderTextSimilarity(): Boolean = evalGraderTextSimilarity != null - fun isPython(): Boolean = python != null + fun isEvalGraderPython(): Boolean = evalGraderPython != null - fun isScoreModel(): Boolean = scoreModel != null + fun isEvalGraderScoreModel(): Boolean = evalGraderScoreModel != null /** * A LabelModelGrader object which uses a model to assign labels to each item in the * evaluation. */ - fun asLabelModel(): EvalLabelModelGrader = labelModel.getOrThrow("labelModel") + fun asLabelModelGrader(): LabelModelGrader = labelModelGrader.getOrThrow("labelModelGrader") /** * A StringCheckGrader object that performs a string comparison between input and reference * using a specified operation. */ - fun asStringCheck(): EvalStringCheckGrader = stringCheck.getOrThrow("stringCheck") + fun asStringCheckGrader(): StringCheckGrader = + stringCheckGrader.getOrThrow("stringCheckGrader") /** A TextSimilarityGrader object which grades text based on similarity metrics. */ - fun asTextSimilarity(): EvalTextSimilarityGrader = - textSimilarity.getOrThrow("textSimilarity") + fun asEvalGraderTextSimilarity(): EvalGraderTextSimilarity = + evalGraderTextSimilarity.getOrThrow("evalGraderTextSimilarity") /** A PythonGrader object that runs a python script on the input. */ - fun asPython(): Python = python.getOrThrow("python") + fun asEvalGraderPython(): EvalGraderPython = evalGraderPython.getOrThrow("evalGraderPython") /** A ScoreModelGrader object that uses a model to assign a score to the input. */ - fun asScoreModel(): ScoreModel = scoreModel.getOrThrow("scoreModel") + fun asEvalGraderScoreModel(): EvalGraderScoreModel = + evalGraderScoreModel.getOrThrow("evalGraderScoreModel") fun _json(): Optional = Optional.ofNullable(_json) fun accept(visitor: Visitor): T = when { - labelModel != null -> visitor.visitLabelModel(labelModel) - stringCheck != null -> visitor.visitStringCheck(stringCheck) - textSimilarity != null -> visitor.visitTextSimilarity(textSimilarity) - python != null -> visitor.visitPython(python) - scoreModel != null -> visitor.visitScoreModel(scoreModel) + labelModelGrader != null -> visitor.visitLabelModelGrader(labelModelGrader) + stringCheckGrader != null -> visitor.visitStringCheckGrader(stringCheckGrader) + evalGraderTextSimilarity != null -> + visitor.visitEvalGraderTextSimilarity(evalGraderTextSimilarity) + evalGraderPython != null -> visitor.visitEvalGraderPython(evalGraderPython) + evalGraderScoreModel != null -> + visitor.visitEvalGraderScoreModel(evalGraderScoreModel) else -> visitor.unknown(_json) } @@ -943,24 +961,28 @@ private constructor( accept( object : Visitor { - override fun visitLabelModel(labelModel: EvalLabelModelGrader) { - labelModel.validate() + override fun visitLabelModelGrader(labelModelGrader: LabelModelGrader) { + labelModelGrader.validate() } - override fun visitStringCheck(stringCheck: EvalStringCheckGrader) { - stringCheck.validate() + override fun visitStringCheckGrader(stringCheckGrader: StringCheckGrader) { + stringCheckGrader.validate() } - override fun visitTextSimilarity(textSimilarity: EvalTextSimilarityGrader) { - textSimilarity.validate() + override fun visitEvalGraderTextSimilarity( + evalGraderTextSimilarity: EvalGraderTextSimilarity + ) { + evalGraderTextSimilarity.validate() } - override fun visitPython(python: Python) { - python.validate() + override fun visitEvalGraderPython(evalGraderPython: EvalGraderPython) { + evalGraderPython.validate() } - override fun visitScoreModel(scoreModel: ScoreModel) { - scoreModel.validate() + override fun visitEvalGraderScoreModel( + evalGraderScoreModel: EvalGraderScoreModel + ) { + evalGraderScoreModel.validate() } } ) @@ -985,18 +1007,22 @@ private constructor( internal fun validity(): Int = accept( object : Visitor { - override fun visitLabelModel(labelModel: EvalLabelModelGrader) = - labelModel.validity() + override fun visitLabelModelGrader(labelModelGrader: LabelModelGrader) = + labelModelGrader.validity() - override fun visitStringCheck(stringCheck: EvalStringCheckGrader) = - stringCheck.validity() + override fun visitStringCheckGrader(stringCheckGrader: StringCheckGrader) = + stringCheckGrader.validity() - override fun visitTextSimilarity(textSimilarity: EvalTextSimilarityGrader) = - textSimilarity.validity() + override fun visitEvalGraderTextSimilarity( + evalGraderTextSimilarity: EvalGraderTextSimilarity + ) = evalGraderTextSimilarity.validity() - override fun visitPython(python: Python) = python.validity() + override fun visitEvalGraderPython(evalGraderPython: EvalGraderPython) = + evalGraderPython.validity() - override fun visitScoreModel(scoreModel: ScoreModel) = scoreModel.validity() + override fun visitEvalGraderScoreModel( + evalGraderScoreModel: EvalGraderScoreModel + ) = evalGraderScoreModel.validity() override fun unknown(json: JsonValue?) = 0 } @@ -1007,18 +1033,21 @@ private constructor( return true } - return /* spotless:off */ other is TestingCriterion && labelModel == other.labelModel && stringCheck == other.stringCheck && textSimilarity == other.textSimilarity && python == other.python && scoreModel == other.scoreModel /* spotless:on */ + return /* spotless:off */ other is TestingCriterion && labelModelGrader == other.labelModelGrader && stringCheckGrader == other.stringCheckGrader && evalGraderTextSimilarity == other.evalGraderTextSimilarity && evalGraderPython == other.evalGraderPython && evalGraderScoreModel == other.evalGraderScoreModel /* spotless:on */ } - override fun hashCode(): Int = /* spotless:off */ Objects.hash(labelModel, stringCheck, textSimilarity, python, scoreModel) /* spotless:on */ + override fun hashCode(): Int = /* spotless:off */ Objects.hash(labelModelGrader, stringCheckGrader, evalGraderTextSimilarity, evalGraderPython, evalGraderScoreModel) /* spotless:on */ override fun toString(): String = when { - labelModel != null -> "TestingCriterion{labelModel=$labelModel}" - stringCheck != null -> "TestingCriterion{stringCheck=$stringCheck}" - textSimilarity != null -> "TestingCriterion{textSimilarity=$textSimilarity}" - python != null -> "TestingCriterion{python=$python}" - scoreModel != null -> "TestingCriterion{scoreModel=$scoreModel}" + labelModelGrader != null -> "TestingCriterion{labelModelGrader=$labelModelGrader}" + stringCheckGrader != null -> + "TestingCriterion{stringCheckGrader=$stringCheckGrader}" + evalGraderTextSimilarity != null -> + "TestingCriterion{evalGraderTextSimilarity=$evalGraderTextSimilarity}" + evalGraderPython != null -> "TestingCriterion{evalGraderPython=$evalGraderPython}" + evalGraderScoreModel != null -> + "TestingCriterion{evalGraderScoreModel=$evalGraderScoreModel}" _json != null -> "TestingCriterion{_unknown=$_json}" else -> throw IllegalStateException("Invalid TestingCriterion") } @@ -1030,28 +1059,31 @@ private constructor( * evaluation. */ @JvmStatic - fun ofLabelModel(labelModel: EvalLabelModelGrader) = - TestingCriterion(labelModel = labelModel) + fun ofLabelModelGrader(labelModelGrader: LabelModelGrader) = + TestingCriterion(labelModelGrader = labelModelGrader) /** * A StringCheckGrader object that performs a string comparison between input and * reference using a specified operation. */ @JvmStatic - fun ofStringCheck(stringCheck: EvalStringCheckGrader) = - TestingCriterion(stringCheck = stringCheck) + fun ofStringCheckGrader(stringCheckGrader: StringCheckGrader) = + TestingCriterion(stringCheckGrader = stringCheckGrader) /** A TextSimilarityGrader object which grades text based on similarity metrics. */ @JvmStatic - fun ofTextSimilarity(textSimilarity: EvalTextSimilarityGrader) = - TestingCriterion(textSimilarity = textSimilarity) + fun ofEvalGraderTextSimilarity(evalGraderTextSimilarity: EvalGraderTextSimilarity) = + TestingCriterion(evalGraderTextSimilarity = evalGraderTextSimilarity) /** A PythonGrader object that runs a python script on the input. */ - @JvmStatic fun ofPython(python: Python) = TestingCriterion(python = python) + @JvmStatic + fun ofEvalGraderPython(evalGraderPython: EvalGraderPython) = + TestingCriterion(evalGraderPython = evalGraderPython) /** A ScoreModelGrader object that uses a model to assign a score to the input. */ @JvmStatic - fun ofScoreModel(scoreModel: ScoreModel) = TestingCriterion(scoreModel = scoreModel) + fun ofEvalGraderScoreModel(evalGraderScoreModel: EvalGraderScoreModel) = + TestingCriterion(evalGraderScoreModel = evalGraderScoreModel) } /** @@ -1064,22 +1096,22 @@ private constructor( * A LabelModelGrader object which uses a model to assign labels to each item in the * evaluation. */ - fun visitLabelModel(labelModel: EvalLabelModelGrader): T + fun visitLabelModelGrader(labelModelGrader: LabelModelGrader): T /** * A StringCheckGrader object that performs a string comparison between input and * reference using a specified operation. */ - fun visitStringCheck(stringCheck: EvalStringCheckGrader): T + fun visitStringCheckGrader(stringCheckGrader: StringCheckGrader): T /** A TextSimilarityGrader object which grades text based on similarity metrics. */ - fun visitTextSimilarity(textSimilarity: EvalTextSimilarityGrader): T + fun visitEvalGraderTextSimilarity(evalGraderTextSimilarity: EvalGraderTextSimilarity): T /** A PythonGrader object that runs a python script on the input. */ - fun visitPython(python: Python): T + fun visitEvalGraderPython(evalGraderPython: EvalGraderPython): T /** A ScoreModelGrader object that uses a model to assign a score to the input. */ - fun visitScoreModel(scoreModel: ScoreModel): T + fun visitEvalGraderScoreModel(evalGraderScoreModel: EvalGraderScoreModel): T /** * Maps an unknown variant of [TestingCriterion] to a value of type [T]. @@ -1100,37 +1132,38 @@ private constructor( override fun ObjectCodec.deserialize(node: JsonNode): TestingCriterion { val json = JsonValue.fromJsonNode(node) - val type = json.asObject().getOrNull()?.get("type")?.asString()?.getOrNull() - when (type) { - "label_model" -> { - return tryDeserialize(node, jacksonTypeRef())?.let { - TestingCriterion(labelModel = it, _json = json) - } ?: TestingCriterion(_json = json) - } - "string_check" -> { - return tryDeserialize(node, jacksonTypeRef())?.let { - TestingCriterion(stringCheck = it, _json = json) - } ?: TestingCriterion(_json = json) - } - "text_similarity" -> { - return tryDeserialize(node, jacksonTypeRef()) - ?.let { TestingCriterion(textSimilarity = it, _json = json) } - ?: TestingCriterion(_json = json) - } - "python" -> { - return tryDeserialize(node, jacksonTypeRef())?.let { - TestingCriterion(python = it, _json = json) - } ?: TestingCriterion(_json = json) - } - "score_model" -> { - return tryDeserialize(node, jacksonTypeRef())?.let { - TestingCriterion(scoreModel = it, _json = json) - } ?: TestingCriterion(_json = json) - } + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + TestingCriterion(labelModelGrader = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + TestingCriterion(stringCheckGrader = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + TestingCriterion(evalGraderTextSimilarity = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + TestingCriterion(evalGraderPython = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + TestingCriterion(evalGraderScoreModel = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with + // all the possible variants (e.g. deserializing from boolean). + 0 -> TestingCriterion(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely + // valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() } - - return TestingCriterion(_json = json) } } @@ -1142,42 +1175,77 @@ private constructor( provider: SerializerProvider, ) { when { - value.labelModel != null -> generator.writeObject(value.labelModel) - value.stringCheck != null -> generator.writeObject(value.stringCheck) - value.textSimilarity != null -> generator.writeObject(value.textSimilarity) - value.python != null -> generator.writeObject(value.python) - value.scoreModel != null -> generator.writeObject(value.scoreModel) + value.labelModelGrader != null -> generator.writeObject(value.labelModelGrader) + value.stringCheckGrader != null -> + generator.writeObject(value.stringCheckGrader) + value.evalGraderTextSimilarity != null -> + generator.writeObject(value.evalGraderTextSimilarity) + value.evalGraderPython != null -> generator.writeObject(value.evalGraderPython) + value.evalGraderScoreModel != null -> + generator.writeObject(value.evalGraderScoreModel) value._json != null -> generator.writeObject(value._json) else -> throw IllegalStateException("Invalid TestingCriterion") } } } - /** A PythonGrader object that runs a python script on the input. */ - class Python + /** A TextSimilarityGrader object which grades text based on similarity metrics. */ + class EvalGraderTextSimilarity private constructor( + private val evaluationMetric: JsonField, + private val input: JsonField, private val name: JsonField, - private val source: JsonField, + private val reference: JsonField, private val type: JsonValue, - private val imageTag: JsonField, private val passThreshold: JsonField, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( + @JsonProperty("evaluation_metric") + @ExcludeMissing + evaluationMetric: JsonField = + JsonMissing.of(), + @JsonProperty("input") @ExcludeMissing input: JsonField = JsonMissing.of(), @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), - @JsonProperty("source") + @JsonProperty("reference") @ExcludeMissing - source: JsonField = JsonMissing.of(), + reference: JsonField = JsonMissing.of(), @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), - @JsonProperty("image_tag") - @ExcludeMissing - imageTag: JsonField = JsonMissing.of(), @JsonProperty("pass_threshold") @ExcludeMissing passThreshold: JsonField = JsonMissing.of(), - ) : this(name, source, type, imageTag, passThreshold, mutableMapOf()) + ) : this(evaluationMetric, input, name, reference, type, passThreshold, mutableMapOf()) + + fun toTextSimilarityGrader(): TextSimilarityGrader = + TextSimilarityGrader.builder() + .evaluationMetric(evaluationMetric) + .input(input) + .name(name) + .reference(reference) + .type(type) + .build() + + /** + * The evaluation metric to use. One of `fuzzy_match`, `bleu`, `gleu`, `meteor`, + * `rouge_1`, `rouge_2`, `rouge_3`, `rouge_4`, `rouge_5`, or `rouge_l`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun evaluationMetric(): TextSimilarityGrader.EvaluationMetric = + evaluationMetric.getRequired("evaluation_metric") + + /** + * The text being graded. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun input(): String = input.getRequired("input") /** * The name of the grader. @@ -1189,20 +1257,20 @@ private constructor( fun name(): String = name.getRequired("name") /** - * The source code of the python script. + * The text being graded against. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected * value). */ - fun source(): String = source.getRequired("source") + fun reference(): String = reference.getRequired("reference") /** - * The object type, which is always `python`. + * The type of grader. * * Expected to always return the following: * ```java - * JsonValue.from("python") + * JsonValue.from("text_similarity") * ``` * * However, this method can be useful for debugging and logging (e.g. if the server @@ -1211,42 +1279,48 @@ private constructor( @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type /** - * The image tag to use for the python script. + * The threshold for the score. * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). */ - fun imageTag(): Optional = imageTag.getOptional("image_tag") + fun passThreshold(): Double = passThreshold.getRequired("pass_threshold") /** - * The threshold for the score. + * Returns the raw JSON value of [evaluationMetric]. * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). + * Unlike [evaluationMetric], this method doesn't throw if the JSON field has an + * unexpected type. */ - fun passThreshold(): Optional = passThreshold.getOptional("pass_threshold") + @JsonProperty("evaluation_metric") + @ExcludeMissing + fun _evaluationMetric(): JsonField = + evaluationMetric /** - * Returns the raw JSON value of [name]. + * Returns the raw JSON value of [input]. * - * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [input], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + @JsonProperty("input") @ExcludeMissing fun _input(): JsonField = input /** - * Returns the raw JSON value of [source]. + * Returns the raw JSON value of [name]. * - * Unlike [source], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("source") @ExcludeMissing fun _source(): JsonField = source + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name /** - * Returns the raw JSON value of [imageTag]. + * Returns the raw JSON value of [reference]. * - * Unlike [imageTag], this method doesn't throw if the JSON field has an unexpected + * Unlike [reference], this method doesn't throw if the JSON field has an unexpected * type. */ - @JsonProperty("image_tag") @ExcludeMissing fun _imageTag(): JsonField = imageTag + @JsonProperty("reference") + @ExcludeMissing + fun _reference(): JsonField = reference /** * Returns the raw JSON value of [passThreshold]. @@ -1273,37 +1347,75 @@ private constructor( companion object { /** - * Returns a mutable builder for constructing an instance of [Python]. + * Returns a mutable builder for constructing an instance of + * [EvalGraderTextSimilarity]. * * The following fields are required: * ```java + * .evaluationMetric() + * .input() * .name() - * .source() + * .reference() + * .passThreshold() * ``` */ @JvmStatic fun builder() = Builder() } - /** A builder for [Python]. */ + /** A builder for [EvalGraderTextSimilarity]. */ class Builder internal constructor() { + private var evaluationMetric: JsonField? = + null + private var input: JsonField? = null private var name: JsonField? = null - private var source: JsonField? = null - private var type: JsonValue = JsonValue.from("python") - private var imageTag: JsonField = JsonMissing.of() - private var passThreshold: JsonField = JsonMissing.of() + private var reference: JsonField? = null + private var type: JsonValue = JsonValue.from("text_similarity") + private var passThreshold: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(python: Python) = apply { - name = python.name - source = python.source - type = python.type - imageTag = python.imageTag - passThreshold = python.passThreshold - additionalProperties = python.additionalProperties.toMutableMap() + internal fun from(evalGraderTextSimilarity: EvalGraderTextSimilarity) = apply { + evaluationMetric = evalGraderTextSimilarity.evaluationMetric + input = evalGraderTextSimilarity.input + name = evalGraderTextSimilarity.name + reference = evalGraderTextSimilarity.reference + type = evalGraderTextSimilarity.type + passThreshold = evalGraderTextSimilarity.passThreshold + additionalProperties = + evalGraderTextSimilarity.additionalProperties.toMutableMap() } + /** + * The evaluation metric to use. One of `fuzzy_match`, `bleu`, `gleu`, `meteor`, + * `rouge_1`, `rouge_2`, `rouge_3`, `rouge_4`, `rouge_5`, or `rouge_l`. + */ + fun evaluationMetric(evaluationMetric: TextSimilarityGrader.EvaluationMetric) = + evaluationMetric(JsonField.of(evaluationMetric)) + + /** + * Sets [Builder.evaluationMetric] to an arbitrary JSON value. + * + * You should usually call [Builder.evaluationMetric] with a well-typed + * [TextSimilarityGrader.EvaluationMetric] value instead. This method is primarily + * for setting the field to an undocumented or not yet supported value. + */ + fun evaluationMetric( + evaluationMetric: JsonField + ) = apply { this.evaluationMetric = evaluationMetric } + + /** The text being graded. */ + fun input(input: String) = input(JsonField.of(input)) + + /** + * Sets [Builder.input] to an arbitrary JSON value. + * + * You should usually call [Builder.input] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun input(input: JsonField) = apply { this.input = input } + /** The name of the grader. */ fun name(name: String) = name(JsonField.of(name)) @@ -1316,17 +1428,17 @@ private constructor( */ fun name(name: JsonField) = apply { this.name = name } - /** The source code of the python script. */ - fun source(source: String) = source(JsonField.of(source)) + /** The text being graded against. */ + fun reference(reference: String) = reference(JsonField.of(reference)) /** - * Sets [Builder.source] to an arbitrary JSON value. + * Sets [Builder.reference] to an arbitrary JSON value. * - * You should usually call [Builder.source] with a well-typed [String] value + * You should usually call [Builder.reference] with a well-typed [String] value * instead. This method is primarily for setting the field to an undocumented or not * yet supported value. */ - fun source(source: JsonField) = apply { this.source = source } + fun reference(reference: JsonField) = apply { this.reference = reference } /** * Sets the field to an arbitrary JSON value. @@ -1334,7 +1446,7 @@ private constructor( * It is usually unnecessary to call this method because the field defaults to the * following: * ```java - * JsonValue.from("python") + * JsonValue.from("text_similarity") * ``` * * This method is primarily for setting the field to an undocumented or not yet @@ -1342,18 +1454,6 @@ private constructor( */ fun type(type: JsonValue) = apply { this.type = type } - /** The image tag to use for the python script. */ - fun imageTag(imageTag: String) = imageTag(JsonField.of(imageTag)) - - /** - * Sets [Builder.imageTag] to an arbitrary JSON value. - * - * You should usually call [Builder.imageTag] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun imageTag(imageTag: JsonField) = apply { this.imageTag = imageTag } - /** The threshold for the score. */ fun passThreshold(passThreshold: Double) = passThreshold(JsonField.of(passThreshold)) @@ -1392,44 +1492,49 @@ private constructor( } /** - * Returns an immutable instance of [Python]. + * Returns an immutable instance of [EvalGraderTextSimilarity]. * * Further updates to this [Builder] will not mutate the returned instance. * * The following fields are required: * ```java + * .evaluationMetric() + * .input() * .name() - * .source() + * .reference() + * .passThreshold() * ``` * * @throws IllegalStateException if any required field is unset. */ - fun build(): Python = - Python( + fun build(): EvalGraderTextSimilarity = + EvalGraderTextSimilarity( + checkRequired("evaluationMetric", evaluationMetric), + checkRequired("input", input), checkRequired("name", name), - checkRequired("source", source), + checkRequired("reference", reference), type, - imageTag, - passThreshold, + checkRequired("passThreshold", passThreshold), additionalProperties.toMutableMap(), ) } private var validated: Boolean = false - fun validate(): Python = apply { + fun validate(): EvalGraderTextSimilarity = apply { if (validated) { return@apply } + evaluationMetric().validate() + input() name() - source() + reference() _type().let { - if (it != JsonValue.from("python")) { + if (it != JsonValue.from("text_similarity")) { throw OpenAIInvalidDataException("'type' is invalid, received $it") } } - imageTag() passThreshold() validated = true } @@ -1450,10 +1555,11 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (if (name.asKnown().isPresent) 1 else 0) + - (if (source.asKnown().isPresent) 1 else 0) + - type.let { if (it == JsonValue.from("python")) 1 else 0 } + - (if (imageTag.asKnown().isPresent) 1 else 0) + + (evaluationMetric.asKnown().getOrNull()?.validity() ?: 0) + + (if (input.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (if (reference.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("text_similarity")) 1 else 0 } + (if (passThreshold.asKnown().isPresent) 1 else 0) override fun equals(other: Any?): Boolean { @@ -1461,84 +1567,77 @@ private constructor( return true } - return /* spotless:off */ other is Python && name == other.name && source == other.source && type == other.type && imageTag == other.imageTag && passThreshold == other.passThreshold && additionalProperties == other.additionalProperties /* spotless:on */ + return /* spotless:off */ other is EvalGraderTextSimilarity && evaluationMetric == other.evaluationMetric && input == other.input && name == other.name && reference == other.reference && type == other.type && passThreshold == other.passThreshold && additionalProperties == other.additionalProperties /* spotless:on */ } /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(name, source, type, imageTag, passThreshold, additionalProperties) } + private val hashCode: Int by lazy { Objects.hash(evaluationMetric, input, name, reference, type, passThreshold, additionalProperties) } /* spotless:on */ override fun hashCode(): Int = hashCode override fun toString() = - "Python{name=$name, source=$source, type=$type, imageTag=$imageTag, passThreshold=$passThreshold, additionalProperties=$additionalProperties}" + "EvalGraderTextSimilarity{evaluationMetric=$evaluationMetric, input=$input, name=$name, reference=$reference, type=$type, passThreshold=$passThreshold, additionalProperties=$additionalProperties}" } - /** A ScoreModelGrader object that uses a model to assign a score to the input. */ - class ScoreModel + /** A PythonGrader object that runs a python script on the input. */ + class EvalGraderPython private constructor( - private val input: JsonField>, - private val model: JsonField, private val name: JsonField, + private val source: JsonField, private val type: JsonValue, + private val imageTag: JsonField, private val passThreshold: JsonField, - private val range: JsonField>, - private val samplingParams: JsonValue, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( - @JsonProperty("input") - @ExcludeMissing - input: JsonField> = JsonMissing.of(), - @JsonProperty("model") @ExcludeMissing model: JsonField = JsonMissing.of(), @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("source") + @ExcludeMissing + source: JsonField = JsonMissing.of(), @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + @JsonProperty("image_tag") + @ExcludeMissing + imageTag: JsonField = JsonMissing.of(), @JsonProperty("pass_threshold") @ExcludeMissing passThreshold: JsonField = JsonMissing.of(), - @JsonProperty("range") - @ExcludeMissing - range: JsonField> = JsonMissing.of(), - @JsonProperty("sampling_params") - @ExcludeMissing - samplingParams: JsonValue = JsonMissing.of(), - ) : this(input, model, name, type, passThreshold, range, samplingParams, mutableMapOf()) + ) : this(name, source, type, imageTag, passThreshold, mutableMapOf()) - /** - * The input text. This may include template strings. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected - * value). - */ - fun input(): List = input.getRequired("input") + fun toPythonGrader(): PythonGrader = + PythonGrader.builder() + .name(name) + .source(source) + .type(type) + .imageTag(imageTag) + .build() /** - * The model to use for the evaluation. + * The name of the grader. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected * value). */ - fun model(): String = model.getRequired("model") + fun name(): String = name.getRequired("name") /** - * The name of the grader. + * The source code of the python script. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected * value). */ - fun name(): String = name.getRequired("name") + fun source(): String = source.getRequired("source") /** - * The object type, which is always `score_model`. + * The object type, which is always `python`. * * Expected to always return the following: * ```java - * JsonValue.from("score_model") + * JsonValue.from("python") * ``` * * However, this method can be useful for debugging and logging (e.g. if the server @@ -1547,46 +1646,42 @@ private constructor( @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type /** - * The threshold for the score. + * The image tag to use for the python script. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). */ - fun passThreshold(): Optional = passThreshold.getOptional("pass_threshold") + fun imageTag(): Optional = imageTag.getOptional("image_tag") /** - * The range of the score. Defaults to `[0, 1]`. + * The threshold for the score. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). */ - fun range(): Optional> = range.getOptional("range") - - /** The sampling parameters for the model. */ - @JsonProperty("sampling_params") - @ExcludeMissing - fun _samplingParams(): JsonValue = samplingParams + fun passThreshold(): Optional = passThreshold.getOptional("pass_threshold") /** - * Returns the raw JSON value of [input]. + * Returns the raw JSON value of [name]. * - * Unlike [input], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("input") @ExcludeMissing fun _input(): JsonField> = input + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name /** - * Returns the raw JSON value of [model]. + * Returns the raw JSON value of [source]. * - * Unlike [model], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [source], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("model") @ExcludeMissing fun _model(): JsonField = model + @JsonProperty("source") @ExcludeMissing fun _source(): JsonField = source /** - * Returns the raw JSON value of [name]. + * Returns the raw JSON value of [imageTag]. * - * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [imageTag], this method doesn't throw if the JSON field has an unexpected + * type. */ - @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + @JsonProperty("image_tag") @ExcludeMissing fun _imageTag(): JsonField = imageTag /** * Returns the raw JSON value of [passThreshold]. @@ -1598,13 +1693,6 @@ private constructor( @ExcludeMissing fun _passThreshold(): JsonField = passThreshold - /** - * Returns the raw JSON value of [range]. - * - * Unlike [range], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("range") @ExcludeMissing fun _range(): JsonField> = range - @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { additionalProperties.put(key, value) @@ -1620,80 +1708,37 @@ private constructor( companion object { /** - * Returns a mutable builder for constructing an instance of [ScoreModel]. + * Returns a mutable builder for constructing an instance of [EvalGraderPython]. * * The following fields are required: * ```java - * .input() - * .model() * .name() + * .source() * ``` */ @JvmStatic fun builder() = Builder() } - /** A builder for [ScoreModel]. */ + /** A builder for [EvalGraderPython]. */ class Builder internal constructor() { - private var input: JsonField>? = null - private var model: JsonField? = null private var name: JsonField? = null - private var type: JsonValue = JsonValue.from("score_model") + private var source: JsonField? = null + private var type: JsonValue = JsonValue.from("python") + private var imageTag: JsonField = JsonMissing.of() private var passThreshold: JsonField = JsonMissing.of() - private var range: JsonField>? = null - private var samplingParams: JsonValue = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(scoreModel: ScoreModel) = apply { - input = scoreModel.input.map { it.toMutableList() } - model = scoreModel.model - name = scoreModel.name - type = scoreModel.type - passThreshold = scoreModel.passThreshold - range = scoreModel.range.map { it.toMutableList() } - samplingParams = scoreModel.samplingParams - additionalProperties = scoreModel.additionalProperties.toMutableMap() - } - - /** The input text. This may include template strings. */ - fun input(input: List) = input(JsonField.of(input)) - - /** - * Sets [Builder.input] to an arbitrary JSON value. - * - * You should usually call [Builder.input] with a well-typed `List` value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun input(input: JsonField>) = apply { - this.input = input.map { it.toMutableList() } - } - - /** - * Adds a single [Input] to [Builder.input]. - * - * @throws IllegalStateException if the field was previously set to a non-list. - */ - fun addInput(input: Input) = apply { - this.input = - (this.input ?: JsonField.of(mutableListOf())).also { - checkKnown("input", it).add(input) - } + internal fun from(evalGraderPython: EvalGraderPython) = apply { + name = evalGraderPython.name + source = evalGraderPython.source + type = evalGraderPython.type + imageTag = evalGraderPython.imageTag + passThreshold = evalGraderPython.passThreshold + additionalProperties = evalGraderPython.additionalProperties.toMutableMap() } - /** The model to use for the evaluation. */ - 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) = apply { this.model = model } - /** The name of the grader. */ fun name(name: String) = name(JsonField.of(name)) @@ -1706,8 +1751,410 @@ private constructor( */ fun name(name: JsonField) = apply { this.name = name } + /** The source code of the python script. */ + fun source(source: String) = source(JsonField.of(source)) + /** - * Sets the field to an arbitrary JSON value. + * Sets [Builder.source] to an arbitrary JSON value. + * + * You should usually call [Builder.source] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun source(source: JsonField) = apply { this.source = source } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("python") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + /** The image tag to use for the python script. */ + fun imageTag(imageTag: String) = imageTag(JsonField.of(imageTag)) + + /** + * Sets [Builder.imageTag] to an arbitrary JSON value. + * + * You should usually call [Builder.imageTag] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun imageTag(imageTag: JsonField) = apply { this.imageTag = imageTag } + + /** The threshold for the score. */ + fun passThreshold(passThreshold: Double) = + passThreshold(JsonField.of(passThreshold)) + + /** + * Sets [Builder.passThreshold] to an arbitrary JSON value. + * + * You should usually call [Builder.passThreshold] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun passThreshold(passThreshold: JsonField) = apply { + this.passThreshold = passThreshold + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [EvalGraderPython]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * .source() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): EvalGraderPython = + EvalGraderPython( + checkRequired("name", name), + checkRequired("source", source), + type, + imageTag, + passThreshold, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): EvalGraderPython = apply { + if (validated) { + return@apply + } + + name() + source() + _type().let { + if (it != JsonValue.from("python")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + imageTag() + passThreshold() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (name.asKnown().isPresent) 1 else 0) + + (if (source.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("python")) 1 else 0 } + + (if (imageTag.asKnown().isPresent) 1 else 0) + + (if (passThreshold.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is EvalGraderPython && name == other.name && source == other.source && type == other.type && imageTag == other.imageTag && passThreshold == other.passThreshold && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, source, type, imageTag, passThreshold, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "EvalGraderPython{name=$name, source=$source, type=$type, imageTag=$imageTag, passThreshold=$passThreshold, additionalProperties=$additionalProperties}" + } + + /** A ScoreModelGrader object that uses a model to assign a score to the input. */ + class EvalGraderScoreModel + private constructor( + private val input: JsonField>, + private val model: JsonField, + private val name: JsonField, + private val type: JsonValue, + private val range: JsonField>, + private val samplingParams: JsonValue, + private val passThreshold: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("input") + @ExcludeMissing + input: JsonField> = JsonMissing.of(), + @JsonProperty("model") @ExcludeMissing model: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + @JsonProperty("range") + @ExcludeMissing + range: JsonField> = JsonMissing.of(), + @JsonProperty("sampling_params") + @ExcludeMissing + samplingParams: JsonValue = JsonMissing.of(), + @JsonProperty("pass_threshold") + @ExcludeMissing + passThreshold: JsonField = JsonMissing.of(), + ) : this(input, model, name, type, range, samplingParams, passThreshold, mutableMapOf()) + + fun toScoreModelGrader(): ScoreModelGrader = + ScoreModelGrader.builder() + .input(input) + .model(model) + .name(name) + .type(type) + .range(range) + .samplingParams(samplingParams) + .build() + + /** + * The input text. This may include template strings. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun input(): List = input.getRequired("input") + + /** + * The model to use for the evaluation. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun model(): String = model.getRequired("model") + + /** + * The name of the grader. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun name(): String = name.getRequired("name") + + /** + * The object type, which is always `score_model`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("score_model") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * The range of the score. Defaults to `[0, 1]`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun range(): Optional> = range.getOptional("range") + + /** The sampling parameters for the model. */ + @JsonProperty("sampling_params") + @ExcludeMissing + fun _samplingParams(): JsonValue = samplingParams + + /** + * The threshold for the score. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun passThreshold(): Optional = passThreshold.getOptional("pass_threshold") + + /** + * Returns the raw JSON value of [input]. + * + * Unlike [input], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("input") + @ExcludeMissing + fun _input(): JsonField> = input + + /** + * 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 = model + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [range]. + * + * Unlike [range], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("range") @ExcludeMissing fun _range(): JsonField> = range + + /** + * Returns the raw JSON value of [passThreshold]. + * + * Unlike [passThreshold], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("pass_threshold") + @ExcludeMissing + fun _passThreshold(): JsonField = passThreshold + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [EvalGraderScoreModel]. + * + * The following fields are required: + * ```java + * .input() + * .model() + * .name() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [EvalGraderScoreModel]. */ + class Builder internal constructor() { + + private var input: JsonField>? = null + private var model: JsonField? = null + private var name: JsonField? = null + private var type: JsonValue = JsonValue.from("score_model") + private var range: JsonField>? = null + private var samplingParams: JsonValue = JsonMissing.of() + private var passThreshold: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(evalGraderScoreModel: EvalGraderScoreModel) = apply { + input = evalGraderScoreModel.input.map { it.toMutableList() } + model = evalGraderScoreModel.model + name = evalGraderScoreModel.name + type = evalGraderScoreModel.type + range = evalGraderScoreModel.range.map { it.toMutableList() } + samplingParams = evalGraderScoreModel.samplingParams + passThreshold = evalGraderScoreModel.passThreshold + additionalProperties = evalGraderScoreModel.additionalProperties.toMutableMap() + } + + /** The input text. This may include template strings. */ + fun input(input: List) = input(JsonField.of(input)) + + /** + * Sets [Builder.input] to an arbitrary JSON value. + * + * You should usually call [Builder.input] with a well-typed + * `List` value instead. This method is primarily for + * setting the field to an undocumented or not yet supported value. + */ + fun input(input: JsonField>) = apply { + this.input = input.map { it.toMutableList() } + } + + /** + * Adds a single [ScoreModelGrader.Input] to [Builder.input]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addInput(input: ScoreModelGrader.Input) = apply { + this.input = + (this.input ?: JsonField.of(mutableListOf())).also { + checkKnown("input", it).add(input) + } + } + + /** The model to use for the evaluation. */ + 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) = apply { this.model = model } + + /** The name of the grader. */ + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** + * Sets the field to an arbitrary JSON value. * * It is usually unnecessary to call this method because the field defaults to the * following: @@ -1720,21 +2167,6 @@ private constructor( */ fun type(type: JsonValue) = apply { this.type = type } - /** The threshold for the score. */ - fun passThreshold(passThreshold: Double) = - passThreshold(JsonField.of(passThreshold)) - - /** - * Sets [Builder.passThreshold] to an arbitrary JSON value. - * - * You should usually call [Builder.passThreshold] with a well-typed [Double] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun passThreshold(passThreshold: JsonField) = apply { - this.passThreshold = passThreshold - } - /** The range of the score. Defaults to `[0, 1]`. */ fun range(range: List) = range(JsonField.of(range)) @@ -1766,6 +2198,21 @@ private constructor( this.samplingParams = samplingParams } + /** The threshold for the score. */ + fun passThreshold(passThreshold: Double) = + passThreshold(JsonField.of(passThreshold)) + + /** + * Sets [Builder.passThreshold] to an arbitrary JSON value. + * + * You should usually call [Builder.passThreshold] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun passThreshold(passThreshold: JsonField) = apply { + this.passThreshold = passThreshold + } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() putAllAdditionalProperties(additionalProperties) @@ -1789,7 +2236,7 @@ private constructor( } /** - * Returns an immutable instance of [ScoreModel]. + * Returns an immutable instance of [EvalGraderScoreModel]. * * Further updates to this [Builder] will not mutate the returned instance. * @@ -1802,22 +2249,22 @@ private constructor( * * @throws IllegalStateException if any required field is unset. */ - fun build(): ScoreModel = - ScoreModel( + fun build(): EvalGraderScoreModel = + EvalGraderScoreModel( checkRequired("input", input).map { it.toImmutable() }, checkRequired("model", model), checkRequired("name", name), type, - passThreshold, (range ?: JsonMissing.of()).map { it.toImmutable() }, samplingParams, + passThreshold, additionalProperties.toMutableMap(), ) } private var validated: Boolean = false - fun validate(): ScoreModel = apply { + fun validate(): EvalGraderScoreModel = apply { if (validated) { return@apply } @@ -1830,8 +2277,8 @@ private constructor( throw OpenAIInvalidDataException("'type' is invalid, received $it") } } - passThreshold() range() + passThreshold() validated = true } @@ -1855,1003 +2302,25 @@ private constructor( (if (model.asKnown().isPresent) 1 else 0) + (if (name.asKnown().isPresent) 1 else 0) + type.let { if (it == JsonValue.from("score_model")) 1 else 0 } + - (if (passThreshold.asKnown().isPresent) 1 else 0) + - (range.asKnown().getOrNull()?.size ?: 0) - - /** - * A message input to the model with a role indicating instruction following hierarchy. - * Instructions given with the `developer` or `system` role take precedence over - * instructions given with the `user` role. Messages with the `assistant` role are - * presumed to have been generated by the model in previous interactions. - */ - class Input - private constructor( - private val content: JsonField, - private val role: JsonField, - private val type: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("content") - @ExcludeMissing - content: JsonField = JsonMissing.of(), - @JsonProperty("role") @ExcludeMissing role: JsonField = JsonMissing.of(), - @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), - ) : this(content, role, type, mutableMapOf()) - - /** - * Text inputs to the model - can contain template strings. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected - * value). - */ - fun content(): Content = content.getRequired("content") - - /** - * The role of the message input. One of `user`, `assistant`, `system`, or - * `developer`. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected - * value). - */ - fun role(): Role = role.getRequired("role") - - /** - * The type of the message input. Always `message`. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun type(): Optional = type.getOptional("type") - - /** - * Returns the raw JSON value of [content]. - * - * Unlike [content], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("content") - @ExcludeMissing - fun _content(): JsonField = content - - /** - * Returns the raw JSON value of [role]. - * - * Unlike [role], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("role") @ExcludeMissing fun _role(): JsonField = role - - /** - * Returns the raw JSON value of [type]. - * - * Unlike [type], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** - * Returns a mutable builder for constructing an instance of [Input]. - * - * The following fields are required: - * ```java - * .content() - * .role() - * ``` - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Input]. */ - class Builder internal constructor() { - - private var content: JsonField? = null - private var role: JsonField? = null - private var type: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(input: Input) = apply { - content = input.content - role = input.role - type = input.type - additionalProperties = input.additionalProperties.toMutableMap() - } - - /** Text inputs to the model - can contain template strings. */ - fun content(content: Content) = content(JsonField.of(content)) - - /** - * Sets [Builder.content] to an arbitrary JSON value. - * - * You should usually call [Builder.content] with a well-typed [Content] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun content(content: JsonField) = apply { this.content = content } - - /** Alias for calling [content] with `Content.ofTextInput(textInput)`. */ - fun content(textInput: String) = content(Content.ofTextInput(textInput)) - - /** - * Alias for calling [content] with - * `Content.ofResponseInputText(responseInputText)`. - */ - fun content(responseInputText: ResponseInputText) = - content(Content.ofResponseInputText(responseInputText)) - - /** Alias for calling [content] with `Content.ofOutputText(outputText)`. */ - fun content(outputText: Content.OutputText) = - content(Content.ofOutputText(outputText)) - - /** - * The role of the message input. One of `user`, `assistant`, `system`, or - * `developer`. - */ - fun role(role: Role) = role(JsonField.of(role)) - - /** - * Sets [Builder.role] to an arbitrary JSON value. - * - * You should usually call [Builder.role] with a well-typed [Role] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun role(role: JsonField) = apply { this.role = role } - - /** The type of the message input. Always `message`. */ - fun type(type: Type) = type(JsonField.of(type)) - - /** - * Sets [Builder.type] to an arbitrary JSON value. - * - * You should usually call [Builder.type] with a well-typed [Type] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun type(type: JsonField) = apply { this.type = type } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [Input]. - * - * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .content() - * .role() - * ``` - * - * @throws IllegalStateException if any required field is unset. - */ - fun build(): Input = - Input( - checkRequired("content", content), - checkRequired("role", role), - type, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): Input = apply { - if (validated) { - return@apply - } - - content().validate() - role().validate() - type().ifPresent { it.validate() } - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (content.asKnown().getOrNull()?.validity() ?: 0) + - (role.asKnown().getOrNull()?.validity() ?: 0) + - (type.asKnown().getOrNull()?.validity() ?: 0) - - /** Text inputs to the model - can contain template strings. */ - @JsonDeserialize(using = Content.Deserializer::class) - @JsonSerialize(using = Content.Serializer::class) - class Content - private constructor( - private val textInput: String? = null, - private val responseInputText: ResponseInputText? = null, - private val outputText: OutputText? = null, - private val _json: JsonValue? = null, - ) { - - /** A text input to the model. */ - fun textInput(): Optional = Optional.ofNullable(textInput) - - /** A text input to the model. */ - fun responseInputText(): Optional = - Optional.ofNullable(responseInputText) - - /** A text output from the model. */ - fun outputText(): Optional = Optional.ofNullable(outputText) - - fun isTextInput(): Boolean = textInput != null - - fun isResponseInputText(): Boolean = responseInputText != null - - fun isOutputText(): Boolean = outputText != null - - /** A text input to the model. */ - fun asTextInput(): String = textInput.getOrThrow("textInput") - - /** A text input to the model. */ - fun asResponseInputText(): ResponseInputText = - responseInputText.getOrThrow("responseInputText") - - /** A text output from the model. */ - fun asOutputText(): OutputText = outputText.getOrThrow("outputText") - - fun _json(): Optional = Optional.ofNullable(_json) - - fun accept(visitor: Visitor): T = - when { - textInput != null -> visitor.visitTextInput(textInput) - responseInputText != null -> - visitor.visitResponseInputText(responseInputText) - outputText != null -> visitor.visitOutputText(outputText) - else -> visitor.unknown(_json) - } - - private var validated: Boolean = false - - fun validate(): Content = apply { - if (validated) { - return@apply - } - - accept( - object : Visitor { - override fun visitTextInput(textInput: String) {} - - override fun visitResponseInputText( - responseInputText: ResponseInputText - ) { - responseInputText.validate() - } - - override fun visitOutputText(outputText: OutputText) { - outputText.validate() - } - } - ) - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - accept( - object : Visitor { - override fun visitTextInput(textInput: String) = 1 - - override fun visitResponseInputText( - responseInputText: ResponseInputText - ) = responseInputText.validity() - - override fun visitOutputText(outputText: OutputText) = - outputText.validity() - - override fun unknown(json: JsonValue?) = 0 - } - ) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is Content && textInput == other.textInput && responseInputText == other.responseInputText && outputText == other.outputText /* spotless:on */ - } - - override fun hashCode(): Int = /* spotless:off */ Objects.hash(textInput, responseInputText, outputText) /* spotless:on */ - - override fun toString(): String = - when { - textInput != null -> "Content{textInput=$textInput}" - responseInputText != null -> - "Content{responseInputText=$responseInputText}" - outputText != null -> "Content{outputText=$outputText}" - _json != null -> "Content{_unknown=$_json}" - else -> throw IllegalStateException("Invalid Content") - } - - companion object { - - /** A text input to the model. */ - @JvmStatic - fun ofTextInput(textInput: String) = Content(textInput = textInput) - - /** A text input to the model. */ - @JvmStatic - fun ofResponseInputText(responseInputText: ResponseInputText) = - Content(responseInputText = responseInputText) - - /** A text output from the model. */ - @JvmStatic - fun ofOutputText(outputText: OutputText) = Content(outputText = outputText) - } - - /** - * An interface that defines how to map each variant of [Content] to a value of - * type [T]. - */ - interface Visitor { - - /** A text input to the model. */ - fun visitTextInput(textInput: String): T - - /** A text input to the model. */ - fun visitResponseInputText(responseInputText: ResponseInputText): T - - /** A text output from the model. */ - fun visitOutputText(outputText: OutputText): T - - /** - * Maps an unknown variant of [Content] to a value of type [T]. - * - * An instance of [Content] can contain an unknown variant if it was - * deserialized from data that doesn't match any known variant. For example, - * if the SDK is on an older version than the API, then the API may respond - * with new variants that the SDK is unaware of. - * - * @throws OpenAIInvalidDataException in the default implementation. - */ - fun unknown(json: JsonValue?): T { - throw OpenAIInvalidDataException("Unknown Content: $json") - } - } - - internal class Deserializer : BaseDeserializer(Content::class) { - - override fun ObjectCodec.deserialize(node: JsonNode): Content { - val json = JsonValue.fromJsonNode(node) - - val bestMatches = - sequenceOf( - tryDeserialize(node, jacksonTypeRef()) - ?.let { Content(responseInputText = it, _json = json) }, - tryDeserialize(node, jacksonTypeRef())?.let { - Content(outputText = it, _json = json) - }, - tryDeserialize(node, jacksonTypeRef())?.let { - Content(textInput = it, _json = json) - }, - ) - .filterNotNull() - .allMaxBy { it.validity() } - .toList() - return when (bestMatches.size) { - // This can happen if what we're deserializing is completely - // incompatible with all the possible variants (e.g. deserializing - // from array). - 0 -> Content(_json = json) - 1 -> bestMatches.single() - // If there's more than one match with the highest validity, then - // use the first completely valid match, or simply the first match - // if none are completely valid. - else -> - bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() - } - } - } - - internal class Serializer : BaseSerializer(Content::class) { - - override fun serialize( - value: Content, - generator: JsonGenerator, - provider: SerializerProvider, - ) { - when { - value.textInput != null -> generator.writeObject(value.textInput) - value.responseInputText != null -> - generator.writeObject(value.responseInputText) - value.outputText != null -> generator.writeObject(value.outputText) - value._json != null -> generator.writeObject(value._json) - else -> throw IllegalStateException("Invalid Content") - } - } - } - - /** A text output from the model. */ - class OutputText - private constructor( - private val text: JsonField, - private val type: JsonValue, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("text") - @ExcludeMissing - text: JsonField = JsonMissing.of(), - @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), - ) : this(text, type, mutableMapOf()) - - /** - * The text output from the model. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected - * type or is unexpectedly missing or null (e.g. if the server responded - * with an unexpected value). - */ - fun text(): String = text.getRequired("text") - - /** - * The type of the output text. Always `output_text`. - * - * Expected to always return the following: - * ```java - * JsonValue.from("output_text") - * ``` - * - * However, this method can be useful for debugging and logging (e.g. if the - * server responded with an unexpected value). - */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type - - /** - * Returns the raw JSON value of [text]. - * - * Unlike [text], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("text") @ExcludeMissing fun _text(): JsonField = text - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** - * Returns a mutable builder for constructing an instance of - * [OutputText]. - * - * The following fields are required: - * ```java - * .text() - * ``` - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [OutputText]. */ - class Builder internal constructor() { - - private var text: JsonField? = null - private var type: JsonValue = JsonValue.from("output_text") - private var additionalProperties: MutableMap = - mutableMapOf() - - @JvmSynthetic - internal fun from(outputText: OutputText) = apply { - text = outputText.text - type = outputText.type - additionalProperties = - outputText.additionalProperties.toMutableMap() - } - - /** The text output from the model. */ - fun text(text: String) = text(JsonField.of(text)) - - /** - * Sets [Builder.text] to an arbitrary JSON value. - * - * You should usually call [Builder.text] with a well-typed [String] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun text(text: JsonField) = apply { this.text = text } - - /** - * Sets the field to an arbitrary JSON value. - * - * It is usually unnecessary to call this method because the field - * defaults to the following: - * ```java - * JsonValue.from("output_text") - * ``` - * - * This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun type(type: JsonValue) = apply { this.type = type } - - fun additionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties( - additionalProperties: Map - ) = apply { this.additionalProperties.putAll(additionalProperties) } - - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [OutputText]. - * - * Further updates to this [Builder] will not mutate the returned - * instance. - * - * The following fields are required: - * ```java - * .text() - * ``` - * - * @throws IllegalStateException if any required field is unset. - */ - fun build(): OutputText = - OutputText( - checkRequired("text", text), - type, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): OutputText = apply { - if (validated) { - return@apply - } - - text() - _type().let { - if (it != JsonValue.from("output_text")) { - throw OpenAIInvalidDataException( - "'type' is invalid, received $it" - ) - } - } - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this - * object recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (if (text.asKnown().isPresent) 1 else 0) + - type.let { if (it == JsonValue.from("output_text")) 1 else 0 } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is OutputText && text == other.text && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ - } - - /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(text, type, additionalProperties) } - /* spotless:on */ - - override fun hashCode(): Int = hashCode - - override fun toString() = - "OutputText{text=$text, type=$type, additionalProperties=$additionalProperties}" - } - } - - /** - * The role of the message input. One of `user`, `assistant`, `system`, or - * `developer`. - */ - class Role @JsonCreator private constructor(private val value: JsonField) : - Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that - * doesn't match any known member, and you want to know that value. For example, - * if the SDK is on an older version than the API, then the API may respond with - * new members that the SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue - fun _value(): JsonField = value - - companion object { - - @JvmField val USER = of("user") - - @JvmField val ASSISTANT = of("assistant") - - @JvmField val SYSTEM = of("system") - - @JvmField val DEVELOPER = of("developer") - - @JvmStatic fun of(value: String) = Role(JsonField.of(value)) - } - - /** An enum containing [Role]'s known values. */ - enum class Known { - USER, - ASSISTANT, - SYSTEM, - DEVELOPER, - } - - /** - * An enum containing [Role]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Role] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For - * example, if the SDK is on an older version than the API, then the API may - * respond with new members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - USER, - ASSISTANT, - SYSTEM, - DEVELOPER, - /** - * An enum member indicating that [Role] was instantiated with an unknown - * value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or - * if you want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - USER -> Value.USER - ASSISTANT -> Value.ASSISTANT - SYSTEM -> Value.SYSTEM - DEVELOPER -> Value.DEVELOPER - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known - * and don't want to throw for the unknown case. - * - * @throws OpenAIInvalidDataException if this class instance's value is a not a - * known member. - */ - fun known(): Known = - when (this) { - USER -> Known.USER - ASSISTANT -> Known.ASSISTANT - SYSTEM -> Known.SYSTEM - DEVELOPER -> Known.DEVELOPER - else -> throw OpenAIInvalidDataException("Unknown Role: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for - * debugging and generally doesn't throw. - * - * @throws OpenAIInvalidDataException if this class instance's value does not - * have the expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - OpenAIInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): Role = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is Role && value == other.value /* spotless:on */ - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - /** The type of the message input. Always `message`. */ - class Type @JsonCreator private constructor(private val value: JsonField) : - Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that - * doesn't match any known member, and you want to know that value. For example, - * if the SDK is on an older version than the API, then the API may respond with - * new members that the SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue - fun _value(): JsonField = value - - companion object { - - @JvmField val MESSAGE = of("message") - - @JvmStatic fun of(value: String) = Type(JsonField.of(value)) - } - - /** An enum containing [Type]'s known values. */ - enum class Known { - MESSAGE - } - - /** - * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Type] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For - * example, if the SDK is on an older version than the API, then the API may - * respond with new members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - MESSAGE, - /** - * An enum member indicating that [Type] was instantiated with an unknown - * value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or - * if you want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - MESSAGE -> Value.MESSAGE - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known - * and don't want to throw for the unknown case. - * - * @throws OpenAIInvalidDataException if this class instance's value is a not a - * known member. - */ - fun known(): Known = - when (this) { - MESSAGE -> Known.MESSAGE - else -> throw OpenAIInvalidDataException("Unknown Type: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for - * debugging and generally doesn't throw. - * - * @throws OpenAIInvalidDataException if this class instance's value does not - * have the expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - OpenAIInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): Type = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is Type && value == other.value /* spotless:on */ - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is Input && content == other.content && role == other.role && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ - } - - /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(content, role, type, additionalProperties) } - /* spotless:on */ - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Input{content=$content, role=$role, type=$type, additionalProperties=$additionalProperties}" - } + (range.asKnown().getOrNull()?.size ?: 0) + + (if (passThreshold.asKnown().isPresent) 1 else 0) override fun equals(other: Any?): Boolean { if (this === other) { return true } - return /* spotless:off */ other is ScoreModel && input == other.input && model == other.model && name == other.name && type == other.type && passThreshold == other.passThreshold && range == other.range && samplingParams == other.samplingParams && additionalProperties == other.additionalProperties /* spotless:on */ + return /* spotless:off */ other is EvalGraderScoreModel && input == other.input && model == other.model && name == other.name && type == other.type && range == other.range && samplingParams == other.samplingParams && passThreshold == other.passThreshold && additionalProperties == other.additionalProperties /* spotless:on */ } /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(input, model, name, type, passThreshold, range, samplingParams, additionalProperties) } + private val hashCode: Int by lazy { Objects.hash(input, model, name, type, range, samplingParams, passThreshold, additionalProperties) } /* spotless:on */ override fun hashCode(): Int = hashCode override fun toString() = - "ScoreModel{input=$input, model=$model, name=$name, type=$type, passThreshold=$passThreshold, range=$range, samplingParams=$samplingParams, additionalProperties=$additionalProperties}" + "EvalGraderScoreModel{input=$input, model=$model, name=$name, type=$type, range=$range, samplingParams=$samplingParams, passThreshold=$passThreshold, additionalProperties=$additionalProperties}" } } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalRetrieveParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalRetrieveParams.kt index 63111243..3a411a0b 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalRetrieveParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalRetrieveParams.kt @@ -3,20 +3,21 @@ package com.openai.models.evals import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** Get an evaluation by ID. */ class EvalRetrieveParams private constructor( - private val evalId: String, + private val evalId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun evalId(): String = evalId + fun evalId(): Optional = Optional.ofNullable(evalId) fun _additionalHeaders(): Headers = additionalHeaders @@ -26,14 +27,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [EvalRetrieveParams]. - * - * The following fields are required: - * ```java - * .evalId() - * ``` - */ + @JvmStatic fun none(): EvalRetrieveParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [EvalRetrieveParams]. */ @JvmStatic fun builder() = Builder() } @@ -51,7 +47,10 @@ private constructor( additionalQueryParams = evalRetrieveParams.additionalQueryParams.toBuilder() } - fun evalId(evalId: String) = apply { this.evalId = evalId } + fun evalId(evalId: String?) = apply { this.evalId = evalId } + + /** Alias for calling [Builder.evalId] with `evalId.orElse(null)`. */ + fun evalId(evalId: Optional) = evalId(evalId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -155,25 +154,14 @@ private constructor( * Returns an immutable instance of [EvalRetrieveParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .evalId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): EvalRetrieveParams = - EvalRetrieveParams( - checkRequired("evalId", evalId), - additionalHeaders.build(), - additionalQueryParams.build(), - ) + EvalRetrieveParams(evalId, additionalHeaders.build(), additionalQueryParams.build()) } fun _pathParam(index: Int): String = when (index) { - 0 -> evalId + 0 -> evalId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalRetrieveResponse.kt b/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalRetrieveResponse.kt index f420c699..56c27978 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalRetrieveResponse.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalRetrieveResponse.kt @@ -15,7 +15,6 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import com.openai.core.BaseDeserializer import com.openai.core.BaseSerializer -import com.openai.core.Enum import com.openai.core.ExcludeMissing import com.openai.core.JsonField import com.openai.core.JsonMissing @@ -26,7 +25,11 @@ import com.openai.core.checkRequired import com.openai.core.getOrThrow import com.openai.core.toImmutable import com.openai.errors.OpenAIInvalidDataException -import com.openai.models.responses.ResponseInputText +import com.openai.models.graders.gradermodels.LabelModelGrader +import com.openai.models.graders.gradermodels.PythonGrader +import com.openai.models.graders.gradermodels.ScoreModelGrader +import com.openai.models.graders.gradermodels.StringCheckGrader +import com.openai.models.graders.gradermodels.TextSimilarityGrader import java.util.Collections import java.util.Objects import java.util.Optional @@ -388,34 +391,43 @@ private constructor( } /** - * Alias for calling [addTestingCriterion] with `TestingCriterion.ofLabelModel(labelModel)`. + * Alias for calling [addTestingCriterion] with + * `TestingCriterion.ofLabelModelGrader(labelModelGrader)`. */ - fun addTestingCriterion(labelModel: EvalLabelModelGrader) = - addTestingCriterion(TestingCriterion.ofLabelModel(labelModel)) + fun addTestingCriterion(labelModelGrader: LabelModelGrader) = + addTestingCriterion(TestingCriterion.ofLabelModelGrader(labelModelGrader)) /** * Alias for calling [addTestingCriterion] with - * `TestingCriterion.ofStringCheck(stringCheck)`. + * `TestingCriterion.ofStringCheckGrader(stringCheckGrader)`. */ - fun addTestingCriterion(stringCheck: EvalStringCheckGrader) = - addTestingCriterion(TestingCriterion.ofStringCheck(stringCheck)) + fun addTestingCriterion(stringCheckGrader: StringCheckGrader) = + addTestingCriterion(TestingCriterion.ofStringCheckGrader(stringCheckGrader)) /** * Alias for calling [addTestingCriterion] with - * `TestingCriterion.ofTextSimilarity(textSimilarity)`. + * `TestingCriterion.ofEvalGraderTextSimilarity(evalGraderTextSimilarity)`. */ - fun addTestingCriterion(textSimilarity: EvalTextSimilarityGrader) = - addTestingCriterion(TestingCriterion.ofTextSimilarity(textSimilarity)) + fun addTestingCriterion( + evalGraderTextSimilarity: TestingCriterion.EvalGraderTextSimilarity + ) = + addTestingCriterion( + TestingCriterion.ofEvalGraderTextSimilarity(evalGraderTextSimilarity) + ) - /** Alias for calling [addTestingCriterion] with `TestingCriterion.ofPython(python)`. */ - fun addTestingCriterion(python: TestingCriterion.Python) = - addTestingCriterion(TestingCriterion.ofPython(python)) + /** + * Alias for calling [addTestingCriterion] with + * `TestingCriterion.ofEvalGraderPython(evalGraderPython)`. + */ + fun addTestingCriterion(evalGraderPython: TestingCriterion.EvalGraderPython) = + addTestingCriterion(TestingCriterion.ofEvalGraderPython(evalGraderPython)) /** - * Alias for calling [addTestingCriterion] with `TestingCriterion.ofScoreModel(scoreModel)`. + * Alias for calling [addTestingCriterion] with + * `TestingCriterion.ofEvalGraderScoreModel(evalGraderScoreModel)`. */ - fun addTestingCriterion(scoreModel: TestingCriterion.ScoreModel) = - addTestingCriterion(TestingCriterion.ofScoreModel(scoreModel)) + fun addTestingCriterion(evalGraderScoreModel: TestingCriterion.EvalGraderScoreModel) = + addTestingCriterion(TestingCriterion.ofEvalGraderScoreModel(evalGraderScoreModel)) fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() @@ -860,11 +872,11 @@ private constructor( @JsonSerialize(using = TestingCriterion.Serializer::class) class TestingCriterion private constructor( - private val labelModel: EvalLabelModelGrader? = null, - private val stringCheck: EvalStringCheckGrader? = null, - private val textSimilarity: EvalTextSimilarityGrader? = null, - private val python: Python? = null, - private val scoreModel: ScoreModel? = null, + private val labelModelGrader: LabelModelGrader? = null, + private val stringCheckGrader: StringCheckGrader? = null, + private val evalGraderTextSimilarity: EvalGraderTextSimilarity? = null, + private val evalGraderPython: EvalGraderPython? = null, + private val evalGraderScoreModel: EvalGraderScoreModel? = null, private val _json: JsonValue? = null, ) { @@ -872,65 +884,71 @@ private constructor( * A LabelModelGrader object which uses a model to assign labels to each item in the * evaluation. */ - fun labelModel(): Optional = Optional.ofNullable(labelModel) + fun labelModelGrader(): Optional = Optional.ofNullable(labelModelGrader) /** * A StringCheckGrader object that performs a string comparison between input and reference * using a specified operation. */ - fun stringCheck(): Optional = Optional.ofNullable(stringCheck) + fun stringCheckGrader(): Optional = + Optional.ofNullable(stringCheckGrader) /** A TextSimilarityGrader object which grades text based on similarity metrics. */ - fun textSimilarity(): Optional = - Optional.ofNullable(textSimilarity) + fun evalGraderTextSimilarity(): Optional = + Optional.ofNullable(evalGraderTextSimilarity) /** A PythonGrader object that runs a python script on the input. */ - fun python(): Optional = Optional.ofNullable(python) + fun evalGraderPython(): Optional = Optional.ofNullable(evalGraderPython) /** A ScoreModelGrader object that uses a model to assign a score to the input. */ - fun scoreModel(): Optional = Optional.ofNullable(scoreModel) + fun evalGraderScoreModel(): Optional = + Optional.ofNullable(evalGraderScoreModel) - fun isLabelModel(): Boolean = labelModel != null + fun isLabelModelGrader(): Boolean = labelModelGrader != null - fun isStringCheck(): Boolean = stringCheck != null + fun isStringCheckGrader(): Boolean = stringCheckGrader != null - fun isTextSimilarity(): Boolean = textSimilarity != null + fun isEvalGraderTextSimilarity(): Boolean = evalGraderTextSimilarity != null - fun isPython(): Boolean = python != null + fun isEvalGraderPython(): Boolean = evalGraderPython != null - fun isScoreModel(): Boolean = scoreModel != null + fun isEvalGraderScoreModel(): Boolean = evalGraderScoreModel != null /** * A LabelModelGrader object which uses a model to assign labels to each item in the * evaluation. */ - fun asLabelModel(): EvalLabelModelGrader = labelModel.getOrThrow("labelModel") + fun asLabelModelGrader(): LabelModelGrader = labelModelGrader.getOrThrow("labelModelGrader") /** * A StringCheckGrader object that performs a string comparison between input and reference * using a specified operation. */ - fun asStringCheck(): EvalStringCheckGrader = stringCheck.getOrThrow("stringCheck") + fun asStringCheckGrader(): StringCheckGrader = + stringCheckGrader.getOrThrow("stringCheckGrader") /** A TextSimilarityGrader object which grades text based on similarity metrics. */ - fun asTextSimilarity(): EvalTextSimilarityGrader = - textSimilarity.getOrThrow("textSimilarity") + fun asEvalGraderTextSimilarity(): EvalGraderTextSimilarity = + evalGraderTextSimilarity.getOrThrow("evalGraderTextSimilarity") /** A PythonGrader object that runs a python script on the input. */ - fun asPython(): Python = python.getOrThrow("python") + fun asEvalGraderPython(): EvalGraderPython = evalGraderPython.getOrThrow("evalGraderPython") /** A ScoreModelGrader object that uses a model to assign a score to the input. */ - fun asScoreModel(): ScoreModel = scoreModel.getOrThrow("scoreModel") + fun asEvalGraderScoreModel(): EvalGraderScoreModel = + evalGraderScoreModel.getOrThrow("evalGraderScoreModel") fun _json(): Optional = Optional.ofNullable(_json) fun accept(visitor: Visitor): T = when { - labelModel != null -> visitor.visitLabelModel(labelModel) - stringCheck != null -> visitor.visitStringCheck(stringCheck) - textSimilarity != null -> visitor.visitTextSimilarity(textSimilarity) - python != null -> visitor.visitPython(python) - scoreModel != null -> visitor.visitScoreModel(scoreModel) + labelModelGrader != null -> visitor.visitLabelModelGrader(labelModelGrader) + stringCheckGrader != null -> visitor.visitStringCheckGrader(stringCheckGrader) + evalGraderTextSimilarity != null -> + visitor.visitEvalGraderTextSimilarity(evalGraderTextSimilarity) + evalGraderPython != null -> visitor.visitEvalGraderPython(evalGraderPython) + evalGraderScoreModel != null -> + visitor.visitEvalGraderScoreModel(evalGraderScoreModel) else -> visitor.unknown(_json) } @@ -943,24 +961,28 @@ private constructor( accept( object : Visitor { - override fun visitLabelModel(labelModel: EvalLabelModelGrader) { - labelModel.validate() + override fun visitLabelModelGrader(labelModelGrader: LabelModelGrader) { + labelModelGrader.validate() } - override fun visitStringCheck(stringCheck: EvalStringCheckGrader) { - stringCheck.validate() + override fun visitStringCheckGrader(stringCheckGrader: StringCheckGrader) { + stringCheckGrader.validate() } - override fun visitTextSimilarity(textSimilarity: EvalTextSimilarityGrader) { - textSimilarity.validate() + override fun visitEvalGraderTextSimilarity( + evalGraderTextSimilarity: EvalGraderTextSimilarity + ) { + evalGraderTextSimilarity.validate() } - override fun visitPython(python: Python) { - python.validate() + override fun visitEvalGraderPython(evalGraderPython: EvalGraderPython) { + evalGraderPython.validate() } - override fun visitScoreModel(scoreModel: ScoreModel) { - scoreModel.validate() + override fun visitEvalGraderScoreModel( + evalGraderScoreModel: EvalGraderScoreModel + ) { + evalGraderScoreModel.validate() } } ) @@ -985,18 +1007,22 @@ private constructor( internal fun validity(): Int = accept( object : Visitor { - override fun visitLabelModel(labelModel: EvalLabelModelGrader) = - labelModel.validity() + override fun visitLabelModelGrader(labelModelGrader: LabelModelGrader) = + labelModelGrader.validity() - override fun visitStringCheck(stringCheck: EvalStringCheckGrader) = - stringCheck.validity() + override fun visitStringCheckGrader(stringCheckGrader: StringCheckGrader) = + stringCheckGrader.validity() - override fun visitTextSimilarity(textSimilarity: EvalTextSimilarityGrader) = - textSimilarity.validity() + override fun visitEvalGraderTextSimilarity( + evalGraderTextSimilarity: EvalGraderTextSimilarity + ) = evalGraderTextSimilarity.validity() - override fun visitPython(python: Python) = python.validity() + override fun visitEvalGraderPython(evalGraderPython: EvalGraderPython) = + evalGraderPython.validity() - override fun visitScoreModel(scoreModel: ScoreModel) = scoreModel.validity() + override fun visitEvalGraderScoreModel( + evalGraderScoreModel: EvalGraderScoreModel + ) = evalGraderScoreModel.validity() override fun unknown(json: JsonValue?) = 0 } @@ -1007,18 +1033,21 @@ private constructor( return true } - return /* spotless:off */ other is TestingCriterion && labelModel == other.labelModel && stringCheck == other.stringCheck && textSimilarity == other.textSimilarity && python == other.python && scoreModel == other.scoreModel /* spotless:on */ + return /* spotless:off */ other is TestingCriterion && labelModelGrader == other.labelModelGrader && stringCheckGrader == other.stringCheckGrader && evalGraderTextSimilarity == other.evalGraderTextSimilarity && evalGraderPython == other.evalGraderPython && evalGraderScoreModel == other.evalGraderScoreModel /* spotless:on */ } - override fun hashCode(): Int = /* spotless:off */ Objects.hash(labelModel, stringCheck, textSimilarity, python, scoreModel) /* spotless:on */ + override fun hashCode(): Int = /* spotless:off */ Objects.hash(labelModelGrader, stringCheckGrader, evalGraderTextSimilarity, evalGraderPython, evalGraderScoreModel) /* spotless:on */ override fun toString(): String = when { - labelModel != null -> "TestingCriterion{labelModel=$labelModel}" - stringCheck != null -> "TestingCriterion{stringCheck=$stringCheck}" - textSimilarity != null -> "TestingCriterion{textSimilarity=$textSimilarity}" - python != null -> "TestingCriterion{python=$python}" - scoreModel != null -> "TestingCriterion{scoreModel=$scoreModel}" + labelModelGrader != null -> "TestingCriterion{labelModelGrader=$labelModelGrader}" + stringCheckGrader != null -> + "TestingCriterion{stringCheckGrader=$stringCheckGrader}" + evalGraderTextSimilarity != null -> + "TestingCriterion{evalGraderTextSimilarity=$evalGraderTextSimilarity}" + evalGraderPython != null -> "TestingCriterion{evalGraderPython=$evalGraderPython}" + evalGraderScoreModel != null -> + "TestingCriterion{evalGraderScoreModel=$evalGraderScoreModel}" _json != null -> "TestingCriterion{_unknown=$_json}" else -> throw IllegalStateException("Invalid TestingCriterion") } @@ -1030,28 +1059,31 @@ private constructor( * evaluation. */ @JvmStatic - fun ofLabelModel(labelModel: EvalLabelModelGrader) = - TestingCriterion(labelModel = labelModel) + fun ofLabelModelGrader(labelModelGrader: LabelModelGrader) = + TestingCriterion(labelModelGrader = labelModelGrader) /** * A StringCheckGrader object that performs a string comparison between input and * reference using a specified operation. */ @JvmStatic - fun ofStringCheck(stringCheck: EvalStringCheckGrader) = - TestingCriterion(stringCheck = stringCheck) + fun ofStringCheckGrader(stringCheckGrader: StringCheckGrader) = + TestingCriterion(stringCheckGrader = stringCheckGrader) /** A TextSimilarityGrader object which grades text based on similarity metrics. */ @JvmStatic - fun ofTextSimilarity(textSimilarity: EvalTextSimilarityGrader) = - TestingCriterion(textSimilarity = textSimilarity) + fun ofEvalGraderTextSimilarity(evalGraderTextSimilarity: EvalGraderTextSimilarity) = + TestingCriterion(evalGraderTextSimilarity = evalGraderTextSimilarity) /** A PythonGrader object that runs a python script on the input. */ - @JvmStatic fun ofPython(python: Python) = TestingCriterion(python = python) + @JvmStatic + fun ofEvalGraderPython(evalGraderPython: EvalGraderPython) = + TestingCriterion(evalGraderPython = evalGraderPython) /** A ScoreModelGrader object that uses a model to assign a score to the input. */ @JvmStatic - fun ofScoreModel(scoreModel: ScoreModel) = TestingCriterion(scoreModel = scoreModel) + fun ofEvalGraderScoreModel(evalGraderScoreModel: EvalGraderScoreModel) = + TestingCriterion(evalGraderScoreModel = evalGraderScoreModel) } /** @@ -1064,22 +1096,22 @@ private constructor( * A LabelModelGrader object which uses a model to assign labels to each item in the * evaluation. */ - fun visitLabelModel(labelModel: EvalLabelModelGrader): T + fun visitLabelModelGrader(labelModelGrader: LabelModelGrader): T /** * A StringCheckGrader object that performs a string comparison between input and * reference using a specified operation. */ - fun visitStringCheck(stringCheck: EvalStringCheckGrader): T + fun visitStringCheckGrader(stringCheckGrader: StringCheckGrader): T /** A TextSimilarityGrader object which grades text based on similarity metrics. */ - fun visitTextSimilarity(textSimilarity: EvalTextSimilarityGrader): T + fun visitEvalGraderTextSimilarity(evalGraderTextSimilarity: EvalGraderTextSimilarity): T /** A PythonGrader object that runs a python script on the input. */ - fun visitPython(python: Python): T + fun visitEvalGraderPython(evalGraderPython: EvalGraderPython): T /** A ScoreModelGrader object that uses a model to assign a score to the input. */ - fun visitScoreModel(scoreModel: ScoreModel): T + fun visitEvalGraderScoreModel(evalGraderScoreModel: EvalGraderScoreModel): T /** * Maps an unknown variant of [TestingCriterion] to a value of type [T]. @@ -1100,37 +1132,38 @@ private constructor( override fun ObjectCodec.deserialize(node: JsonNode): TestingCriterion { val json = JsonValue.fromJsonNode(node) - val type = json.asObject().getOrNull()?.get("type")?.asString()?.getOrNull() - when (type) { - "label_model" -> { - return tryDeserialize(node, jacksonTypeRef())?.let { - TestingCriterion(labelModel = it, _json = json) - } ?: TestingCriterion(_json = json) - } - "string_check" -> { - return tryDeserialize(node, jacksonTypeRef())?.let { - TestingCriterion(stringCheck = it, _json = json) - } ?: TestingCriterion(_json = json) - } - "text_similarity" -> { - return tryDeserialize(node, jacksonTypeRef()) - ?.let { TestingCriterion(textSimilarity = it, _json = json) } - ?: TestingCriterion(_json = json) - } - "python" -> { - return tryDeserialize(node, jacksonTypeRef())?.let { - TestingCriterion(python = it, _json = json) - } ?: TestingCriterion(_json = json) - } - "score_model" -> { - return tryDeserialize(node, jacksonTypeRef())?.let { - TestingCriterion(scoreModel = it, _json = json) - } ?: TestingCriterion(_json = json) - } + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + TestingCriterion(labelModelGrader = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + TestingCriterion(stringCheckGrader = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + TestingCriterion(evalGraderTextSimilarity = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + TestingCriterion(evalGraderPython = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + TestingCriterion(evalGraderScoreModel = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with + // all the possible variants (e.g. deserializing from boolean). + 0 -> TestingCriterion(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely + // valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() } - - return TestingCriterion(_json = json) } } @@ -1142,42 +1175,77 @@ private constructor( provider: SerializerProvider, ) { when { - value.labelModel != null -> generator.writeObject(value.labelModel) - value.stringCheck != null -> generator.writeObject(value.stringCheck) - value.textSimilarity != null -> generator.writeObject(value.textSimilarity) - value.python != null -> generator.writeObject(value.python) - value.scoreModel != null -> generator.writeObject(value.scoreModel) + value.labelModelGrader != null -> generator.writeObject(value.labelModelGrader) + value.stringCheckGrader != null -> + generator.writeObject(value.stringCheckGrader) + value.evalGraderTextSimilarity != null -> + generator.writeObject(value.evalGraderTextSimilarity) + value.evalGraderPython != null -> generator.writeObject(value.evalGraderPython) + value.evalGraderScoreModel != null -> + generator.writeObject(value.evalGraderScoreModel) value._json != null -> generator.writeObject(value._json) else -> throw IllegalStateException("Invalid TestingCriterion") } } } - /** A PythonGrader object that runs a python script on the input. */ - class Python + /** A TextSimilarityGrader object which grades text based on similarity metrics. */ + class EvalGraderTextSimilarity private constructor( + private val evaluationMetric: JsonField, + private val input: JsonField, private val name: JsonField, - private val source: JsonField, + private val reference: JsonField, private val type: JsonValue, - private val imageTag: JsonField, private val passThreshold: JsonField, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( + @JsonProperty("evaluation_metric") + @ExcludeMissing + evaluationMetric: JsonField = + JsonMissing.of(), + @JsonProperty("input") @ExcludeMissing input: JsonField = JsonMissing.of(), @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), - @JsonProperty("source") + @JsonProperty("reference") @ExcludeMissing - source: JsonField = JsonMissing.of(), + reference: JsonField = JsonMissing.of(), @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), - @JsonProperty("image_tag") - @ExcludeMissing - imageTag: JsonField = JsonMissing.of(), @JsonProperty("pass_threshold") @ExcludeMissing passThreshold: JsonField = JsonMissing.of(), - ) : this(name, source, type, imageTag, passThreshold, mutableMapOf()) + ) : this(evaluationMetric, input, name, reference, type, passThreshold, mutableMapOf()) + + fun toTextSimilarityGrader(): TextSimilarityGrader = + TextSimilarityGrader.builder() + .evaluationMetric(evaluationMetric) + .input(input) + .name(name) + .reference(reference) + .type(type) + .build() + + /** + * The evaluation metric to use. One of `fuzzy_match`, `bleu`, `gleu`, `meteor`, + * `rouge_1`, `rouge_2`, `rouge_3`, `rouge_4`, `rouge_5`, or `rouge_l`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun evaluationMetric(): TextSimilarityGrader.EvaluationMetric = + evaluationMetric.getRequired("evaluation_metric") + + /** + * The text being graded. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun input(): String = input.getRequired("input") /** * The name of the grader. @@ -1189,20 +1257,20 @@ private constructor( fun name(): String = name.getRequired("name") /** - * The source code of the python script. + * The text being graded against. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected * value). */ - fun source(): String = source.getRequired("source") + fun reference(): String = reference.getRequired("reference") /** - * The object type, which is always `python`. + * The type of grader. * * Expected to always return the following: * ```java - * JsonValue.from("python") + * JsonValue.from("text_similarity") * ``` * * However, this method can be useful for debugging and logging (e.g. if the server @@ -1211,42 +1279,48 @@ private constructor( @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type /** - * The image tag to use for the python script. + * The threshold for the score. * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). */ - fun imageTag(): Optional = imageTag.getOptional("image_tag") + fun passThreshold(): Double = passThreshold.getRequired("pass_threshold") /** - * The threshold for the score. + * Returns the raw JSON value of [evaluationMetric]. * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). + * Unlike [evaluationMetric], this method doesn't throw if the JSON field has an + * unexpected type. */ - fun passThreshold(): Optional = passThreshold.getOptional("pass_threshold") + @JsonProperty("evaluation_metric") + @ExcludeMissing + fun _evaluationMetric(): JsonField = + evaluationMetric /** - * Returns the raw JSON value of [name]. + * Returns the raw JSON value of [input]. * - * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [input], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + @JsonProperty("input") @ExcludeMissing fun _input(): JsonField = input /** - * Returns the raw JSON value of [source]. + * Returns the raw JSON value of [name]. * - * Unlike [source], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("source") @ExcludeMissing fun _source(): JsonField = source + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name /** - * Returns the raw JSON value of [imageTag]. + * Returns the raw JSON value of [reference]. * - * Unlike [imageTag], this method doesn't throw if the JSON field has an unexpected + * Unlike [reference], this method doesn't throw if the JSON field has an unexpected * type. */ - @JsonProperty("image_tag") @ExcludeMissing fun _imageTag(): JsonField = imageTag + @JsonProperty("reference") + @ExcludeMissing + fun _reference(): JsonField = reference /** * Returns the raw JSON value of [passThreshold]. @@ -1273,37 +1347,75 @@ private constructor( companion object { /** - * Returns a mutable builder for constructing an instance of [Python]. + * Returns a mutable builder for constructing an instance of + * [EvalGraderTextSimilarity]. * * The following fields are required: * ```java + * .evaluationMetric() + * .input() * .name() - * .source() + * .reference() + * .passThreshold() * ``` */ @JvmStatic fun builder() = Builder() } - /** A builder for [Python]. */ + /** A builder for [EvalGraderTextSimilarity]. */ class Builder internal constructor() { + private var evaluationMetric: JsonField? = + null + private var input: JsonField? = null private var name: JsonField? = null - private var source: JsonField? = null - private var type: JsonValue = JsonValue.from("python") - private var imageTag: JsonField = JsonMissing.of() - private var passThreshold: JsonField = JsonMissing.of() + private var reference: JsonField? = null + private var type: JsonValue = JsonValue.from("text_similarity") + private var passThreshold: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(python: Python) = apply { - name = python.name - source = python.source - type = python.type - imageTag = python.imageTag - passThreshold = python.passThreshold - additionalProperties = python.additionalProperties.toMutableMap() + internal fun from(evalGraderTextSimilarity: EvalGraderTextSimilarity) = apply { + evaluationMetric = evalGraderTextSimilarity.evaluationMetric + input = evalGraderTextSimilarity.input + name = evalGraderTextSimilarity.name + reference = evalGraderTextSimilarity.reference + type = evalGraderTextSimilarity.type + passThreshold = evalGraderTextSimilarity.passThreshold + additionalProperties = + evalGraderTextSimilarity.additionalProperties.toMutableMap() } + /** + * The evaluation metric to use. One of `fuzzy_match`, `bleu`, `gleu`, `meteor`, + * `rouge_1`, `rouge_2`, `rouge_3`, `rouge_4`, `rouge_5`, or `rouge_l`. + */ + fun evaluationMetric(evaluationMetric: TextSimilarityGrader.EvaluationMetric) = + evaluationMetric(JsonField.of(evaluationMetric)) + + /** + * Sets [Builder.evaluationMetric] to an arbitrary JSON value. + * + * You should usually call [Builder.evaluationMetric] with a well-typed + * [TextSimilarityGrader.EvaluationMetric] value instead. This method is primarily + * for setting the field to an undocumented or not yet supported value. + */ + fun evaluationMetric( + evaluationMetric: JsonField + ) = apply { this.evaluationMetric = evaluationMetric } + + /** The text being graded. */ + fun input(input: String) = input(JsonField.of(input)) + + /** + * Sets [Builder.input] to an arbitrary JSON value. + * + * You should usually call [Builder.input] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun input(input: JsonField) = apply { this.input = input } + /** The name of the grader. */ fun name(name: String) = name(JsonField.of(name)) @@ -1316,17 +1428,17 @@ private constructor( */ fun name(name: JsonField) = apply { this.name = name } - /** The source code of the python script. */ - fun source(source: String) = source(JsonField.of(source)) + /** The text being graded against. */ + fun reference(reference: String) = reference(JsonField.of(reference)) /** - * Sets [Builder.source] to an arbitrary JSON value. + * Sets [Builder.reference] to an arbitrary JSON value. * - * You should usually call [Builder.source] with a well-typed [String] value + * You should usually call [Builder.reference] with a well-typed [String] value * instead. This method is primarily for setting the field to an undocumented or not * yet supported value. */ - fun source(source: JsonField) = apply { this.source = source } + fun reference(reference: JsonField) = apply { this.reference = reference } /** * Sets the field to an arbitrary JSON value. @@ -1334,7 +1446,7 @@ private constructor( * It is usually unnecessary to call this method because the field defaults to the * following: * ```java - * JsonValue.from("python") + * JsonValue.from("text_similarity") * ``` * * This method is primarily for setting the field to an undocumented or not yet @@ -1342,18 +1454,6 @@ private constructor( */ fun type(type: JsonValue) = apply { this.type = type } - /** The image tag to use for the python script. */ - fun imageTag(imageTag: String) = imageTag(JsonField.of(imageTag)) - - /** - * Sets [Builder.imageTag] to an arbitrary JSON value. - * - * You should usually call [Builder.imageTag] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun imageTag(imageTag: JsonField) = apply { this.imageTag = imageTag } - /** The threshold for the score. */ fun passThreshold(passThreshold: Double) = passThreshold(JsonField.of(passThreshold)) @@ -1392,44 +1492,49 @@ private constructor( } /** - * Returns an immutable instance of [Python]. + * Returns an immutable instance of [EvalGraderTextSimilarity]. * * Further updates to this [Builder] will not mutate the returned instance. * * The following fields are required: * ```java + * .evaluationMetric() + * .input() * .name() - * .source() + * .reference() + * .passThreshold() * ``` * * @throws IllegalStateException if any required field is unset. */ - fun build(): Python = - Python( + fun build(): EvalGraderTextSimilarity = + EvalGraderTextSimilarity( + checkRequired("evaluationMetric", evaluationMetric), + checkRequired("input", input), checkRequired("name", name), - checkRequired("source", source), + checkRequired("reference", reference), type, - imageTag, - passThreshold, + checkRequired("passThreshold", passThreshold), additionalProperties.toMutableMap(), ) } private var validated: Boolean = false - fun validate(): Python = apply { + fun validate(): EvalGraderTextSimilarity = apply { if (validated) { return@apply } + evaluationMetric().validate() + input() name() - source() + reference() _type().let { - if (it != JsonValue.from("python")) { + if (it != JsonValue.from("text_similarity")) { throw OpenAIInvalidDataException("'type' is invalid, received $it") } } - imageTag() passThreshold() validated = true } @@ -1450,10 +1555,11 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (if (name.asKnown().isPresent) 1 else 0) + - (if (source.asKnown().isPresent) 1 else 0) + - type.let { if (it == JsonValue.from("python")) 1 else 0 } + - (if (imageTag.asKnown().isPresent) 1 else 0) + + (evaluationMetric.asKnown().getOrNull()?.validity() ?: 0) + + (if (input.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (if (reference.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("text_similarity")) 1 else 0 } + (if (passThreshold.asKnown().isPresent) 1 else 0) override fun equals(other: Any?): Boolean { @@ -1461,84 +1567,77 @@ private constructor( return true } - return /* spotless:off */ other is Python && name == other.name && source == other.source && type == other.type && imageTag == other.imageTag && passThreshold == other.passThreshold && additionalProperties == other.additionalProperties /* spotless:on */ + return /* spotless:off */ other is EvalGraderTextSimilarity && evaluationMetric == other.evaluationMetric && input == other.input && name == other.name && reference == other.reference && type == other.type && passThreshold == other.passThreshold && additionalProperties == other.additionalProperties /* spotless:on */ } /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(name, source, type, imageTag, passThreshold, additionalProperties) } + private val hashCode: Int by lazy { Objects.hash(evaluationMetric, input, name, reference, type, passThreshold, additionalProperties) } /* spotless:on */ override fun hashCode(): Int = hashCode override fun toString() = - "Python{name=$name, source=$source, type=$type, imageTag=$imageTag, passThreshold=$passThreshold, additionalProperties=$additionalProperties}" + "EvalGraderTextSimilarity{evaluationMetric=$evaluationMetric, input=$input, name=$name, reference=$reference, type=$type, passThreshold=$passThreshold, additionalProperties=$additionalProperties}" } - /** A ScoreModelGrader object that uses a model to assign a score to the input. */ - class ScoreModel + /** A PythonGrader object that runs a python script on the input. */ + class EvalGraderPython private constructor( - private val input: JsonField>, - private val model: JsonField, private val name: JsonField, + private val source: JsonField, private val type: JsonValue, + private val imageTag: JsonField, private val passThreshold: JsonField, - private val range: JsonField>, - private val samplingParams: JsonValue, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( - @JsonProperty("input") - @ExcludeMissing - input: JsonField> = JsonMissing.of(), - @JsonProperty("model") @ExcludeMissing model: JsonField = JsonMissing.of(), @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("source") + @ExcludeMissing + source: JsonField = JsonMissing.of(), @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + @JsonProperty("image_tag") + @ExcludeMissing + imageTag: JsonField = JsonMissing.of(), @JsonProperty("pass_threshold") @ExcludeMissing passThreshold: JsonField = JsonMissing.of(), - @JsonProperty("range") - @ExcludeMissing - range: JsonField> = JsonMissing.of(), - @JsonProperty("sampling_params") - @ExcludeMissing - samplingParams: JsonValue = JsonMissing.of(), - ) : this(input, model, name, type, passThreshold, range, samplingParams, mutableMapOf()) + ) : this(name, source, type, imageTag, passThreshold, mutableMapOf()) - /** - * The input text. This may include template strings. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected - * value). - */ - fun input(): List = input.getRequired("input") + fun toPythonGrader(): PythonGrader = + PythonGrader.builder() + .name(name) + .source(source) + .type(type) + .imageTag(imageTag) + .build() /** - * The model to use for the evaluation. + * The name of the grader. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected * value). */ - fun model(): String = model.getRequired("model") + fun name(): String = name.getRequired("name") /** - * The name of the grader. + * The source code of the python script. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected * value). */ - fun name(): String = name.getRequired("name") + fun source(): String = source.getRequired("source") /** - * The object type, which is always `score_model`. + * The object type, which is always `python`. * * Expected to always return the following: * ```java - * JsonValue.from("score_model") + * JsonValue.from("python") * ``` * * However, this method can be useful for debugging and logging (e.g. if the server @@ -1547,46 +1646,42 @@ private constructor( @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type /** - * The threshold for the score. + * The image tag to use for the python script. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). */ - fun passThreshold(): Optional = passThreshold.getOptional("pass_threshold") + fun imageTag(): Optional = imageTag.getOptional("image_tag") /** - * The range of the score. Defaults to `[0, 1]`. + * The threshold for the score. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). */ - fun range(): Optional> = range.getOptional("range") - - /** The sampling parameters for the model. */ - @JsonProperty("sampling_params") - @ExcludeMissing - fun _samplingParams(): JsonValue = samplingParams + fun passThreshold(): Optional = passThreshold.getOptional("pass_threshold") /** - * Returns the raw JSON value of [input]. + * Returns the raw JSON value of [name]. * - * Unlike [input], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("input") @ExcludeMissing fun _input(): JsonField> = input + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name /** - * Returns the raw JSON value of [model]. + * Returns the raw JSON value of [source]. * - * Unlike [model], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [source], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("model") @ExcludeMissing fun _model(): JsonField = model + @JsonProperty("source") @ExcludeMissing fun _source(): JsonField = source /** - * Returns the raw JSON value of [name]. + * Returns the raw JSON value of [imageTag]. * - * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [imageTag], this method doesn't throw if the JSON field has an unexpected + * type. */ - @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + @JsonProperty("image_tag") @ExcludeMissing fun _imageTag(): JsonField = imageTag /** * Returns the raw JSON value of [passThreshold]. @@ -1598,13 +1693,6 @@ private constructor( @ExcludeMissing fun _passThreshold(): JsonField = passThreshold - /** - * Returns the raw JSON value of [range]. - * - * Unlike [range], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("range") @ExcludeMissing fun _range(): JsonField> = range - @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { additionalProperties.put(key, value) @@ -1620,80 +1708,37 @@ private constructor( companion object { /** - * Returns a mutable builder for constructing an instance of [ScoreModel]. + * Returns a mutable builder for constructing an instance of [EvalGraderPython]. * * The following fields are required: * ```java - * .input() - * .model() * .name() + * .source() * ``` */ @JvmStatic fun builder() = Builder() } - /** A builder for [ScoreModel]. */ + /** A builder for [EvalGraderPython]. */ class Builder internal constructor() { - private var input: JsonField>? = null - private var model: JsonField? = null private var name: JsonField? = null - private var type: JsonValue = JsonValue.from("score_model") + private var source: JsonField? = null + private var type: JsonValue = JsonValue.from("python") + private var imageTag: JsonField = JsonMissing.of() private var passThreshold: JsonField = JsonMissing.of() - private var range: JsonField>? = null - private var samplingParams: JsonValue = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(scoreModel: ScoreModel) = apply { - input = scoreModel.input.map { it.toMutableList() } - model = scoreModel.model - name = scoreModel.name - type = scoreModel.type - passThreshold = scoreModel.passThreshold - range = scoreModel.range.map { it.toMutableList() } - samplingParams = scoreModel.samplingParams - additionalProperties = scoreModel.additionalProperties.toMutableMap() - } - - /** The input text. This may include template strings. */ - fun input(input: List) = input(JsonField.of(input)) - - /** - * Sets [Builder.input] to an arbitrary JSON value. - * - * You should usually call [Builder.input] with a well-typed `List` value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun input(input: JsonField>) = apply { - this.input = input.map { it.toMutableList() } - } - - /** - * Adds a single [Input] to [Builder.input]. - * - * @throws IllegalStateException if the field was previously set to a non-list. - */ - fun addInput(input: Input) = apply { - this.input = - (this.input ?: JsonField.of(mutableListOf())).also { - checkKnown("input", it).add(input) - } + internal fun from(evalGraderPython: EvalGraderPython) = apply { + name = evalGraderPython.name + source = evalGraderPython.source + type = evalGraderPython.type + imageTag = evalGraderPython.imageTag + passThreshold = evalGraderPython.passThreshold + additionalProperties = evalGraderPython.additionalProperties.toMutableMap() } - /** The model to use for the evaluation. */ - 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) = apply { this.model = model } - /** The name of the grader. */ fun name(name: String) = name(JsonField.of(name)) @@ -1706,8 +1751,410 @@ private constructor( */ fun name(name: JsonField) = apply { this.name = name } + /** The source code of the python script. */ + fun source(source: String) = source(JsonField.of(source)) + /** - * Sets the field to an arbitrary JSON value. + * Sets [Builder.source] to an arbitrary JSON value. + * + * You should usually call [Builder.source] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun source(source: JsonField) = apply { this.source = source } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("python") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + /** The image tag to use for the python script. */ + fun imageTag(imageTag: String) = imageTag(JsonField.of(imageTag)) + + /** + * Sets [Builder.imageTag] to an arbitrary JSON value. + * + * You should usually call [Builder.imageTag] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun imageTag(imageTag: JsonField) = apply { this.imageTag = imageTag } + + /** The threshold for the score. */ + fun passThreshold(passThreshold: Double) = + passThreshold(JsonField.of(passThreshold)) + + /** + * Sets [Builder.passThreshold] to an arbitrary JSON value. + * + * You should usually call [Builder.passThreshold] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun passThreshold(passThreshold: JsonField) = apply { + this.passThreshold = passThreshold + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [EvalGraderPython]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * .source() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): EvalGraderPython = + EvalGraderPython( + checkRequired("name", name), + checkRequired("source", source), + type, + imageTag, + passThreshold, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): EvalGraderPython = apply { + if (validated) { + return@apply + } + + name() + source() + _type().let { + if (it != JsonValue.from("python")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + imageTag() + passThreshold() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (name.asKnown().isPresent) 1 else 0) + + (if (source.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("python")) 1 else 0 } + + (if (imageTag.asKnown().isPresent) 1 else 0) + + (if (passThreshold.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is EvalGraderPython && name == other.name && source == other.source && type == other.type && imageTag == other.imageTag && passThreshold == other.passThreshold && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, source, type, imageTag, passThreshold, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "EvalGraderPython{name=$name, source=$source, type=$type, imageTag=$imageTag, passThreshold=$passThreshold, additionalProperties=$additionalProperties}" + } + + /** A ScoreModelGrader object that uses a model to assign a score to the input. */ + class EvalGraderScoreModel + private constructor( + private val input: JsonField>, + private val model: JsonField, + private val name: JsonField, + private val type: JsonValue, + private val range: JsonField>, + private val samplingParams: JsonValue, + private val passThreshold: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("input") + @ExcludeMissing + input: JsonField> = JsonMissing.of(), + @JsonProperty("model") @ExcludeMissing model: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + @JsonProperty("range") + @ExcludeMissing + range: JsonField> = JsonMissing.of(), + @JsonProperty("sampling_params") + @ExcludeMissing + samplingParams: JsonValue = JsonMissing.of(), + @JsonProperty("pass_threshold") + @ExcludeMissing + passThreshold: JsonField = JsonMissing.of(), + ) : this(input, model, name, type, range, samplingParams, passThreshold, mutableMapOf()) + + fun toScoreModelGrader(): ScoreModelGrader = + ScoreModelGrader.builder() + .input(input) + .model(model) + .name(name) + .type(type) + .range(range) + .samplingParams(samplingParams) + .build() + + /** + * The input text. This may include template strings. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun input(): List = input.getRequired("input") + + /** + * The model to use for the evaluation. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun model(): String = model.getRequired("model") + + /** + * The name of the grader. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun name(): String = name.getRequired("name") + + /** + * The object type, which is always `score_model`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("score_model") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * The range of the score. Defaults to `[0, 1]`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun range(): Optional> = range.getOptional("range") + + /** The sampling parameters for the model. */ + @JsonProperty("sampling_params") + @ExcludeMissing + fun _samplingParams(): JsonValue = samplingParams + + /** + * The threshold for the score. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun passThreshold(): Optional = passThreshold.getOptional("pass_threshold") + + /** + * Returns the raw JSON value of [input]. + * + * Unlike [input], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("input") + @ExcludeMissing + fun _input(): JsonField> = input + + /** + * 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 = model + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [range]. + * + * Unlike [range], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("range") @ExcludeMissing fun _range(): JsonField> = range + + /** + * Returns the raw JSON value of [passThreshold]. + * + * Unlike [passThreshold], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("pass_threshold") + @ExcludeMissing + fun _passThreshold(): JsonField = passThreshold + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [EvalGraderScoreModel]. + * + * The following fields are required: + * ```java + * .input() + * .model() + * .name() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [EvalGraderScoreModel]. */ + class Builder internal constructor() { + + private var input: JsonField>? = null + private var model: JsonField? = null + private var name: JsonField? = null + private var type: JsonValue = JsonValue.from("score_model") + private var range: JsonField>? = null + private var samplingParams: JsonValue = JsonMissing.of() + private var passThreshold: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(evalGraderScoreModel: EvalGraderScoreModel) = apply { + input = evalGraderScoreModel.input.map { it.toMutableList() } + model = evalGraderScoreModel.model + name = evalGraderScoreModel.name + type = evalGraderScoreModel.type + range = evalGraderScoreModel.range.map { it.toMutableList() } + samplingParams = evalGraderScoreModel.samplingParams + passThreshold = evalGraderScoreModel.passThreshold + additionalProperties = evalGraderScoreModel.additionalProperties.toMutableMap() + } + + /** The input text. This may include template strings. */ + fun input(input: List) = input(JsonField.of(input)) + + /** + * Sets [Builder.input] to an arbitrary JSON value. + * + * You should usually call [Builder.input] with a well-typed + * `List` value instead. This method is primarily for + * setting the field to an undocumented or not yet supported value. + */ + fun input(input: JsonField>) = apply { + this.input = input.map { it.toMutableList() } + } + + /** + * Adds a single [ScoreModelGrader.Input] to [Builder.input]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addInput(input: ScoreModelGrader.Input) = apply { + this.input = + (this.input ?: JsonField.of(mutableListOf())).also { + checkKnown("input", it).add(input) + } + } + + /** The model to use for the evaluation. */ + 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) = apply { this.model = model } + + /** The name of the grader. */ + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** + * Sets the field to an arbitrary JSON value. * * It is usually unnecessary to call this method because the field defaults to the * following: @@ -1720,21 +2167,6 @@ private constructor( */ fun type(type: JsonValue) = apply { this.type = type } - /** The threshold for the score. */ - fun passThreshold(passThreshold: Double) = - passThreshold(JsonField.of(passThreshold)) - - /** - * Sets [Builder.passThreshold] to an arbitrary JSON value. - * - * You should usually call [Builder.passThreshold] with a well-typed [Double] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun passThreshold(passThreshold: JsonField) = apply { - this.passThreshold = passThreshold - } - /** The range of the score. Defaults to `[0, 1]`. */ fun range(range: List) = range(JsonField.of(range)) @@ -1766,6 +2198,21 @@ private constructor( this.samplingParams = samplingParams } + /** The threshold for the score. */ + fun passThreshold(passThreshold: Double) = + passThreshold(JsonField.of(passThreshold)) + + /** + * Sets [Builder.passThreshold] to an arbitrary JSON value. + * + * You should usually call [Builder.passThreshold] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun passThreshold(passThreshold: JsonField) = apply { + this.passThreshold = passThreshold + } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() putAllAdditionalProperties(additionalProperties) @@ -1789,7 +2236,7 @@ private constructor( } /** - * Returns an immutable instance of [ScoreModel]. + * Returns an immutable instance of [EvalGraderScoreModel]. * * Further updates to this [Builder] will not mutate the returned instance. * @@ -1802,22 +2249,22 @@ private constructor( * * @throws IllegalStateException if any required field is unset. */ - fun build(): ScoreModel = - ScoreModel( + fun build(): EvalGraderScoreModel = + EvalGraderScoreModel( checkRequired("input", input).map { it.toImmutable() }, checkRequired("model", model), checkRequired("name", name), type, - passThreshold, (range ?: JsonMissing.of()).map { it.toImmutable() }, samplingParams, + passThreshold, additionalProperties.toMutableMap(), ) } private var validated: Boolean = false - fun validate(): ScoreModel = apply { + fun validate(): EvalGraderScoreModel = apply { if (validated) { return@apply } @@ -1830,8 +2277,8 @@ private constructor( throw OpenAIInvalidDataException("'type' is invalid, received $it") } } - passThreshold() range() + passThreshold() validated = true } @@ -1855,1003 +2302,25 @@ private constructor( (if (model.asKnown().isPresent) 1 else 0) + (if (name.asKnown().isPresent) 1 else 0) + type.let { if (it == JsonValue.from("score_model")) 1 else 0 } + - (if (passThreshold.asKnown().isPresent) 1 else 0) + - (range.asKnown().getOrNull()?.size ?: 0) - - /** - * A message input to the model with a role indicating instruction following hierarchy. - * Instructions given with the `developer` or `system` role take precedence over - * instructions given with the `user` role. Messages with the `assistant` role are - * presumed to have been generated by the model in previous interactions. - */ - class Input - private constructor( - private val content: JsonField, - private val role: JsonField, - private val type: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("content") - @ExcludeMissing - content: JsonField = JsonMissing.of(), - @JsonProperty("role") @ExcludeMissing role: JsonField = JsonMissing.of(), - @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), - ) : this(content, role, type, mutableMapOf()) - - /** - * Text inputs to the model - can contain template strings. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected - * value). - */ - fun content(): Content = content.getRequired("content") - - /** - * The role of the message input. One of `user`, `assistant`, `system`, or - * `developer`. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected - * value). - */ - fun role(): Role = role.getRequired("role") - - /** - * The type of the message input. Always `message`. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun type(): Optional = type.getOptional("type") - - /** - * Returns the raw JSON value of [content]. - * - * Unlike [content], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("content") - @ExcludeMissing - fun _content(): JsonField = content - - /** - * Returns the raw JSON value of [role]. - * - * Unlike [role], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("role") @ExcludeMissing fun _role(): JsonField = role - - /** - * Returns the raw JSON value of [type]. - * - * Unlike [type], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** - * Returns a mutable builder for constructing an instance of [Input]. - * - * The following fields are required: - * ```java - * .content() - * .role() - * ``` - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Input]. */ - class Builder internal constructor() { - - private var content: JsonField? = null - private var role: JsonField? = null - private var type: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(input: Input) = apply { - content = input.content - role = input.role - type = input.type - additionalProperties = input.additionalProperties.toMutableMap() - } - - /** Text inputs to the model - can contain template strings. */ - fun content(content: Content) = content(JsonField.of(content)) - - /** - * Sets [Builder.content] to an arbitrary JSON value. - * - * You should usually call [Builder.content] with a well-typed [Content] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun content(content: JsonField) = apply { this.content = content } - - /** Alias for calling [content] with `Content.ofTextInput(textInput)`. */ - fun content(textInput: String) = content(Content.ofTextInput(textInput)) - - /** - * Alias for calling [content] with - * `Content.ofResponseInputText(responseInputText)`. - */ - fun content(responseInputText: ResponseInputText) = - content(Content.ofResponseInputText(responseInputText)) - - /** Alias for calling [content] with `Content.ofOutputText(outputText)`. */ - fun content(outputText: Content.OutputText) = - content(Content.ofOutputText(outputText)) - - /** - * The role of the message input. One of `user`, `assistant`, `system`, or - * `developer`. - */ - fun role(role: Role) = role(JsonField.of(role)) - - /** - * Sets [Builder.role] to an arbitrary JSON value. - * - * You should usually call [Builder.role] with a well-typed [Role] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun role(role: JsonField) = apply { this.role = role } - - /** The type of the message input. Always `message`. */ - fun type(type: Type) = type(JsonField.of(type)) - - /** - * Sets [Builder.type] to an arbitrary JSON value. - * - * You should usually call [Builder.type] with a well-typed [Type] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun type(type: JsonField) = apply { this.type = type } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [Input]. - * - * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .content() - * .role() - * ``` - * - * @throws IllegalStateException if any required field is unset. - */ - fun build(): Input = - Input( - checkRequired("content", content), - checkRequired("role", role), - type, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): Input = apply { - if (validated) { - return@apply - } - - content().validate() - role().validate() - type().ifPresent { it.validate() } - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (content.asKnown().getOrNull()?.validity() ?: 0) + - (role.asKnown().getOrNull()?.validity() ?: 0) + - (type.asKnown().getOrNull()?.validity() ?: 0) - - /** Text inputs to the model - can contain template strings. */ - @JsonDeserialize(using = Content.Deserializer::class) - @JsonSerialize(using = Content.Serializer::class) - class Content - private constructor( - private val textInput: String? = null, - private val responseInputText: ResponseInputText? = null, - private val outputText: OutputText? = null, - private val _json: JsonValue? = null, - ) { - - /** A text input to the model. */ - fun textInput(): Optional = Optional.ofNullable(textInput) - - /** A text input to the model. */ - fun responseInputText(): Optional = - Optional.ofNullable(responseInputText) - - /** A text output from the model. */ - fun outputText(): Optional = Optional.ofNullable(outputText) - - fun isTextInput(): Boolean = textInput != null - - fun isResponseInputText(): Boolean = responseInputText != null - - fun isOutputText(): Boolean = outputText != null - - /** A text input to the model. */ - fun asTextInput(): String = textInput.getOrThrow("textInput") - - /** A text input to the model. */ - fun asResponseInputText(): ResponseInputText = - responseInputText.getOrThrow("responseInputText") - - /** A text output from the model. */ - fun asOutputText(): OutputText = outputText.getOrThrow("outputText") - - fun _json(): Optional = Optional.ofNullable(_json) - - fun accept(visitor: Visitor): T = - when { - textInput != null -> visitor.visitTextInput(textInput) - responseInputText != null -> - visitor.visitResponseInputText(responseInputText) - outputText != null -> visitor.visitOutputText(outputText) - else -> visitor.unknown(_json) - } - - private var validated: Boolean = false - - fun validate(): Content = apply { - if (validated) { - return@apply - } - - accept( - object : Visitor { - override fun visitTextInput(textInput: String) {} - - override fun visitResponseInputText( - responseInputText: ResponseInputText - ) { - responseInputText.validate() - } - - override fun visitOutputText(outputText: OutputText) { - outputText.validate() - } - } - ) - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - accept( - object : Visitor { - override fun visitTextInput(textInput: String) = 1 - - override fun visitResponseInputText( - responseInputText: ResponseInputText - ) = responseInputText.validity() - - override fun visitOutputText(outputText: OutputText) = - outputText.validity() - - override fun unknown(json: JsonValue?) = 0 - } - ) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is Content && textInput == other.textInput && responseInputText == other.responseInputText && outputText == other.outputText /* spotless:on */ - } - - override fun hashCode(): Int = /* spotless:off */ Objects.hash(textInput, responseInputText, outputText) /* spotless:on */ - - override fun toString(): String = - when { - textInput != null -> "Content{textInput=$textInput}" - responseInputText != null -> - "Content{responseInputText=$responseInputText}" - outputText != null -> "Content{outputText=$outputText}" - _json != null -> "Content{_unknown=$_json}" - else -> throw IllegalStateException("Invalid Content") - } - - companion object { - - /** A text input to the model. */ - @JvmStatic - fun ofTextInput(textInput: String) = Content(textInput = textInput) - - /** A text input to the model. */ - @JvmStatic - fun ofResponseInputText(responseInputText: ResponseInputText) = - Content(responseInputText = responseInputText) - - /** A text output from the model. */ - @JvmStatic - fun ofOutputText(outputText: OutputText) = Content(outputText = outputText) - } - - /** - * An interface that defines how to map each variant of [Content] to a value of - * type [T]. - */ - interface Visitor { - - /** A text input to the model. */ - fun visitTextInput(textInput: String): T - - /** A text input to the model. */ - fun visitResponseInputText(responseInputText: ResponseInputText): T - - /** A text output from the model. */ - fun visitOutputText(outputText: OutputText): T - - /** - * Maps an unknown variant of [Content] to a value of type [T]. - * - * An instance of [Content] can contain an unknown variant if it was - * deserialized from data that doesn't match any known variant. For example, - * if the SDK is on an older version than the API, then the API may respond - * with new variants that the SDK is unaware of. - * - * @throws OpenAIInvalidDataException in the default implementation. - */ - fun unknown(json: JsonValue?): T { - throw OpenAIInvalidDataException("Unknown Content: $json") - } - } - - internal class Deserializer : BaseDeserializer(Content::class) { - - override fun ObjectCodec.deserialize(node: JsonNode): Content { - val json = JsonValue.fromJsonNode(node) - - val bestMatches = - sequenceOf( - tryDeserialize(node, jacksonTypeRef()) - ?.let { Content(responseInputText = it, _json = json) }, - tryDeserialize(node, jacksonTypeRef())?.let { - Content(outputText = it, _json = json) - }, - tryDeserialize(node, jacksonTypeRef())?.let { - Content(textInput = it, _json = json) - }, - ) - .filterNotNull() - .allMaxBy { it.validity() } - .toList() - return when (bestMatches.size) { - // This can happen if what we're deserializing is completely - // incompatible with all the possible variants (e.g. deserializing - // from array). - 0 -> Content(_json = json) - 1 -> bestMatches.single() - // If there's more than one match with the highest validity, then - // use the first completely valid match, or simply the first match - // if none are completely valid. - else -> - bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() - } - } - } - - internal class Serializer : BaseSerializer(Content::class) { - - override fun serialize( - value: Content, - generator: JsonGenerator, - provider: SerializerProvider, - ) { - when { - value.textInput != null -> generator.writeObject(value.textInput) - value.responseInputText != null -> - generator.writeObject(value.responseInputText) - value.outputText != null -> generator.writeObject(value.outputText) - value._json != null -> generator.writeObject(value._json) - else -> throw IllegalStateException("Invalid Content") - } - } - } - - /** A text output from the model. */ - class OutputText - private constructor( - private val text: JsonField, - private val type: JsonValue, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("text") - @ExcludeMissing - text: JsonField = JsonMissing.of(), - @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), - ) : this(text, type, mutableMapOf()) - - /** - * The text output from the model. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected - * type or is unexpectedly missing or null (e.g. if the server responded - * with an unexpected value). - */ - fun text(): String = text.getRequired("text") - - /** - * The type of the output text. Always `output_text`. - * - * Expected to always return the following: - * ```java - * JsonValue.from("output_text") - * ``` - * - * However, this method can be useful for debugging and logging (e.g. if the - * server responded with an unexpected value). - */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type - - /** - * Returns the raw JSON value of [text]. - * - * Unlike [text], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("text") @ExcludeMissing fun _text(): JsonField = text - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** - * Returns a mutable builder for constructing an instance of - * [OutputText]. - * - * The following fields are required: - * ```java - * .text() - * ``` - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [OutputText]. */ - class Builder internal constructor() { - - private var text: JsonField? = null - private var type: JsonValue = JsonValue.from("output_text") - private var additionalProperties: MutableMap = - mutableMapOf() - - @JvmSynthetic - internal fun from(outputText: OutputText) = apply { - text = outputText.text - type = outputText.type - additionalProperties = - outputText.additionalProperties.toMutableMap() - } - - /** The text output from the model. */ - fun text(text: String) = text(JsonField.of(text)) - - /** - * Sets [Builder.text] to an arbitrary JSON value. - * - * You should usually call [Builder.text] with a well-typed [String] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun text(text: JsonField) = apply { this.text = text } - - /** - * Sets the field to an arbitrary JSON value. - * - * It is usually unnecessary to call this method because the field - * defaults to the following: - * ```java - * JsonValue.from("output_text") - * ``` - * - * This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun type(type: JsonValue) = apply { this.type = type } - - fun additionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties( - additionalProperties: Map - ) = apply { this.additionalProperties.putAll(additionalProperties) } - - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [OutputText]. - * - * Further updates to this [Builder] will not mutate the returned - * instance. - * - * The following fields are required: - * ```java - * .text() - * ``` - * - * @throws IllegalStateException if any required field is unset. - */ - fun build(): OutputText = - OutputText( - checkRequired("text", text), - type, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): OutputText = apply { - if (validated) { - return@apply - } - - text() - _type().let { - if (it != JsonValue.from("output_text")) { - throw OpenAIInvalidDataException( - "'type' is invalid, received $it" - ) - } - } - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this - * object recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (if (text.asKnown().isPresent) 1 else 0) + - type.let { if (it == JsonValue.from("output_text")) 1 else 0 } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is OutputText && text == other.text && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ - } - - /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(text, type, additionalProperties) } - /* spotless:on */ - - override fun hashCode(): Int = hashCode - - override fun toString() = - "OutputText{text=$text, type=$type, additionalProperties=$additionalProperties}" - } - } - - /** - * The role of the message input. One of `user`, `assistant`, `system`, or - * `developer`. - */ - class Role @JsonCreator private constructor(private val value: JsonField) : - Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that - * doesn't match any known member, and you want to know that value. For example, - * if the SDK is on an older version than the API, then the API may respond with - * new members that the SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue - fun _value(): JsonField = value - - companion object { - - @JvmField val USER = of("user") - - @JvmField val ASSISTANT = of("assistant") - - @JvmField val SYSTEM = of("system") - - @JvmField val DEVELOPER = of("developer") - - @JvmStatic fun of(value: String) = Role(JsonField.of(value)) - } - - /** An enum containing [Role]'s known values. */ - enum class Known { - USER, - ASSISTANT, - SYSTEM, - DEVELOPER, - } - - /** - * An enum containing [Role]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Role] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For - * example, if the SDK is on an older version than the API, then the API may - * respond with new members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - USER, - ASSISTANT, - SYSTEM, - DEVELOPER, - /** - * An enum member indicating that [Role] was instantiated with an unknown - * value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or - * if you want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - USER -> Value.USER - ASSISTANT -> Value.ASSISTANT - SYSTEM -> Value.SYSTEM - DEVELOPER -> Value.DEVELOPER - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known - * and don't want to throw for the unknown case. - * - * @throws OpenAIInvalidDataException if this class instance's value is a not a - * known member. - */ - fun known(): Known = - when (this) { - USER -> Known.USER - ASSISTANT -> Known.ASSISTANT - SYSTEM -> Known.SYSTEM - DEVELOPER -> Known.DEVELOPER - else -> throw OpenAIInvalidDataException("Unknown Role: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for - * debugging and generally doesn't throw. - * - * @throws OpenAIInvalidDataException if this class instance's value does not - * have the expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - OpenAIInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): Role = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is Role && value == other.value /* spotless:on */ - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - /** The type of the message input. Always `message`. */ - class Type @JsonCreator private constructor(private val value: JsonField) : - Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that - * doesn't match any known member, and you want to know that value. For example, - * if the SDK is on an older version than the API, then the API may respond with - * new members that the SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue - fun _value(): JsonField = value - - companion object { - - @JvmField val MESSAGE = of("message") - - @JvmStatic fun of(value: String) = Type(JsonField.of(value)) - } - - /** An enum containing [Type]'s known values. */ - enum class Known { - MESSAGE - } - - /** - * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Type] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For - * example, if the SDK is on an older version than the API, then the API may - * respond with new members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - MESSAGE, - /** - * An enum member indicating that [Type] was instantiated with an unknown - * value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or - * if you want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - MESSAGE -> Value.MESSAGE - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known - * and don't want to throw for the unknown case. - * - * @throws OpenAIInvalidDataException if this class instance's value is a not a - * known member. - */ - fun known(): Known = - when (this) { - MESSAGE -> Known.MESSAGE - else -> throw OpenAIInvalidDataException("Unknown Type: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for - * debugging and generally doesn't throw. - * - * @throws OpenAIInvalidDataException if this class instance's value does not - * have the expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - OpenAIInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): Type = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is Type && value == other.value /* spotless:on */ - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is Input && content == other.content && role == other.role && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ - } - - /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(content, role, type, additionalProperties) } - /* spotless:on */ - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Input{content=$content, role=$role, type=$type, additionalProperties=$additionalProperties}" - } + (range.asKnown().getOrNull()?.size ?: 0) + + (if (passThreshold.asKnown().isPresent) 1 else 0) override fun equals(other: Any?): Boolean { if (this === other) { return true } - return /* spotless:off */ other is ScoreModel && input == other.input && model == other.model && name == other.name && type == other.type && passThreshold == other.passThreshold && range == other.range && samplingParams == other.samplingParams && additionalProperties == other.additionalProperties /* spotless:on */ + return /* spotless:off */ other is EvalGraderScoreModel && input == other.input && model == other.model && name == other.name && type == other.type && range == other.range && samplingParams == other.samplingParams && passThreshold == other.passThreshold && additionalProperties == other.additionalProperties /* spotless:on */ } /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(input, model, name, type, passThreshold, range, samplingParams, additionalProperties) } + private val hashCode: Int by lazy { Objects.hash(input, model, name, type, range, samplingParams, passThreshold, additionalProperties) } /* spotless:on */ override fun hashCode(): Int = hashCode override fun toString() = - "ScoreModel{input=$input, model=$model, name=$name, type=$type, passThreshold=$passThreshold, range=$range, samplingParams=$samplingParams, additionalProperties=$additionalProperties}" + "EvalGraderScoreModel{input=$input, model=$model, name=$name, type=$type, range=$range, samplingParams=$samplingParams, passThreshold=$passThreshold, additionalProperties=$additionalProperties}" } } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalUpdateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalUpdateParams.kt index c5ea3694..d3556b08 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalUpdateParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalUpdateParams.kt @@ -11,7 +11,6 @@ import com.openai.core.JsonField import com.openai.core.JsonMissing import com.openai.core.JsonValue import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import com.openai.core.toImmutable @@ -24,13 +23,13 @@ import kotlin.jvm.optionals.getOrNull /** Update certain properties of an evaluation. */ class EvalUpdateParams private constructor( - private val evalId: String, + private val evalId: String?, private val body: Body, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun evalId(): String = evalId + fun evalId(): Optional = Optional.ofNullable(evalId) /** * Set of 16 key-value pairs that can be attached to an object. This can be useful for storing @@ -77,14 +76,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [EvalUpdateParams]. - * - * The following fields are required: - * ```java - * .evalId() - * ``` - */ + @JvmStatic fun none(): EvalUpdateParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [EvalUpdateParams]. */ @JvmStatic fun builder() = Builder() } @@ -104,7 +98,10 @@ private constructor( additionalQueryParams = evalUpdateParams.additionalQueryParams.toBuilder() } - fun evalId(evalId: String) = apply { this.evalId = evalId } + fun evalId(evalId: String?) = apply { this.evalId = evalId } + + /** Alias for calling [Builder.evalId] with `evalId.orElse(null)`. */ + fun evalId(evalId: Optional) = evalId(evalId.getOrNull()) /** * Sets the entire request body. @@ -270,17 +267,10 @@ private constructor( * Returns an immutable instance of [EvalUpdateParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .evalId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): EvalUpdateParams = EvalUpdateParams( - checkRequired("evalId", evalId), + evalId, body.build(), additionalHeaders.build(), additionalQueryParams.build(), @@ -291,7 +281,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> evalId + 0 -> evalId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalUpdateResponse.kt b/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalUpdateResponse.kt index db7ad9a1..5d05142a 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalUpdateResponse.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalUpdateResponse.kt @@ -15,7 +15,6 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import com.openai.core.BaseDeserializer import com.openai.core.BaseSerializer -import com.openai.core.Enum import com.openai.core.ExcludeMissing import com.openai.core.JsonField import com.openai.core.JsonMissing @@ -26,7 +25,11 @@ import com.openai.core.checkRequired import com.openai.core.getOrThrow import com.openai.core.toImmutable import com.openai.errors.OpenAIInvalidDataException -import com.openai.models.responses.ResponseInputText +import com.openai.models.graders.gradermodels.LabelModelGrader +import com.openai.models.graders.gradermodels.PythonGrader +import com.openai.models.graders.gradermodels.ScoreModelGrader +import com.openai.models.graders.gradermodels.StringCheckGrader +import com.openai.models.graders.gradermodels.TextSimilarityGrader import java.util.Collections import java.util.Objects import java.util.Optional @@ -388,34 +391,43 @@ private constructor( } /** - * Alias for calling [addTestingCriterion] with `TestingCriterion.ofLabelModel(labelModel)`. + * Alias for calling [addTestingCriterion] with + * `TestingCriterion.ofLabelModelGrader(labelModelGrader)`. */ - fun addTestingCriterion(labelModel: EvalLabelModelGrader) = - addTestingCriterion(TestingCriterion.ofLabelModel(labelModel)) + fun addTestingCriterion(labelModelGrader: LabelModelGrader) = + addTestingCriterion(TestingCriterion.ofLabelModelGrader(labelModelGrader)) /** * Alias for calling [addTestingCriterion] with - * `TestingCriterion.ofStringCheck(stringCheck)`. + * `TestingCriterion.ofStringCheckGrader(stringCheckGrader)`. */ - fun addTestingCriterion(stringCheck: EvalStringCheckGrader) = - addTestingCriterion(TestingCriterion.ofStringCheck(stringCheck)) + fun addTestingCriterion(stringCheckGrader: StringCheckGrader) = + addTestingCriterion(TestingCriterion.ofStringCheckGrader(stringCheckGrader)) /** * Alias for calling [addTestingCriterion] with - * `TestingCriterion.ofTextSimilarity(textSimilarity)`. + * `TestingCriterion.ofEvalGraderTextSimilarity(evalGraderTextSimilarity)`. */ - fun addTestingCriterion(textSimilarity: EvalTextSimilarityGrader) = - addTestingCriterion(TestingCriterion.ofTextSimilarity(textSimilarity)) + fun addTestingCriterion( + evalGraderTextSimilarity: TestingCriterion.EvalGraderTextSimilarity + ) = + addTestingCriterion( + TestingCriterion.ofEvalGraderTextSimilarity(evalGraderTextSimilarity) + ) - /** Alias for calling [addTestingCriterion] with `TestingCriterion.ofPython(python)`. */ - fun addTestingCriterion(python: TestingCriterion.Python) = - addTestingCriterion(TestingCriterion.ofPython(python)) + /** + * Alias for calling [addTestingCriterion] with + * `TestingCriterion.ofEvalGraderPython(evalGraderPython)`. + */ + fun addTestingCriterion(evalGraderPython: TestingCriterion.EvalGraderPython) = + addTestingCriterion(TestingCriterion.ofEvalGraderPython(evalGraderPython)) /** - * Alias for calling [addTestingCriterion] with `TestingCriterion.ofScoreModel(scoreModel)`. + * Alias for calling [addTestingCriterion] with + * `TestingCriterion.ofEvalGraderScoreModel(evalGraderScoreModel)`. */ - fun addTestingCriterion(scoreModel: TestingCriterion.ScoreModel) = - addTestingCriterion(TestingCriterion.ofScoreModel(scoreModel)) + fun addTestingCriterion(evalGraderScoreModel: TestingCriterion.EvalGraderScoreModel) = + addTestingCriterion(TestingCriterion.ofEvalGraderScoreModel(evalGraderScoreModel)) fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() @@ -860,11 +872,11 @@ private constructor( @JsonSerialize(using = TestingCriterion.Serializer::class) class TestingCriterion private constructor( - private val labelModel: EvalLabelModelGrader? = null, - private val stringCheck: EvalStringCheckGrader? = null, - private val textSimilarity: EvalTextSimilarityGrader? = null, - private val python: Python? = null, - private val scoreModel: ScoreModel? = null, + private val labelModelGrader: LabelModelGrader? = null, + private val stringCheckGrader: StringCheckGrader? = null, + private val evalGraderTextSimilarity: EvalGraderTextSimilarity? = null, + private val evalGraderPython: EvalGraderPython? = null, + private val evalGraderScoreModel: EvalGraderScoreModel? = null, private val _json: JsonValue? = null, ) { @@ -872,65 +884,71 @@ private constructor( * A LabelModelGrader object which uses a model to assign labels to each item in the * evaluation. */ - fun labelModel(): Optional = Optional.ofNullable(labelModel) + fun labelModelGrader(): Optional = Optional.ofNullable(labelModelGrader) /** * A StringCheckGrader object that performs a string comparison between input and reference * using a specified operation. */ - fun stringCheck(): Optional = Optional.ofNullable(stringCheck) + fun stringCheckGrader(): Optional = + Optional.ofNullable(stringCheckGrader) /** A TextSimilarityGrader object which grades text based on similarity metrics. */ - fun textSimilarity(): Optional = - Optional.ofNullable(textSimilarity) + fun evalGraderTextSimilarity(): Optional = + Optional.ofNullable(evalGraderTextSimilarity) /** A PythonGrader object that runs a python script on the input. */ - fun python(): Optional = Optional.ofNullable(python) + fun evalGraderPython(): Optional = Optional.ofNullable(evalGraderPython) /** A ScoreModelGrader object that uses a model to assign a score to the input. */ - fun scoreModel(): Optional = Optional.ofNullable(scoreModel) + fun evalGraderScoreModel(): Optional = + Optional.ofNullable(evalGraderScoreModel) - fun isLabelModel(): Boolean = labelModel != null + fun isLabelModelGrader(): Boolean = labelModelGrader != null - fun isStringCheck(): Boolean = stringCheck != null + fun isStringCheckGrader(): Boolean = stringCheckGrader != null - fun isTextSimilarity(): Boolean = textSimilarity != null + fun isEvalGraderTextSimilarity(): Boolean = evalGraderTextSimilarity != null - fun isPython(): Boolean = python != null + fun isEvalGraderPython(): Boolean = evalGraderPython != null - fun isScoreModel(): Boolean = scoreModel != null + fun isEvalGraderScoreModel(): Boolean = evalGraderScoreModel != null /** * A LabelModelGrader object which uses a model to assign labels to each item in the * evaluation. */ - fun asLabelModel(): EvalLabelModelGrader = labelModel.getOrThrow("labelModel") + fun asLabelModelGrader(): LabelModelGrader = labelModelGrader.getOrThrow("labelModelGrader") /** * A StringCheckGrader object that performs a string comparison between input and reference * using a specified operation. */ - fun asStringCheck(): EvalStringCheckGrader = stringCheck.getOrThrow("stringCheck") + fun asStringCheckGrader(): StringCheckGrader = + stringCheckGrader.getOrThrow("stringCheckGrader") /** A TextSimilarityGrader object which grades text based on similarity metrics. */ - fun asTextSimilarity(): EvalTextSimilarityGrader = - textSimilarity.getOrThrow("textSimilarity") + fun asEvalGraderTextSimilarity(): EvalGraderTextSimilarity = + evalGraderTextSimilarity.getOrThrow("evalGraderTextSimilarity") /** A PythonGrader object that runs a python script on the input. */ - fun asPython(): Python = python.getOrThrow("python") + fun asEvalGraderPython(): EvalGraderPython = evalGraderPython.getOrThrow("evalGraderPython") /** A ScoreModelGrader object that uses a model to assign a score to the input. */ - fun asScoreModel(): ScoreModel = scoreModel.getOrThrow("scoreModel") + fun asEvalGraderScoreModel(): EvalGraderScoreModel = + evalGraderScoreModel.getOrThrow("evalGraderScoreModel") fun _json(): Optional = Optional.ofNullable(_json) fun accept(visitor: Visitor): T = when { - labelModel != null -> visitor.visitLabelModel(labelModel) - stringCheck != null -> visitor.visitStringCheck(stringCheck) - textSimilarity != null -> visitor.visitTextSimilarity(textSimilarity) - python != null -> visitor.visitPython(python) - scoreModel != null -> visitor.visitScoreModel(scoreModel) + labelModelGrader != null -> visitor.visitLabelModelGrader(labelModelGrader) + stringCheckGrader != null -> visitor.visitStringCheckGrader(stringCheckGrader) + evalGraderTextSimilarity != null -> + visitor.visitEvalGraderTextSimilarity(evalGraderTextSimilarity) + evalGraderPython != null -> visitor.visitEvalGraderPython(evalGraderPython) + evalGraderScoreModel != null -> + visitor.visitEvalGraderScoreModel(evalGraderScoreModel) else -> visitor.unknown(_json) } @@ -943,24 +961,28 @@ private constructor( accept( object : Visitor { - override fun visitLabelModel(labelModel: EvalLabelModelGrader) { - labelModel.validate() + override fun visitLabelModelGrader(labelModelGrader: LabelModelGrader) { + labelModelGrader.validate() } - override fun visitStringCheck(stringCheck: EvalStringCheckGrader) { - stringCheck.validate() + override fun visitStringCheckGrader(stringCheckGrader: StringCheckGrader) { + stringCheckGrader.validate() } - override fun visitTextSimilarity(textSimilarity: EvalTextSimilarityGrader) { - textSimilarity.validate() + override fun visitEvalGraderTextSimilarity( + evalGraderTextSimilarity: EvalGraderTextSimilarity + ) { + evalGraderTextSimilarity.validate() } - override fun visitPython(python: Python) { - python.validate() + override fun visitEvalGraderPython(evalGraderPython: EvalGraderPython) { + evalGraderPython.validate() } - override fun visitScoreModel(scoreModel: ScoreModel) { - scoreModel.validate() + override fun visitEvalGraderScoreModel( + evalGraderScoreModel: EvalGraderScoreModel + ) { + evalGraderScoreModel.validate() } } ) @@ -985,18 +1007,22 @@ private constructor( internal fun validity(): Int = accept( object : Visitor { - override fun visitLabelModel(labelModel: EvalLabelModelGrader) = - labelModel.validity() + override fun visitLabelModelGrader(labelModelGrader: LabelModelGrader) = + labelModelGrader.validity() - override fun visitStringCheck(stringCheck: EvalStringCheckGrader) = - stringCheck.validity() + override fun visitStringCheckGrader(stringCheckGrader: StringCheckGrader) = + stringCheckGrader.validity() - override fun visitTextSimilarity(textSimilarity: EvalTextSimilarityGrader) = - textSimilarity.validity() + override fun visitEvalGraderTextSimilarity( + evalGraderTextSimilarity: EvalGraderTextSimilarity + ) = evalGraderTextSimilarity.validity() - override fun visitPython(python: Python) = python.validity() + override fun visitEvalGraderPython(evalGraderPython: EvalGraderPython) = + evalGraderPython.validity() - override fun visitScoreModel(scoreModel: ScoreModel) = scoreModel.validity() + override fun visitEvalGraderScoreModel( + evalGraderScoreModel: EvalGraderScoreModel + ) = evalGraderScoreModel.validity() override fun unknown(json: JsonValue?) = 0 } @@ -1007,18 +1033,21 @@ private constructor( return true } - return /* spotless:off */ other is TestingCriterion && labelModel == other.labelModel && stringCheck == other.stringCheck && textSimilarity == other.textSimilarity && python == other.python && scoreModel == other.scoreModel /* spotless:on */ + return /* spotless:off */ other is TestingCriterion && labelModelGrader == other.labelModelGrader && stringCheckGrader == other.stringCheckGrader && evalGraderTextSimilarity == other.evalGraderTextSimilarity && evalGraderPython == other.evalGraderPython && evalGraderScoreModel == other.evalGraderScoreModel /* spotless:on */ } - override fun hashCode(): Int = /* spotless:off */ Objects.hash(labelModel, stringCheck, textSimilarity, python, scoreModel) /* spotless:on */ + override fun hashCode(): Int = /* spotless:off */ Objects.hash(labelModelGrader, stringCheckGrader, evalGraderTextSimilarity, evalGraderPython, evalGraderScoreModel) /* spotless:on */ override fun toString(): String = when { - labelModel != null -> "TestingCriterion{labelModel=$labelModel}" - stringCheck != null -> "TestingCriterion{stringCheck=$stringCheck}" - textSimilarity != null -> "TestingCriterion{textSimilarity=$textSimilarity}" - python != null -> "TestingCriterion{python=$python}" - scoreModel != null -> "TestingCriterion{scoreModel=$scoreModel}" + labelModelGrader != null -> "TestingCriterion{labelModelGrader=$labelModelGrader}" + stringCheckGrader != null -> + "TestingCriterion{stringCheckGrader=$stringCheckGrader}" + evalGraderTextSimilarity != null -> + "TestingCriterion{evalGraderTextSimilarity=$evalGraderTextSimilarity}" + evalGraderPython != null -> "TestingCriterion{evalGraderPython=$evalGraderPython}" + evalGraderScoreModel != null -> + "TestingCriterion{evalGraderScoreModel=$evalGraderScoreModel}" _json != null -> "TestingCriterion{_unknown=$_json}" else -> throw IllegalStateException("Invalid TestingCriterion") } @@ -1030,28 +1059,31 @@ private constructor( * evaluation. */ @JvmStatic - fun ofLabelModel(labelModel: EvalLabelModelGrader) = - TestingCriterion(labelModel = labelModel) + fun ofLabelModelGrader(labelModelGrader: LabelModelGrader) = + TestingCriterion(labelModelGrader = labelModelGrader) /** * A StringCheckGrader object that performs a string comparison between input and * reference using a specified operation. */ @JvmStatic - fun ofStringCheck(stringCheck: EvalStringCheckGrader) = - TestingCriterion(stringCheck = stringCheck) + fun ofStringCheckGrader(stringCheckGrader: StringCheckGrader) = + TestingCriterion(stringCheckGrader = stringCheckGrader) /** A TextSimilarityGrader object which grades text based on similarity metrics. */ @JvmStatic - fun ofTextSimilarity(textSimilarity: EvalTextSimilarityGrader) = - TestingCriterion(textSimilarity = textSimilarity) + fun ofEvalGraderTextSimilarity(evalGraderTextSimilarity: EvalGraderTextSimilarity) = + TestingCriterion(evalGraderTextSimilarity = evalGraderTextSimilarity) /** A PythonGrader object that runs a python script on the input. */ - @JvmStatic fun ofPython(python: Python) = TestingCriterion(python = python) + @JvmStatic + fun ofEvalGraderPython(evalGraderPython: EvalGraderPython) = + TestingCriterion(evalGraderPython = evalGraderPython) /** A ScoreModelGrader object that uses a model to assign a score to the input. */ @JvmStatic - fun ofScoreModel(scoreModel: ScoreModel) = TestingCriterion(scoreModel = scoreModel) + fun ofEvalGraderScoreModel(evalGraderScoreModel: EvalGraderScoreModel) = + TestingCriterion(evalGraderScoreModel = evalGraderScoreModel) } /** @@ -1064,22 +1096,22 @@ private constructor( * A LabelModelGrader object which uses a model to assign labels to each item in the * evaluation. */ - fun visitLabelModel(labelModel: EvalLabelModelGrader): T + fun visitLabelModelGrader(labelModelGrader: LabelModelGrader): T /** * A StringCheckGrader object that performs a string comparison between input and * reference using a specified operation. */ - fun visitStringCheck(stringCheck: EvalStringCheckGrader): T + fun visitStringCheckGrader(stringCheckGrader: StringCheckGrader): T /** A TextSimilarityGrader object which grades text based on similarity metrics. */ - fun visitTextSimilarity(textSimilarity: EvalTextSimilarityGrader): T + fun visitEvalGraderTextSimilarity(evalGraderTextSimilarity: EvalGraderTextSimilarity): T /** A PythonGrader object that runs a python script on the input. */ - fun visitPython(python: Python): T + fun visitEvalGraderPython(evalGraderPython: EvalGraderPython): T /** A ScoreModelGrader object that uses a model to assign a score to the input. */ - fun visitScoreModel(scoreModel: ScoreModel): T + fun visitEvalGraderScoreModel(evalGraderScoreModel: EvalGraderScoreModel): T /** * Maps an unknown variant of [TestingCriterion] to a value of type [T]. @@ -1100,37 +1132,38 @@ private constructor( override fun ObjectCodec.deserialize(node: JsonNode): TestingCriterion { val json = JsonValue.fromJsonNode(node) - val type = json.asObject().getOrNull()?.get("type")?.asString()?.getOrNull() - when (type) { - "label_model" -> { - return tryDeserialize(node, jacksonTypeRef())?.let { - TestingCriterion(labelModel = it, _json = json) - } ?: TestingCriterion(_json = json) - } - "string_check" -> { - return tryDeserialize(node, jacksonTypeRef())?.let { - TestingCriterion(stringCheck = it, _json = json) - } ?: TestingCriterion(_json = json) - } - "text_similarity" -> { - return tryDeserialize(node, jacksonTypeRef()) - ?.let { TestingCriterion(textSimilarity = it, _json = json) } - ?: TestingCriterion(_json = json) - } - "python" -> { - return tryDeserialize(node, jacksonTypeRef())?.let { - TestingCriterion(python = it, _json = json) - } ?: TestingCriterion(_json = json) - } - "score_model" -> { - return tryDeserialize(node, jacksonTypeRef())?.let { - TestingCriterion(scoreModel = it, _json = json) - } ?: TestingCriterion(_json = json) - } + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + TestingCriterion(labelModelGrader = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + TestingCriterion(stringCheckGrader = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + TestingCriterion(evalGraderTextSimilarity = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + TestingCriterion(evalGraderPython = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + TestingCriterion(evalGraderScoreModel = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with + // all the possible variants (e.g. deserializing from boolean). + 0 -> TestingCriterion(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely + // valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() } - - return TestingCriterion(_json = json) } } @@ -1142,42 +1175,77 @@ private constructor( provider: SerializerProvider, ) { when { - value.labelModel != null -> generator.writeObject(value.labelModel) - value.stringCheck != null -> generator.writeObject(value.stringCheck) - value.textSimilarity != null -> generator.writeObject(value.textSimilarity) - value.python != null -> generator.writeObject(value.python) - value.scoreModel != null -> generator.writeObject(value.scoreModel) + value.labelModelGrader != null -> generator.writeObject(value.labelModelGrader) + value.stringCheckGrader != null -> + generator.writeObject(value.stringCheckGrader) + value.evalGraderTextSimilarity != null -> + generator.writeObject(value.evalGraderTextSimilarity) + value.evalGraderPython != null -> generator.writeObject(value.evalGraderPython) + value.evalGraderScoreModel != null -> + generator.writeObject(value.evalGraderScoreModel) value._json != null -> generator.writeObject(value._json) else -> throw IllegalStateException("Invalid TestingCriterion") } } } - /** A PythonGrader object that runs a python script on the input. */ - class Python + /** A TextSimilarityGrader object which grades text based on similarity metrics. */ + class EvalGraderTextSimilarity private constructor( + private val evaluationMetric: JsonField, + private val input: JsonField, private val name: JsonField, - private val source: JsonField, + private val reference: JsonField, private val type: JsonValue, - private val imageTag: JsonField, private val passThreshold: JsonField, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( + @JsonProperty("evaluation_metric") + @ExcludeMissing + evaluationMetric: JsonField = + JsonMissing.of(), + @JsonProperty("input") @ExcludeMissing input: JsonField = JsonMissing.of(), @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), - @JsonProperty("source") + @JsonProperty("reference") @ExcludeMissing - source: JsonField = JsonMissing.of(), + reference: JsonField = JsonMissing.of(), @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), - @JsonProperty("image_tag") - @ExcludeMissing - imageTag: JsonField = JsonMissing.of(), @JsonProperty("pass_threshold") @ExcludeMissing passThreshold: JsonField = JsonMissing.of(), - ) : this(name, source, type, imageTag, passThreshold, mutableMapOf()) + ) : this(evaluationMetric, input, name, reference, type, passThreshold, mutableMapOf()) + + fun toTextSimilarityGrader(): TextSimilarityGrader = + TextSimilarityGrader.builder() + .evaluationMetric(evaluationMetric) + .input(input) + .name(name) + .reference(reference) + .type(type) + .build() + + /** + * The evaluation metric to use. One of `fuzzy_match`, `bleu`, `gleu`, `meteor`, + * `rouge_1`, `rouge_2`, `rouge_3`, `rouge_4`, `rouge_5`, or `rouge_l`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun evaluationMetric(): TextSimilarityGrader.EvaluationMetric = + evaluationMetric.getRequired("evaluation_metric") + + /** + * The text being graded. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun input(): String = input.getRequired("input") /** * The name of the grader. @@ -1189,20 +1257,20 @@ private constructor( fun name(): String = name.getRequired("name") /** - * The source code of the python script. + * The text being graded against. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected * value). */ - fun source(): String = source.getRequired("source") + fun reference(): String = reference.getRequired("reference") /** - * The object type, which is always `python`. + * The type of grader. * * Expected to always return the following: * ```java - * JsonValue.from("python") + * JsonValue.from("text_similarity") * ``` * * However, this method can be useful for debugging and logging (e.g. if the server @@ -1211,42 +1279,48 @@ private constructor( @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type /** - * The image tag to use for the python script. + * The threshold for the score. * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). */ - fun imageTag(): Optional = imageTag.getOptional("image_tag") + fun passThreshold(): Double = passThreshold.getRequired("pass_threshold") /** - * The threshold for the score. + * Returns the raw JSON value of [evaluationMetric]. * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). + * Unlike [evaluationMetric], this method doesn't throw if the JSON field has an + * unexpected type. */ - fun passThreshold(): Optional = passThreshold.getOptional("pass_threshold") + @JsonProperty("evaluation_metric") + @ExcludeMissing + fun _evaluationMetric(): JsonField = + evaluationMetric /** - * Returns the raw JSON value of [name]. + * Returns the raw JSON value of [input]. * - * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [input], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + @JsonProperty("input") @ExcludeMissing fun _input(): JsonField = input /** - * Returns the raw JSON value of [source]. + * Returns the raw JSON value of [name]. * - * Unlike [source], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("source") @ExcludeMissing fun _source(): JsonField = source + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name /** - * Returns the raw JSON value of [imageTag]. + * Returns the raw JSON value of [reference]. * - * Unlike [imageTag], this method doesn't throw if the JSON field has an unexpected + * Unlike [reference], this method doesn't throw if the JSON field has an unexpected * type. */ - @JsonProperty("image_tag") @ExcludeMissing fun _imageTag(): JsonField = imageTag + @JsonProperty("reference") + @ExcludeMissing + fun _reference(): JsonField = reference /** * Returns the raw JSON value of [passThreshold]. @@ -1273,37 +1347,75 @@ private constructor( companion object { /** - * Returns a mutable builder for constructing an instance of [Python]. + * Returns a mutable builder for constructing an instance of + * [EvalGraderTextSimilarity]. * * The following fields are required: * ```java + * .evaluationMetric() + * .input() * .name() - * .source() + * .reference() + * .passThreshold() * ``` */ @JvmStatic fun builder() = Builder() } - /** A builder for [Python]. */ + /** A builder for [EvalGraderTextSimilarity]. */ class Builder internal constructor() { + private var evaluationMetric: JsonField? = + null + private var input: JsonField? = null private var name: JsonField? = null - private var source: JsonField? = null - private var type: JsonValue = JsonValue.from("python") - private var imageTag: JsonField = JsonMissing.of() - private var passThreshold: JsonField = JsonMissing.of() + private var reference: JsonField? = null + private var type: JsonValue = JsonValue.from("text_similarity") + private var passThreshold: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(python: Python) = apply { - name = python.name - source = python.source - type = python.type - imageTag = python.imageTag - passThreshold = python.passThreshold - additionalProperties = python.additionalProperties.toMutableMap() + internal fun from(evalGraderTextSimilarity: EvalGraderTextSimilarity) = apply { + evaluationMetric = evalGraderTextSimilarity.evaluationMetric + input = evalGraderTextSimilarity.input + name = evalGraderTextSimilarity.name + reference = evalGraderTextSimilarity.reference + type = evalGraderTextSimilarity.type + passThreshold = evalGraderTextSimilarity.passThreshold + additionalProperties = + evalGraderTextSimilarity.additionalProperties.toMutableMap() } + /** + * The evaluation metric to use. One of `fuzzy_match`, `bleu`, `gleu`, `meteor`, + * `rouge_1`, `rouge_2`, `rouge_3`, `rouge_4`, `rouge_5`, or `rouge_l`. + */ + fun evaluationMetric(evaluationMetric: TextSimilarityGrader.EvaluationMetric) = + evaluationMetric(JsonField.of(evaluationMetric)) + + /** + * Sets [Builder.evaluationMetric] to an arbitrary JSON value. + * + * You should usually call [Builder.evaluationMetric] with a well-typed + * [TextSimilarityGrader.EvaluationMetric] value instead. This method is primarily + * for setting the field to an undocumented or not yet supported value. + */ + fun evaluationMetric( + evaluationMetric: JsonField + ) = apply { this.evaluationMetric = evaluationMetric } + + /** The text being graded. */ + fun input(input: String) = input(JsonField.of(input)) + + /** + * Sets [Builder.input] to an arbitrary JSON value. + * + * You should usually call [Builder.input] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun input(input: JsonField) = apply { this.input = input } + /** The name of the grader. */ fun name(name: String) = name(JsonField.of(name)) @@ -1316,17 +1428,17 @@ private constructor( */ fun name(name: JsonField) = apply { this.name = name } - /** The source code of the python script. */ - fun source(source: String) = source(JsonField.of(source)) + /** The text being graded against. */ + fun reference(reference: String) = reference(JsonField.of(reference)) /** - * Sets [Builder.source] to an arbitrary JSON value. + * Sets [Builder.reference] to an arbitrary JSON value. * - * You should usually call [Builder.source] with a well-typed [String] value + * You should usually call [Builder.reference] with a well-typed [String] value * instead. This method is primarily for setting the field to an undocumented or not * yet supported value. */ - fun source(source: JsonField) = apply { this.source = source } + fun reference(reference: JsonField) = apply { this.reference = reference } /** * Sets the field to an arbitrary JSON value. @@ -1334,7 +1446,7 @@ private constructor( * It is usually unnecessary to call this method because the field defaults to the * following: * ```java - * JsonValue.from("python") + * JsonValue.from("text_similarity") * ``` * * This method is primarily for setting the field to an undocumented or not yet @@ -1342,18 +1454,6 @@ private constructor( */ fun type(type: JsonValue) = apply { this.type = type } - /** The image tag to use for the python script. */ - fun imageTag(imageTag: String) = imageTag(JsonField.of(imageTag)) - - /** - * Sets [Builder.imageTag] to an arbitrary JSON value. - * - * You should usually call [Builder.imageTag] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun imageTag(imageTag: JsonField) = apply { this.imageTag = imageTag } - /** The threshold for the score. */ fun passThreshold(passThreshold: Double) = passThreshold(JsonField.of(passThreshold)) @@ -1392,44 +1492,49 @@ private constructor( } /** - * Returns an immutable instance of [Python]. + * Returns an immutable instance of [EvalGraderTextSimilarity]. * * Further updates to this [Builder] will not mutate the returned instance. * * The following fields are required: * ```java + * .evaluationMetric() + * .input() * .name() - * .source() + * .reference() + * .passThreshold() * ``` * * @throws IllegalStateException if any required field is unset. */ - fun build(): Python = - Python( + fun build(): EvalGraderTextSimilarity = + EvalGraderTextSimilarity( + checkRequired("evaluationMetric", evaluationMetric), + checkRequired("input", input), checkRequired("name", name), - checkRequired("source", source), + checkRequired("reference", reference), type, - imageTag, - passThreshold, + checkRequired("passThreshold", passThreshold), additionalProperties.toMutableMap(), ) } private var validated: Boolean = false - fun validate(): Python = apply { + fun validate(): EvalGraderTextSimilarity = apply { if (validated) { return@apply } + evaluationMetric().validate() + input() name() - source() + reference() _type().let { - if (it != JsonValue.from("python")) { + if (it != JsonValue.from("text_similarity")) { throw OpenAIInvalidDataException("'type' is invalid, received $it") } } - imageTag() passThreshold() validated = true } @@ -1450,10 +1555,11 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (if (name.asKnown().isPresent) 1 else 0) + - (if (source.asKnown().isPresent) 1 else 0) + - type.let { if (it == JsonValue.from("python")) 1 else 0 } + - (if (imageTag.asKnown().isPresent) 1 else 0) + + (evaluationMetric.asKnown().getOrNull()?.validity() ?: 0) + + (if (input.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (if (reference.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("text_similarity")) 1 else 0 } + (if (passThreshold.asKnown().isPresent) 1 else 0) override fun equals(other: Any?): Boolean { @@ -1461,84 +1567,77 @@ private constructor( return true } - return /* spotless:off */ other is Python && name == other.name && source == other.source && type == other.type && imageTag == other.imageTag && passThreshold == other.passThreshold && additionalProperties == other.additionalProperties /* spotless:on */ + return /* spotless:off */ other is EvalGraderTextSimilarity && evaluationMetric == other.evaluationMetric && input == other.input && name == other.name && reference == other.reference && type == other.type && passThreshold == other.passThreshold && additionalProperties == other.additionalProperties /* spotless:on */ } /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(name, source, type, imageTag, passThreshold, additionalProperties) } + private val hashCode: Int by lazy { Objects.hash(evaluationMetric, input, name, reference, type, passThreshold, additionalProperties) } /* spotless:on */ override fun hashCode(): Int = hashCode override fun toString() = - "Python{name=$name, source=$source, type=$type, imageTag=$imageTag, passThreshold=$passThreshold, additionalProperties=$additionalProperties}" + "EvalGraderTextSimilarity{evaluationMetric=$evaluationMetric, input=$input, name=$name, reference=$reference, type=$type, passThreshold=$passThreshold, additionalProperties=$additionalProperties}" } - /** A ScoreModelGrader object that uses a model to assign a score to the input. */ - class ScoreModel + /** A PythonGrader object that runs a python script on the input. */ + class EvalGraderPython private constructor( - private val input: JsonField>, - private val model: JsonField, private val name: JsonField, + private val source: JsonField, private val type: JsonValue, + private val imageTag: JsonField, private val passThreshold: JsonField, - private val range: JsonField>, - private val samplingParams: JsonValue, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( - @JsonProperty("input") - @ExcludeMissing - input: JsonField> = JsonMissing.of(), - @JsonProperty("model") @ExcludeMissing model: JsonField = JsonMissing.of(), @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("source") + @ExcludeMissing + source: JsonField = JsonMissing.of(), @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + @JsonProperty("image_tag") + @ExcludeMissing + imageTag: JsonField = JsonMissing.of(), @JsonProperty("pass_threshold") @ExcludeMissing passThreshold: JsonField = JsonMissing.of(), - @JsonProperty("range") - @ExcludeMissing - range: JsonField> = JsonMissing.of(), - @JsonProperty("sampling_params") - @ExcludeMissing - samplingParams: JsonValue = JsonMissing.of(), - ) : this(input, model, name, type, passThreshold, range, samplingParams, mutableMapOf()) + ) : this(name, source, type, imageTag, passThreshold, mutableMapOf()) - /** - * The input text. This may include template strings. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected - * value). - */ - fun input(): List = input.getRequired("input") + fun toPythonGrader(): PythonGrader = + PythonGrader.builder() + .name(name) + .source(source) + .type(type) + .imageTag(imageTag) + .build() /** - * The model to use for the evaluation. + * The name of the grader. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected * value). */ - fun model(): String = model.getRequired("model") + fun name(): String = name.getRequired("name") /** - * The name of the grader. + * The source code of the python script. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected * value). */ - fun name(): String = name.getRequired("name") + fun source(): String = source.getRequired("source") /** - * The object type, which is always `score_model`. + * The object type, which is always `python`. * * Expected to always return the following: * ```java - * JsonValue.from("score_model") + * JsonValue.from("python") * ``` * * However, this method can be useful for debugging and logging (e.g. if the server @@ -1547,46 +1646,42 @@ private constructor( @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type /** - * The threshold for the score. + * The image tag to use for the python script. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). */ - fun passThreshold(): Optional = passThreshold.getOptional("pass_threshold") + fun imageTag(): Optional = imageTag.getOptional("image_tag") /** - * The range of the score. Defaults to `[0, 1]`. + * The threshold for the score. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). */ - fun range(): Optional> = range.getOptional("range") - - /** The sampling parameters for the model. */ - @JsonProperty("sampling_params") - @ExcludeMissing - fun _samplingParams(): JsonValue = samplingParams + fun passThreshold(): Optional = passThreshold.getOptional("pass_threshold") /** - * Returns the raw JSON value of [input]. + * Returns the raw JSON value of [name]. * - * Unlike [input], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("input") @ExcludeMissing fun _input(): JsonField> = input + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name /** - * Returns the raw JSON value of [model]. + * Returns the raw JSON value of [source]. * - * Unlike [model], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [source], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("model") @ExcludeMissing fun _model(): JsonField = model + @JsonProperty("source") @ExcludeMissing fun _source(): JsonField = source /** - * Returns the raw JSON value of [name]. + * Returns the raw JSON value of [imageTag]. * - * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [imageTag], this method doesn't throw if the JSON field has an unexpected + * type. */ - @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + @JsonProperty("image_tag") @ExcludeMissing fun _imageTag(): JsonField = imageTag /** * Returns the raw JSON value of [passThreshold]. @@ -1598,13 +1693,6 @@ private constructor( @ExcludeMissing fun _passThreshold(): JsonField = passThreshold - /** - * Returns the raw JSON value of [range]. - * - * Unlike [range], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("range") @ExcludeMissing fun _range(): JsonField> = range - @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { additionalProperties.put(key, value) @@ -1620,80 +1708,37 @@ private constructor( companion object { /** - * Returns a mutable builder for constructing an instance of [ScoreModel]. + * Returns a mutable builder for constructing an instance of [EvalGraderPython]. * * The following fields are required: * ```java - * .input() - * .model() * .name() + * .source() * ``` */ @JvmStatic fun builder() = Builder() } - /** A builder for [ScoreModel]. */ + /** A builder for [EvalGraderPython]. */ class Builder internal constructor() { - private var input: JsonField>? = null - private var model: JsonField? = null private var name: JsonField? = null - private var type: JsonValue = JsonValue.from("score_model") + private var source: JsonField? = null + private var type: JsonValue = JsonValue.from("python") + private var imageTag: JsonField = JsonMissing.of() private var passThreshold: JsonField = JsonMissing.of() - private var range: JsonField>? = null - private var samplingParams: JsonValue = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(scoreModel: ScoreModel) = apply { - input = scoreModel.input.map { it.toMutableList() } - model = scoreModel.model - name = scoreModel.name - type = scoreModel.type - passThreshold = scoreModel.passThreshold - range = scoreModel.range.map { it.toMutableList() } - samplingParams = scoreModel.samplingParams - additionalProperties = scoreModel.additionalProperties.toMutableMap() - } - - /** The input text. This may include template strings. */ - fun input(input: List) = input(JsonField.of(input)) - - /** - * Sets [Builder.input] to an arbitrary JSON value. - * - * You should usually call [Builder.input] with a well-typed `List` value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun input(input: JsonField>) = apply { - this.input = input.map { it.toMutableList() } - } - - /** - * Adds a single [Input] to [Builder.input]. - * - * @throws IllegalStateException if the field was previously set to a non-list. - */ - fun addInput(input: Input) = apply { - this.input = - (this.input ?: JsonField.of(mutableListOf())).also { - checkKnown("input", it).add(input) - } + internal fun from(evalGraderPython: EvalGraderPython) = apply { + name = evalGraderPython.name + source = evalGraderPython.source + type = evalGraderPython.type + imageTag = evalGraderPython.imageTag + passThreshold = evalGraderPython.passThreshold + additionalProperties = evalGraderPython.additionalProperties.toMutableMap() } - /** The model to use for the evaluation. */ - 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) = apply { this.model = model } - /** The name of the grader. */ fun name(name: String) = name(JsonField.of(name)) @@ -1706,8 +1751,410 @@ private constructor( */ fun name(name: JsonField) = apply { this.name = name } + /** The source code of the python script. */ + fun source(source: String) = source(JsonField.of(source)) + /** - * Sets the field to an arbitrary JSON value. + * Sets [Builder.source] to an arbitrary JSON value. + * + * You should usually call [Builder.source] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun source(source: JsonField) = apply { this.source = source } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("python") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + /** The image tag to use for the python script. */ + fun imageTag(imageTag: String) = imageTag(JsonField.of(imageTag)) + + /** + * Sets [Builder.imageTag] to an arbitrary JSON value. + * + * You should usually call [Builder.imageTag] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun imageTag(imageTag: JsonField) = apply { this.imageTag = imageTag } + + /** The threshold for the score. */ + fun passThreshold(passThreshold: Double) = + passThreshold(JsonField.of(passThreshold)) + + /** + * Sets [Builder.passThreshold] to an arbitrary JSON value. + * + * You should usually call [Builder.passThreshold] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun passThreshold(passThreshold: JsonField) = apply { + this.passThreshold = passThreshold + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [EvalGraderPython]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * .source() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): EvalGraderPython = + EvalGraderPython( + checkRequired("name", name), + checkRequired("source", source), + type, + imageTag, + passThreshold, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): EvalGraderPython = apply { + if (validated) { + return@apply + } + + name() + source() + _type().let { + if (it != JsonValue.from("python")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + imageTag() + passThreshold() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (name.asKnown().isPresent) 1 else 0) + + (if (source.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("python")) 1 else 0 } + + (if (imageTag.asKnown().isPresent) 1 else 0) + + (if (passThreshold.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is EvalGraderPython && name == other.name && source == other.source && type == other.type && imageTag == other.imageTag && passThreshold == other.passThreshold && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, source, type, imageTag, passThreshold, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "EvalGraderPython{name=$name, source=$source, type=$type, imageTag=$imageTag, passThreshold=$passThreshold, additionalProperties=$additionalProperties}" + } + + /** A ScoreModelGrader object that uses a model to assign a score to the input. */ + class EvalGraderScoreModel + private constructor( + private val input: JsonField>, + private val model: JsonField, + private val name: JsonField, + private val type: JsonValue, + private val range: JsonField>, + private val samplingParams: JsonValue, + private val passThreshold: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("input") + @ExcludeMissing + input: JsonField> = JsonMissing.of(), + @JsonProperty("model") @ExcludeMissing model: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + @JsonProperty("range") + @ExcludeMissing + range: JsonField> = JsonMissing.of(), + @JsonProperty("sampling_params") + @ExcludeMissing + samplingParams: JsonValue = JsonMissing.of(), + @JsonProperty("pass_threshold") + @ExcludeMissing + passThreshold: JsonField = JsonMissing.of(), + ) : this(input, model, name, type, range, samplingParams, passThreshold, mutableMapOf()) + + fun toScoreModelGrader(): ScoreModelGrader = + ScoreModelGrader.builder() + .input(input) + .model(model) + .name(name) + .type(type) + .range(range) + .samplingParams(samplingParams) + .build() + + /** + * The input text. This may include template strings. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun input(): List = input.getRequired("input") + + /** + * The model to use for the evaluation. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun model(): String = model.getRequired("model") + + /** + * The name of the grader. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun name(): String = name.getRequired("name") + + /** + * The object type, which is always `score_model`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("score_model") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * The range of the score. Defaults to `[0, 1]`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun range(): Optional> = range.getOptional("range") + + /** The sampling parameters for the model. */ + @JsonProperty("sampling_params") + @ExcludeMissing + fun _samplingParams(): JsonValue = samplingParams + + /** + * The threshold for the score. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun passThreshold(): Optional = passThreshold.getOptional("pass_threshold") + + /** + * Returns the raw JSON value of [input]. + * + * Unlike [input], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("input") + @ExcludeMissing + fun _input(): JsonField> = input + + /** + * 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 = model + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [range]. + * + * Unlike [range], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("range") @ExcludeMissing fun _range(): JsonField> = range + + /** + * Returns the raw JSON value of [passThreshold]. + * + * Unlike [passThreshold], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("pass_threshold") + @ExcludeMissing + fun _passThreshold(): JsonField = passThreshold + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [EvalGraderScoreModel]. + * + * The following fields are required: + * ```java + * .input() + * .model() + * .name() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [EvalGraderScoreModel]. */ + class Builder internal constructor() { + + private var input: JsonField>? = null + private var model: JsonField? = null + private var name: JsonField? = null + private var type: JsonValue = JsonValue.from("score_model") + private var range: JsonField>? = null + private var samplingParams: JsonValue = JsonMissing.of() + private var passThreshold: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(evalGraderScoreModel: EvalGraderScoreModel) = apply { + input = evalGraderScoreModel.input.map { it.toMutableList() } + model = evalGraderScoreModel.model + name = evalGraderScoreModel.name + type = evalGraderScoreModel.type + range = evalGraderScoreModel.range.map { it.toMutableList() } + samplingParams = evalGraderScoreModel.samplingParams + passThreshold = evalGraderScoreModel.passThreshold + additionalProperties = evalGraderScoreModel.additionalProperties.toMutableMap() + } + + /** The input text. This may include template strings. */ + fun input(input: List) = input(JsonField.of(input)) + + /** + * Sets [Builder.input] to an arbitrary JSON value. + * + * You should usually call [Builder.input] with a well-typed + * `List` value instead. This method is primarily for + * setting the field to an undocumented or not yet supported value. + */ + fun input(input: JsonField>) = apply { + this.input = input.map { it.toMutableList() } + } + + /** + * Adds a single [ScoreModelGrader.Input] to [Builder.input]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addInput(input: ScoreModelGrader.Input) = apply { + this.input = + (this.input ?: JsonField.of(mutableListOf())).also { + checkKnown("input", it).add(input) + } + } + + /** The model to use for the evaluation. */ + 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) = apply { this.model = model } + + /** The name of the grader. */ + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** + * Sets the field to an arbitrary JSON value. * * It is usually unnecessary to call this method because the field defaults to the * following: @@ -1720,21 +2167,6 @@ private constructor( */ fun type(type: JsonValue) = apply { this.type = type } - /** The threshold for the score. */ - fun passThreshold(passThreshold: Double) = - passThreshold(JsonField.of(passThreshold)) - - /** - * Sets [Builder.passThreshold] to an arbitrary JSON value. - * - * You should usually call [Builder.passThreshold] with a well-typed [Double] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun passThreshold(passThreshold: JsonField) = apply { - this.passThreshold = passThreshold - } - /** The range of the score. Defaults to `[0, 1]`. */ fun range(range: List) = range(JsonField.of(range)) @@ -1766,6 +2198,21 @@ private constructor( this.samplingParams = samplingParams } + /** The threshold for the score. */ + fun passThreshold(passThreshold: Double) = + passThreshold(JsonField.of(passThreshold)) + + /** + * Sets [Builder.passThreshold] to an arbitrary JSON value. + * + * You should usually call [Builder.passThreshold] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun passThreshold(passThreshold: JsonField) = apply { + this.passThreshold = passThreshold + } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() putAllAdditionalProperties(additionalProperties) @@ -1789,7 +2236,7 @@ private constructor( } /** - * Returns an immutable instance of [ScoreModel]. + * Returns an immutable instance of [EvalGraderScoreModel]. * * Further updates to this [Builder] will not mutate the returned instance. * @@ -1802,22 +2249,22 @@ private constructor( * * @throws IllegalStateException if any required field is unset. */ - fun build(): ScoreModel = - ScoreModel( + fun build(): EvalGraderScoreModel = + EvalGraderScoreModel( checkRequired("input", input).map { it.toImmutable() }, checkRequired("model", model), checkRequired("name", name), type, - passThreshold, (range ?: JsonMissing.of()).map { it.toImmutable() }, samplingParams, + passThreshold, additionalProperties.toMutableMap(), ) } private var validated: Boolean = false - fun validate(): ScoreModel = apply { + fun validate(): EvalGraderScoreModel = apply { if (validated) { return@apply } @@ -1830,8 +2277,8 @@ private constructor( throw OpenAIInvalidDataException("'type' is invalid, received $it") } } - passThreshold() range() + passThreshold() validated = true } @@ -1855,1003 +2302,25 @@ private constructor( (if (model.asKnown().isPresent) 1 else 0) + (if (name.asKnown().isPresent) 1 else 0) + type.let { if (it == JsonValue.from("score_model")) 1 else 0 } + - (if (passThreshold.asKnown().isPresent) 1 else 0) + - (range.asKnown().getOrNull()?.size ?: 0) - - /** - * A message input to the model with a role indicating instruction following hierarchy. - * Instructions given with the `developer` or `system` role take precedence over - * instructions given with the `user` role. Messages with the `assistant` role are - * presumed to have been generated by the model in previous interactions. - */ - class Input - private constructor( - private val content: JsonField, - private val role: JsonField, - private val type: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("content") - @ExcludeMissing - content: JsonField = JsonMissing.of(), - @JsonProperty("role") @ExcludeMissing role: JsonField = JsonMissing.of(), - @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), - ) : this(content, role, type, mutableMapOf()) - - /** - * Text inputs to the model - can contain template strings. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected - * value). - */ - fun content(): Content = content.getRequired("content") - - /** - * The role of the message input. One of `user`, `assistant`, `system`, or - * `developer`. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected - * value). - */ - fun role(): Role = role.getRequired("role") - - /** - * The type of the message input. Always `message`. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun type(): Optional = type.getOptional("type") - - /** - * Returns the raw JSON value of [content]. - * - * Unlike [content], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("content") - @ExcludeMissing - fun _content(): JsonField = content - - /** - * Returns the raw JSON value of [role]. - * - * Unlike [role], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("role") @ExcludeMissing fun _role(): JsonField = role - - /** - * Returns the raw JSON value of [type]. - * - * Unlike [type], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** - * Returns a mutable builder for constructing an instance of [Input]. - * - * The following fields are required: - * ```java - * .content() - * .role() - * ``` - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Input]. */ - class Builder internal constructor() { - - private var content: JsonField? = null - private var role: JsonField? = null - private var type: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(input: Input) = apply { - content = input.content - role = input.role - type = input.type - additionalProperties = input.additionalProperties.toMutableMap() - } - - /** Text inputs to the model - can contain template strings. */ - fun content(content: Content) = content(JsonField.of(content)) - - /** - * Sets [Builder.content] to an arbitrary JSON value. - * - * You should usually call [Builder.content] with a well-typed [Content] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun content(content: JsonField) = apply { this.content = content } - - /** Alias for calling [content] with `Content.ofTextInput(textInput)`. */ - fun content(textInput: String) = content(Content.ofTextInput(textInput)) - - /** - * Alias for calling [content] with - * `Content.ofResponseInputText(responseInputText)`. - */ - fun content(responseInputText: ResponseInputText) = - content(Content.ofResponseInputText(responseInputText)) - - /** Alias for calling [content] with `Content.ofOutputText(outputText)`. */ - fun content(outputText: Content.OutputText) = - content(Content.ofOutputText(outputText)) - - /** - * The role of the message input. One of `user`, `assistant`, `system`, or - * `developer`. - */ - fun role(role: Role) = role(JsonField.of(role)) - - /** - * Sets [Builder.role] to an arbitrary JSON value. - * - * You should usually call [Builder.role] with a well-typed [Role] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun role(role: JsonField) = apply { this.role = role } - - /** The type of the message input. Always `message`. */ - fun type(type: Type) = type(JsonField.of(type)) - - /** - * Sets [Builder.type] to an arbitrary JSON value. - * - * You should usually call [Builder.type] with a well-typed [Type] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun type(type: JsonField) = apply { this.type = type } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [Input]. - * - * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .content() - * .role() - * ``` - * - * @throws IllegalStateException if any required field is unset. - */ - fun build(): Input = - Input( - checkRequired("content", content), - checkRequired("role", role), - type, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): Input = apply { - if (validated) { - return@apply - } - - content().validate() - role().validate() - type().ifPresent { it.validate() } - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (content.asKnown().getOrNull()?.validity() ?: 0) + - (role.asKnown().getOrNull()?.validity() ?: 0) + - (type.asKnown().getOrNull()?.validity() ?: 0) - - /** Text inputs to the model - can contain template strings. */ - @JsonDeserialize(using = Content.Deserializer::class) - @JsonSerialize(using = Content.Serializer::class) - class Content - private constructor( - private val textInput: String? = null, - private val responseInputText: ResponseInputText? = null, - private val outputText: OutputText? = null, - private val _json: JsonValue? = null, - ) { - - /** A text input to the model. */ - fun textInput(): Optional = Optional.ofNullable(textInput) - - /** A text input to the model. */ - fun responseInputText(): Optional = - Optional.ofNullable(responseInputText) - - /** A text output from the model. */ - fun outputText(): Optional = Optional.ofNullable(outputText) - - fun isTextInput(): Boolean = textInput != null - - fun isResponseInputText(): Boolean = responseInputText != null - - fun isOutputText(): Boolean = outputText != null - - /** A text input to the model. */ - fun asTextInput(): String = textInput.getOrThrow("textInput") - - /** A text input to the model. */ - fun asResponseInputText(): ResponseInputText = - responseInputText.getOrThrow("responseInputText") - - /** A text output from the model. */ - fun asOutputText(): OutputText = outputText.getOrThrow("outputText") - - fun _json(): Optional = Optional.ofNullable(_json) - - fun accept(visitor: Visitor): T = - when { - textInput != null -> visitor.visitTextInput(textInput) - responseInputText != null -> - visitor.visitResponseInputText(responseInputText) - outputText != null -> visitor.visitOutputText(outputText) - else -> visitor.unknown(_json) - } - - private var validated: Boolean = false - - fun validate(): Content = apply { - if (validated) { - return@apply - } - - accept( - object : Visitor { - override fun visitTextInput(textInput: String) {} - - override fun visitResponseInputText( - responseInputText: ResponseInputText - ) { - responseInputText.validate() - } - - override fun visitOutputText(outputText: OutputText) { - outputText.validate() - } - } - ) - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - accept( - object : Visitor { - override fun visitTextInput(textInput: String) = 1 - - override fun visitResponseInputText( - responseInputText: ResponseInputText - ) = responseInputText.validity() - - override fun visitOutputText(outputText: OutputText) = - outputText.validity() - - override fun unknown(json: JsonValue?) = 0 - } - ) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is Content && textInput == other.textInput && responseInputText == other.responseInputText && outputText == other.outputText /* spotless:on */ - } - - override fun hashCode(): Int = /* spotless:off */ Objects.hash(textInput, responseInputText, outputText) /* spotless:on */ - - override fun toString(): String = - when { - textInput != null -> "Content{textInput=$textInput}" - responseInputText != null -> - "Content{responseInputText=$responseInputText}" - outputText != null -> "Content{outputText=$outputText}" - _json != null -> "Content{_unknown=$_json}" - else -> throw IllegalStateException("Invalid Content") - } - - companion object { - - /** A text input to the model. */ - @JvmStatic - fun ofTextInput(textInput: String) = Content(textInput = textInput) - - /** A text input to the model. */ - @JvmStatic - fun ofResponseInputText(responseInputText: ResponseInputText) = - Content(responseInputText = responseInputText) - - /** A text output from the model. */ - @JvmStatic - fun ofOutputText(outputText: OutputText) = Content(outputText = outputText) - } - - /** - * An interface that defines how to map each variant of [Content] to a value of - * type [T]. - */ - interface Visitor { - - /** A text input to the model. */ - fun visitTextInput(textInput: String): T - - /** A text input to the model. */ - fun visitResponseInputText(responseInputText: ResponseInputText): T - - /** A text output from the model. */ - fun visitOutputText(outputText: OutputText): T - - /** - * Maps an unknown variant of [Content] to a value of type [T]. - * - * An instance of [Content] can contain an unknown variant if it was - * deserialized from data that doesn't match any known variant. For example, - * if the SDK is on an older version than the API, then the API may respond - * with new variants that the SDK is unaware of. - * - * @throws OpenAIInvalidDataException in the default implementation. - */ - fun unknown(json: JsonValue?): T { - throw OpenAIInvalidDataException("Unknown Content: $json") - } - } - - internal class Deserializer : BaseDeserializer(Content::class) { - - override fun ObjectCodec.deserialize(node: JsonNode): Content { - val json = JsonValue.fromJsonNode(node) - - val bestMatches = - sequenceOf( - tryDeserialize(node, jacksonTypeRef()) - ?.let { Content(responseInputText = it, _json = json) }, - tryDeserialize(node, jacksonTypeRef())?.let { - Content(outputText = it, _json = json) - }, - tryDeserialize(node, jacksonTypeRef())?.let { - Content(textInput = it, _json = json) - }, - ) - .filterNotNull() - .allMaxBy { it.validity() } - .toList() - return when (bestMatches.size) { - // This can happen if what we're deserializing is completely - // incompatible with all the possible variants (e.g. deserializing - // from array). - 0 -> Content(_json = json) - 1 -> bestMatches.single() - // If there's more than one match with the highest validity, then - // use the first completely valid match, or simply the first match - // if none are completely valid. - else -> - bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() - } - } - } - - internal class Serializer : BaseSerializer(Content::class) { - - override fun serialize( - value: Content, - generator: JsonGenerator, - provider: SerializerProvider, - ) { - when { - value.textInput != null -> generator.writeObject(value.textInput) - value.responseInputText != null -> - generator.writeObject(value.responseInputText) - value.outputText != null -> generator.writeObject(value.outputText) - value._json != null -> generator.writeObject(value._json) - else -> throw IllegalStateException("Invalid Content") - } - } - } - - /** A text output from the model. */ - class OutputText - private constructor( - private val text: JsonField, - private val type: JsonValue, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("text") - @ExcludeMissing - text: JsonField = JsonMissing.of(), - @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), - ) : this(text, type, mutableMapOf()) - - /** - * The text output from the model. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected - * type or is unexpectedly missing or null (e.g. if the server responded - * with an unexpected value). - */ - fun text(): String = text.getRequired("text") - - /** - * The type of the output text. Always `output_text`. - * - * Expected to always return the following: - * ```java - * JsonValue.from("output_text") - * ``` - * - * However, this method can be useful for debugging and logging (e.g. if the - * server responded with an unexpected value). - */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type - - /** - * Returns the raw JSON value of [text]. - * - * Unlike [text], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("text") @ExcludeMissing fun _text(): JsonField = text - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** - * Returns a mutable builder for constructing an instance of - * [OutputText]. - * - * The following fields are required: - * ```java - * .text() - * ``` - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [OutputText]. */ - class Builder internal constructor() { - - private var text: JsonField? = null - private var type: JsonValue = JsonValue.from("output_text") - private var additionalProperties: MutableMap = - mutableMapOf() - - @JvmSynthetic - internal fun from(outputText: OutputText) = apply { - text = outputText.text - type = outputText.type - additionalProperties = - outputText.additionalProperties.toMutableMap() - } - - /** The text output from the model. */ - fun text(text: String) = text(JsonField.of(text)) - - /** - * Sets [Builder.text] to an arbitrary JSON value. - * - * You should usually call [Builder.text] with a well-typed [String] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun text(text: JsonField) = apply { this.text = text } - - /** - * Sets the field to an arbitrary JSON value. - * - * It is usually unnecessary to call this method because the field - * defaults to the following: - * ```java - * JsonValue.from("output_text") - * ``` - * - * This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun type(type: JsonValue) = apply { this.type = type } - - fun additionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties( - additionalProperties: Map - ) = apply { this.additionalProperties.putAll(additionalProperties) } - - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [OutputText]. - * - * Further updates to this [Builder] will not mutate the returned - * instance. - * - * The following fields are required: - * ```java - * .text() - * ``` - * - * @throws IllegalStateException if any required field is unset. - */ - fun build(): OutputText = - OutputText( - checkRequired("text", text), - type, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): OutputText = apply { - if (validated) { - return@apply - } - - text() - _type().let { - if (it != JsonValue.from("output_text")) { - throw OpenAIInvalidDataException( - "'type' is invalid, received $it" - ) - } - } - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this - * object recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (if (text.asKnown().isPresent) 1 else 0) + - type.let { if (it == JsonValue.from("output_text")) 1 else 0 } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is OutputText && text == other.text && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ - } - - /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(text, type, additionalProperties) } - /* spotless:on */ - - override fun hashCode(): Int = hashCode - - override fun toString() = - "OutputText{text=$text, type=$type, additionalProperties=$additionalProperties}" - } - } - - /** - * The role of the message input. One of `user`, `assistant`, `system`, or - * `developer`. - */ - class Role @JsonCreator private constructor(private val value: JsonField) : - Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that - * doesn't match any known member, and you want to know that value. For example, - * if the SDK is on an older version than the API, then the API may respond with - * new members that the SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue - fun _value(): JsonField = value - - companion object { - - @JvmField val USER = of("user") - - @JvmField val ASSISTANT = of("assistant") - - @JvmField val SYSTEM = of("system") - - @JvmField val DEVELOPER = of("developer") - - @JvmStatic fun of(value: String) = Role(JsonField.of(value)) - } - - /** An enum containing [Role]'s known values. */ - enum class Known { - USER, - ASSISTANT, - SYSTEM, - DEVELOPER, - } - - /** - * An enum containing [Role]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Role] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For - * example, if the SDK is on an older version than the API, then the API may - * respond with new members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - USER, - ASSISTANT, - SYSTEM, - DEVELOPER, - /** - * An enum member indicating that [Role] was instantiated with an unknown - * value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or - * if you want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - USER -> Value.USER - ASSISTANT -> Value.ASSISTANT - SYSTEM -> Value.SYSTEM - DEVELOPER -> Value.DEVELOPER - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known - * and don't want to throw for the unknown case. - * - * @throws OpenAIInvalidDataException if this class instance's value is a not a - * known member. - */ - fun known(): Known = - when (this) { - USER -> Known.USER - ASSISTANT -> Known.ASSISTANT - SYSTEM -> Known.SYSTEM - DEVELOPER -> Known.DEVELOPER - else -> throw OpenAIInvalidDataException("Unknown Role: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for - * debugging and generally doesn't throw. - * - * @throws OpenAIInvalidDataException if this class instance's value does not - * have the expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - OpenAIInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): Role = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is Role && value == other.value /* spotless:on */ - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - /** The type of the message input. Always `message`. */ - class Type @JsonCreator private constructor(private val value: JsonField) : - Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that - * doesn't match any known member, and you want to know that value. For example, - * if the SDK is on an older version than the API, then the API may respond with - * new members that the SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue - fun _value(): JsonField = value - - companion object { - - @JvmField val MESSAGE = of("message") - - @JvmStatic fun of(value: String) = Type(JsonField.of(value)) - } - - /** An enum containing [Type]'s known values. */ - enum class Known { - MESSAGE - } - - /** - * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Type] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For - * example, if the SDK is on an older version than the API, then the API may - * respond with new members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - MESSAGE, - /** - * An enum member indicating that [Type] was instantiated with an unknown - * value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or - * if you want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - MESSAGE -> Value.MESSAGE - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known - * and don't want to throw for the unknown case. - * - * @throws OpenAIInvalidDataException if this class instance's value is a not a - * known member. - */ - fun known(): Known = - when (this) { - MESSAGE -> Known.MESSAGE - else -> throw OpenAIInvalidDataException("Unknown Type: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for - * debugging and generally doesn't throw. - * - * @throws OpenAIInvalidDataException if this class instance's value does not - * have the expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - OpenAIInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): Type = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is Type && value == other.value /* spotless:on */ - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is Input && content == other.content && role == other.role && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ - } - - /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(content, role, type, additionalProperties) } - /* spotless:on */ - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Input{content=$content, role=$role, type=$type, additionalProperties=$additionalProperties}" - } + (range.asKnown().getOrNull()?.size ?: 0) + + (if (passThreshold.asKnown().isPresent) 1 else 0) override fun equals(other: Any?): Boolean { if (this === other) { return true } - return /* spotless:off */ other is ScoreModel && input == other.input && model == other.model && name == other.name && type == other.type && passThreshold == other.passThreshold && range == other.range && samplingParams == other.samplingParams && additionalProperties == other.additionalProperties /* spotless:on */ + return /* spotless:off */ other is EvalGraderScoreModel && input == other.input && model == other.model && name == other.name && type == other.type && range == other.range && samplingParams == other.samplingParams && passThreshold == other.passThreshold && additionalProperties == other.additionalProperties /* spotless:on */ } /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(input, model, name, type, passThreshold, range, samplingParams, additionalProperties) } + private val hashCode: Int by lazy { Objects.hash(input, model, name, type, range, samplingParams, passThreshold, additionalProperties) } /* spotless:on */ override fun hashCode(): Int = hashCode override fun toString() = - "ScoreModel{input=$input, model=$model, name=$name, type=$type, passThreshold=$passThreshold, range=$range, samplingParams=$samplingParams, additionalProperties=$additionalProperties}" + "EvalGraderScoreModel{input=$input, model=$model, name=$name, type=$type, range=$range, samplingParams=$samplingParams, passThreshold=$passThreshold, additionalProperties=$additionalProperties}" } } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunCancelParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunCancelParams.kt index 63c37ab0..05903cbd 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunCancelParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunCancelParams.kt @@ -10,12 +10,13 @@ import com.openai.core.http.QueryParams import com.openai.core.toImmutable import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** Cancel an ongoing evaluation run. */ class RunCancelParams private constructor( private val evalId: String, - private val runId: String, + private val runId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, @@ -23,7 +24,7 @@ private constructor( fun evalId(): String = evalId - fun runId(): String = runId + fun runId(): Optional = Optional.ofNullable(runId) fun _additionalBodyProperties(): Map = additionalBodyProperties @@ -41,7 +42,6 @@ private constructor( * The following fields are required: * ```java * .evalId() - * .runId() * ``` */ @JvmStatic fun builder() = Builder() @@ -67,7 +67,10 @@ private constructor( fun evalId(evalId: String) = apply { this.evalId = evalId } - fun runId(runId: String) = apply { this.runId = runId } + fun runId(runId: String?) = apply { this.runId = runId } + + /** Alias for calling [Builder.runId] with `runId.orElse(null)`. */ + fun runId(runId: Optional) = runId(runId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -197,7 +200,6 @@ private constructor( * The following fields are required: * ```java * .evalId() - * .runId() * ``` * * @throws IllegalStateException if any required field is unset. @@ -205,7 +207,7 @@ private constructor( fun build(): RunCancelParams = RunCancelParams( checkRequired("evalId", evalId), - checkRequired("runId", runId), + runId, additionalHeaders.build(), additionalQueryParams.build(), additionalBodyProperties.toImmutable(), @@ -218,7 +220,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { 0 -> evalId - 1 -> runId + 1 -> runId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunCreateParams.kt index 952e12ba..a50d3f6d 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunCreateParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunCreateParams.kt @@ -39,13 +39,13 @@ import kotlin.jvm.optionals.getOrNull /** Create a new evaluation run. This is the endpoint that will kick off grading. */ class RunCreateParams private constructor( - private val evalId: String, + private val evalId: String?, private val body: Body, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun evalId(): String = evalId + fun evalId(): Optional = Optional.ofNullable(evalId) /** * Details about the run's data source. @@ -112,7 +112,6 @@ private constructor( * * The following fields are required: * ```java - * .evalId() * .dataSource() * ``` */ @@ -135,7 +134,10 @@ private constructor( additionalQueryParams = runCreateParams.additionalQueryParams.toBuilder() } - fun evalId(evalId: String) = apply { this.evalId = evalId } + fun evalId(evalId: String?) = apply { this.evalId = evalId } + + /** Alias for calling [Builder.evalId] with `evalId.orElse(null)`. */ + fun evalId(evalId: Optional) = evalId(evalId.getOrNull()) /** * Sets the entire request body. @@ -342,7 +344,6 @@ private constructor( * * The following fields are required: * ```java - * .evalId() * .dataSource() * ``` * @@ -350,7 +351,7 @@ private constructor( */ fun build(): RunCreateParams = RunCreateParams( - checkRequired("evalId", evalId), + evalId, body.build(), additionalHeaders.build(), additionalQueryParams.build(), @@ -361,7 +362,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> evalId + 0 -> evalId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunDeleteParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunDeleteParams.kt index 2214b0d2..784ca9c0 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunDeleteParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunDeleteParams.kt @@ -10,12 +10,13 @@ import com.openai.core.http.QueryParams import com.openai.core.toImmutable import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** Delete an eval run. */ class RunDeleteParams private constructor( private val evalId: String, - private val runId: String, + private val runId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, @@ -23,7 +24,7 @@ private constructor( fun evalId(): String = evalId - fun runId(): String = runId + fun runId(): Optional = Optional.ofNullable(runId) fun _additionalBodyProperties(): Map = additionalBodyProperties @@ -41,7 +42,6 @@ private constructor( * The following fields are required: * ```java * .evalId() - * .runId() * ``` */ @JvmStatic fun builder() = Builder() @@ -67,7 +67,10 @@ private constructor( fun evalId(evalId: String) = apply { this.evalId = evalId } - fun runId(runId: String) = apply { this.runId = runId } + fun runId(runId: String?) = apply { this.runId = runId } + + /** Alias for calling [Builder.runId] with `runId.orElse(null)`. */ + fun runId(runId: Optional) = runId(runId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -197,7 +200,6 @@ private constructor( * The following fields are required: * ```java * .evalId() - * .runId() * ``` * * @throws IllegalStateException if any required field is unset. @@ -205,7 +207,7 @@ private constructor( fun build(): RunDeleteParams = RunDeleteParams( checkRequired("evalId", evalId), - checkRequired("runId", runId), + runId, additionalHeaders.build(), additionalQueryParams.build(), additionalBodyProperties.toImmutable(), @@ -218,7 +220,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { 0 -> evalId - 1 -> runId + 1 -> runId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunListPage.kt b/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunListPage.kt index ca22d061..4e9fc0d7 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunListPage.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunListPage.kt @@ -2,12 +2,12 @@ package com.openai.models.evals.runs +import com.openai.core.AutoPager +import com.openai.core.Page import com.openai.core.checkRequired import com.openai.services.blocking.evals.RunService import java.util.Objects import java.util.Optional -import java.util.stream.Stream -import java.util.stream.StreamSupport import kotlin.jvm.optionals.getOrNull /** @see [RunService.list] */ @@ -16,7 +16,7 @@ private constructor( private val service: RunService, private val params: RunListParams, private val response: RunListPageResponse, -) { +) : Page { /** * Delegates to [RunListPageResponse], but gracefully handles missing data. @@ -33,19 +33,16 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): RunListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): Optional = getNextPageParams().map { service.list(it) } + override fun nextPage(): RunListPage = service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPager = AutoPager.from(this) /** The parameters that were used to request this page. */ fun params(): RunListParams = params @@ -114,25 +111,6 @@ private constructor( ) } - class AutoPager(private val firstPage: RunListPage) : Iterable { - - override fun iterator(): Iterator = iterator { - var page = firstPage - var index = 0 - while (true) { - while (index < page.data().size) { - yield(page.data()[index++]) - } - page = page.getNextPage().getOrNull() ?: break - index = 0 - } - } - - fun stream(): Stream { - return StreamSupport.stream(spliterator(), false) - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunListPageAsync.kt b/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunListPageAsync.kt index f159f392..a914663d 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunListPageAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunListPageAsync.kt @@ -2,22 +2,24 @@ package com.openai.models.evals.runs +import com.openai.core.AutoPagerAsync +import com.openai.core.PageAsync import com.openai.core.checkRequired import com.openai.services.async.evals.RunServiceAsync import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor -import java.util.function.Predicate import kotlin.jvm.optionals.getOrNull /** @see [RunServiceAsync.list] */ class RunListPageAsync private constructor( private val service: RunServiceAsync, + private val streamHandlerExecutor: Executor, private val params: RunListParams, private val response: RunListPageResponse, -) { +) : PageAsync { /** * Delegates to [RunListPageResponse], but gracefully handles missing data. @@ -34,22 +36,17 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): RunListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): CompletableFuture> = - getNextPageParams() - .map { service.list(it).thenApply { Optional.of(it) } } - .orElseGet { CompletableFuture.completedFuture(Optional.empty()) } + override fun nextPage(): CompletableFuture = service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPagerAsync = + AutoPagerAsync.from(this, streamHandlerExecutor) /** The parameters that were used to request this page. */ fun params(): RunListParams = params @@ -67,6 +64,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -78,18 +76,24 @@ private constructor( class Builder internal constructor() { private var service: RunServiceAsync? = null + private var streamHandlerExecutor: Executor? = null private var params: RunListParams? = null private var response: RunListPageResponse? = null @JvmSynthetic internal fun from(runListPageAsync: RunListPageAsync) = apply { service = runListPageAsync.service + streamHandlerExecutor = runListPageAsync.streamHandlerExecutor params = runListPageAsync.params response = runListPageAsync.response } fun service(service: RunServiceAsync) = apply { this.service = service } + fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply { + this.streamHandlerExecutor = streamHandlerExecutor + } + /** The parameters that were used to request this page. */ fun params(params: RunListParams) = apply { this.params = params } @@ -104,6 +108,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -113,50 +118,22 @@ private constructor( fun build(): RunListPageAsync = RunListPageAsync( checkRequired("service", service), + checkRequired("streamHandlerExecutor", streamHandlerExecutor), checkRequired("params", params), checkRequired("response", response), ) } - class AutoPager(private val firstPage: RunListPageAsync) { - - fun forEach( - action: Predicate, - executor: Executor, - ): CompletableFuture { - fun CompletableFuture>.forEach( - action: (RunListResponse) -> Boolean, - executor: Executor, - ): CompletableFuture = - thenComposeAsync( - { page -> - page - .filter { it.data().all(action) } - .map { it.getNextPage().forEach(action, executor) } - .orElseGet { CompletableFuture.completedFuture(null) } - }, - executor, - ) - return CompletableFuture.completedFuture(Optional.of(firstPage)) - .forEach(action::test, executor) - } - - fun toList(executor: Executor): CompletableFuture> { - val values = mutableListOf() - return forEach(values::add, executor).thenApply { values } - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return /* spotless:off */ other is RunListPageAsync && service == other.service && params == other.params && response == other.response /* spotless:on */ + return /* spotless:off */ other is RunListPageAsync && service == other.service && streamHandlerExecutor == other.streamHandlerExecutor && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, params, response) /* spotless:on */ + override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, streamHandlerExecutor, params, response) /* spotless:on */ override fun toString() = - "RunListPageAsync{service=$service, params=$params, response=$response}" + "RunListPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, response=$response}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunListParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunListParams.kt index b825f64b..56035b50 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunListParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunListParams.kt @@ -6,7 +6,6 @@ import com.fasterxml.jackson.annotation.JsonCreator import com.openai.core.Enum import com.openai.core.JsonField import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import com.openai.errors.OpenAIInvalidDataException @@ -17,7 +16,7 @@ import kotlin.jvm.optionals.getOrNull /** Get a list of runs for an evaluation. */ class RunListParams private constructor( - private val evalId: String, + private val evalId: String?, private val after: String?, private val limit: Long?, private val order: Order?, @@ -26,7 +25,7 @@ private constructor( private val additionalQueryParams: QueryParams, ) : Params { - fun evalId(): String = evalId + fun evalId(): Optional = Optional.ofNullable(evalId) /** Identifier for the last run from the previous pagination request. */ fun after(): Optional = Optional.ofNullable(after) @@ -53,14 +52,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [RunListParams]. - * - * The following fields are required: - * ```java - * .evalId() - * ``` - */ + @JvmStatic fun none(): RunListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [RunListParams]. */ @JvmStatic fun builder() = Builder() } @@ -86,7 +80,10 @@ private constructor( additionalQueryParams = runListParams.additionalQueryParams.toBuilder() } - fun evalId(evalId: String) = apply { this.evalId = evalId } + fun evalId(evalId: String?) = apply { this.evalId = evalId } + + /** Alias for calling [Builder.evalId] with `evalId.orElse(null)`. */ + fun evalId(evalId: Optional) = evalId(evalId.getOrNull()) /** Identifier for the last run from the previous pagination request. */ fun after(after: String?) = apply { this.after = after } @@ -227,17 +224,10 @@ private constructor( * Returns an immutable instance of [RunListParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .evalId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): RunListParams = RunListParams( - checkRequired("evalId", evalId), + evalId, after, limit, order, @@ -249,7 +239,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> evalId + 0 -> evalId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunRetrieveParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunRetrieveParams.kt index b5cfc500..26e388e7 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunRetrieveParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/RunRetrieveParams.kt @@ -7,19 +7,21 @@ import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** Get an evaluation run by ID. */ class RunRetrieveParams private constructor( private val evalId: String, - private val runId: String, + private val runId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { fun evalId(): String = evalId - fun runId(): String = runId + fun runId(): Optional = Optional.ofNullable(runId) fun _additionalHeaders(): Headers = additionalHeaders @@ -35,7 +37,6 @@ private constructor( * The following fields are required: * ```java * .evalId() - * .runId() * ``` */ @JvmStatic fun builder() = Builder() @@ -59,7 +60,10 @@ private constructor( fun evalId(evalId: String) = apply { this.evalId = evalId } - fun runId(runId: String) = apply { this.runId = runId } + fun runId(runId: String?) = apply { this.runId = runId } + + /** Alias for calling [Builder.runId] with `runId.orElse(null)`. */ + fun runId(runId: Optional) = runId(runId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -167,7 +171,6 @@ private constructor( * The following fields are required: * ```java * .evalId() - * .runId() * ``` * * @throws IllegalStateException if any required field is unset. @@ -175,7 +178,7 @@ private constructor( fun build(): RunRetrieveParams = RunRetrieveParams( checkRequired("evalId", evalId), - checkRequired("runId", runId), + runId, additionalHeaders.build(), additionalQueryParams.build(), ) @@ -184,7 +187,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { 0 -> evalId - 1 -> runId + 1 -> runId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/outputitems/OutputItemListPage.kt b/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/outputitems/OutputItemListPage.kt index e24395a2..b75e0d39 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/outputitems/OutputItemListPage.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/outputitems/OutputItemListPage.kt @@ -2,12 +2,12 @@ package com.openai.models.evals.runs.outputitems +import com.openai.core.AutoPager +import com.openai.core.Page import com.openai.core.checkRequired import com.openai.services.blocking.evals.runs.OutputItemService import java.util.Objects import java.util.Optional -import java.util.stream.Stream -import java.util.stream.StreamSupport import kotlin.jvm.optionals.getOrNull /** @see [OutputItemService.list] */ @@ -16,7 +16,7 @@ private constructor( private val service: OutputItemService, private val params: OutputItemListParams, private val response: OutputItemListPageResponse, -) { +) : Page { /** * Delegates to [OutputItemListPageResponse], but gracefully handles missing data. @@ -33,19 +33,16 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): OutputItemListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): Optional = getNextPageParams().map { service.list(it) } + override fun nextPage(): OutputItemListPage = service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPager = AutoPager.from(this) /** The parameters that were used to request this page. */ fun params(): OutputItemListParams = params @@ -114,25 +111,6 @@ private constructor( ) } - class AutoPager(private val firstPage: OutputItemListPage) : Iterable { - - override fun iterator(): Iterator = iterator { - var page = firstPage - var index = 0 - while (true) { - while (index < page.data().size) { - yield(page.data()[index++]) - } - page = page.getNextPage().getOrNull() ?: break - index = 0 - } - } - - fun stream(): Stream { - return StreamSupport.stream(spliterator(), false) - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/outputitems/OutputItemListPageAsync.kt b/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/outputitems/OutputItemListPageAsync.kt index 9e5c9635..c12bf482 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/outputitems/OutputItemListPageAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/outputitems/OutputItemListPageAsync.kt @@ -2,22 +2,24 @@ package com.openai.models.evals.runs.outputitems +import com.openai.core.AutoPagerAsync +import com.openai.core.PageAsync import com.openai.core.checkRequired import com.openai.services.async.evals.runs.OutputItemServiceAsync import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor -import java.util.function.Predicate import kotlin.jvm.optionals.getOrNull /** @see [OutputItemServiceAsync.list] */ class OutputItemListPageAsync private constructor( private val service: OutputItemServiceAsync, + private val streamHandlerExecutor: Executor, private val params: OutputItemListParams, private val response: OutputItemListPageResponse, -) { +) : PageAsync { /** * Delegates to [OutputItemListPageResponse], but gracefully handles missing data. @@ -34,22 +36,18 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): OutputItemListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): CompletableFuture> = - getNextPageParams() - .map { service.list(it).thenApply { Optional.of(it) } } - .orElseGet { CompletableFuture.completedFuture(Optional.empty()) } + override fun nextPage(): CompletableFuture = + service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPagerAsync = + AutoPagerAsync.from(this, streamHandlerExecutor) /** The parameters that were used to request this page. */ fun params(): OutputItemListParams = params @@ -67,6 +65,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -78,18 +77,24 @@ private constructor( class Builder internal constructor() { private var service: OutputItemServiceAsync? = null + private var streamHandlerExecutor: Executor? = null private var params: OutputItemListParams? = null private var response: OutputItemListPageResponse? = null @JvmSynthetic internal fun from(outputItemListPageAsync: OutputItemListPageAsync) = apply { service = outputItemListPageAsync.service + streamHandlerExecutor = outputItemListPageAsync.streamHandlerExecutor params = outputItemListPageAsync.params response = outputItemListPageAsync.response } fun service(service: OutputItemServiceAsync) = apply { this.service = service } + fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply { + this.streamHandlerExecutor = streamHandlerExecutor + } + /** The parameters that were used to request this page. */ fun params(params: OutputItemListParams) = apply { this.params = params } @@ -104,6 +109,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -113,50 +119,22 @@ private constructor( fun build(): OutputItemListPageAsync = OutputItemListPageAsync( checkRequired("service", service), + checkRequired("streamHandlerExecutor", streamHandlerExecutor), checkRequired("params", params), checkRequired("response", response), ) } - class AutoPager(private val firstPage: OutputItemListPageAsync) { - - fun forEach( - action: Predicate, - executor: Executor, - ): CompletableFuture { - fun CompletableFuture>.forEach( - action: (OutputItemListResponse) -> Boolean, - executor: Executor, - ): CompletableFuture = - thenComposeAsync( - { page -> - page - .filter { it.data().all(action) } - .map { it.getNextPage().forEach(action, executor) } - .orElseGet { CompletableFuture.completedFuture(null) } - }, - executor, - ) - return CompletableFuture.completedFuture(Optional.of(firstPage)) - .forEach(action::test, executor) - } - - fun toList(executor: Executor): CompletableFuture> { - val values = mutableListOf() - return forEach(values::add, executor).thenApply { values } - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return /* spotless:off */ other is OutputItemListPageAsync && service == other.service && params == other.params && response == other.response /* spotless:on */ + return /* spotless:off */ other is OutputItemListPageAsync && service == other.service && streamHandlerExecutor == other.streamHandlerExecutor && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, params, response) /* spotless:on */ + override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, streamHandlerExecutor, params, response) /* spotless:on */ override fun toString() = - "OutputItemListPageAsync{service=$service, params=$params, response=$response}" + "OutputItemListPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, response=$response}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/outputitems/OutputItemListParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/outputitems/OutputItemListParams.kt index 4c6c896b..d7b88210 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/outputitems/OutputItemListParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/outputitems/OutputItemListParams.kt @@ -18,7 +18,7 @@ import kotlin.jvm.optionals.getOrNull class OutputItemListParams private constructor( private val evalId: String, - private val runId: String, + private val runId: String?, private val after: String?, private val limit: Long?, private val order: Order?, @@ -29,7 +29,7 @@ private constructor( fun evalId(): String = evalId - fun runId(): String = runId + fun runId(): Optional = Optional.ofNullable(runId) /** Identifier for the last output item from the previous pagination request. */ fun after(): Optional = Optional.ofNullable(after) @@ -63,7 +63,6 @@ private constructor( * The following fields are required: * ```java * .evalId() - * .runId() * ``` */ @JvmStatic fun builder() = Builder() @@ -95,7 +94,10 @@ private constructor( fun evalId(evalId: String) = apply { this.evalId = evalId } - fun runId(runId: String) = apply { this.runId = runId } + fun runId(runId: String?) = apply { this.runId = runId } + + /** Alias for calling [Builder.runId] with `runId.orElse(null)`. */ + fun runId(runId: Optional) = runId(runId.getOrNull()) /** Identifier for the last output item from the previous pagination request. */ fun after(after: String?) = apply { this.after = after } @@ -240,7 +242,6 @@ private constructor( * The following fields are required: * ```java * .evalId() - * .runId() * ``` * * @throws IllegalStateException if any required field is unset. @@ -248,7 +249,7 @@ private constructor( fun build(): OutputItemListParams = OutputItemListParams( checkRequired("evalId", evalId), - checkRequired("runId", runId), + runId, after, limit, order, @@ -261,7 +262,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { 0 -> evalId - 1 -> runId + 1 -> runId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/outputitems/OutputItemRetrieveParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/outputitems/OutputItemRetrieveParams.kt index 3d1a3ce3..361599f5 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/outputitems/OutputItemRetrieveParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/outputitems/OutputItemRetrieveParams.kt @@ -7,13 +7,15 @@ import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** Get an evaluation run output item by ID. */ class OutputItemRetrieveParams private constructor( private val evalId: String, private val runId: String, - private val outputItemId: String, + private val outputItemId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { @@ -22,7 +24,7 @@ private constructor( fun runId(): String = runId - fun outputItemId(): String = outputItemId + fun outputItemId(): Optional = Optional.ofNullable(outputItemId) fun _additionalHeaders(): Headers = additionalHeaders @@ -39,7 +41,6 @@ private constructor( * ```java * .evalId() * .runId() - * .outputItemId() * ``` */ @JvmStatic fun builder() = Builder() @@ -67,7 +68,10 @@ private constructor( fun runId(runId: String) = apply { this.runId = runId } - fun outputItemId(outputItemId: String) = apply { this.outputItemId = outputItemId } + fun outputItemId(outputItemId: String?) = apply { this.outputItemId = outputItemId } + + /** Alias for calling [Builder.outputItemId] with `outputItemId.orElse(null)`. */ + fun outputItemId(outputItemId: Optional) = outputItemId(outputItemId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -176,7 +180,6 @@ private constructor( * ```java * .evalId() * .runId() - * .outputItemId() * ``` * * @throws IllegalStateException if any required field is unset. @@ -185,7 +188,7 @@ private constructor( OutputItemRetrieveParams( checkRequired("evalId", evalId), checkRequired("runId", runId), - checkRequired("outputItemId", outputItemId), + outputItemId, additionalHeaders.build(), additionalQueryParams.build(), ) @@ -195,7 +198,7 @@ private constructor( when (index) { 0 -> evalId 1 -> runId - 2 -> outputItemId + 2 -> outputItemId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/files/FileContentParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/files/FileContentParams.kt index 0a4ea8ab..5035b168 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/files/FileContentParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/files/FileContentParams.kt @@ -3,20 +3,21 @@ package com.openai.models.files import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** Returns the contents of the specified file. */ class FileContentParams private constructor( - private val fileId: String, + private val fileId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun fileId(): String = fileId + fun fileId(): Optional = Optional.ofNullable(fileId) fun _additionalHeaders(): Headers = additionalHeaders @@ -26,14 +27,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [FileContentParams]. - * - * The following fields are required: - * ```java - * .fileId() - * ``` - */ + @JvmStatic fun none(): FileContentParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [FileContentParams]. */ @JvmStatic fun builder() = Builder() } @@ -51,7 +47,10 @@ private constructor( additionalQueryParams = fileContentParams.additionalQueryParams.toBuilder() } - fun fileId(fileId: String) = apply { this.fileId = fileId } + fun fileId(fileId: String?) = apply { this.fileId = fileId } + + /** Alias for calling [Builder.fileId] with `fileId.orElse(null)`. */ + fun fileId(fileId: Optional) = fileId(fileId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -155,25 +154,14 @@ private constructor( * Returns an immutable instance of [FileContentParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .fileId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): FileContentParams = - FileContentParams( - checkRequired("fileId", fileId), - additionalHeaders.build(), - additionalQueryParams.build(), - ) + FileContentParams(fileId, additionalHeaders.build(), additionalQueryParams.build()) } fun _pathParam(index: Int): String = when (index) { - 0 -> fileId + 0 -> fileId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/files/FileDeleteParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/files/FileDeleteParams.kt index 2bc93b6a..dca35f8a 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/files/FileDeleteParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/files/FileDeleteParams.kt @@ -4,23 +4,23 @@ package com.openai.models.files import com.openai.core.JsonValue import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import com.openai.core.toImmutable import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** Delete a file. */ class FileDeleteParams private constructor( - private val fileId: String, + private val fileId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, ) : Params { - fun fileId(): String = fileId + fun fileId(): Optional = Optional.ofNullable(fileId) fun _additionalBodyProperties(): Map = additionalBodyProperties @@ -32,14 +32,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [FileDeleteParams]. - * - * The following fields are required: - * ```java - * .fileId() - * ``` - */ + @JvmStatic fun none(): FileDeleteParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [FileDeleteParams]. */ @JvmStatic fun builder() = Builder() } @@ -59,7 +54,10 @@ private constructor( additionalBodyProperties = fileDeleteParams.additionalBodyProperties.toMutableMap() } - fun fileId(fileId: String) = apply { this.fileId = fileId } + fun fileId(fileId: String?) = apply { this.fileId = fileId } + + /** Alias for calling [Builder.fileId] with `fileId.orElse(null)`. */ + fun fileId(fileId: Optional) = fileId(fileId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -185,17 +183,10 @@ private constructor( * Returns an immutable instance of [FileDeleteParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .fileId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): FileDeleteParams = FileDeleteParams( - checkRequired("fileId", fileId), + fileId, additionalHeaders.build(), additionalQueryParams.build(), additionalBodyProperties.toImmutable(), @@ -207,7 +198,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> fileId + 0 -> fileId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/files/FileListPage.kt b/openai-java-core/src/main/kotlin/com/openai/models/files/FileListPage.kt index 2aa16da3..9310e134 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/files/FileListPage.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/files/FileListPage.kt @@ -2,12 +2,12 @@ package com.openai.models.files +import com.openai.core.AutoPager +import com.openai.core.Page import com.openai.core.checkRequired import com.openai.services.blocking.FileService import java.util.Objects import java.util.Optional -import java.util.stream.Stream -import java.util.stream.StreamSupport import kotlin.jvm.optionals.getOrNull /** @see [FileService.list] */ @@ -16,7 +16,7 @@ private constructor( private val service: FileService, private val params: FileListParams, private val response: FileListPageResponse, -) { +) : Page { /** * Delegates to [FileListPageResponse], but gracefully handles missing data. @@ -32,19 +32,16 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): FileListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): Optional = getNextPageParams().map { service.list(it) } + override fun nextPage(): FileListPage = service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPager = AutoPager.from(this) /** The parameters that were used to request this page. */ fun params(): FileListParams = params @@ -113,25 +110,6 @@ private constructor( ) } - class AutoPager(private val firstPage: FileListPage) : Iterable { - - override fun iterator(): Iterator = iterator { - var page = firstPage - var index = 0 - while (true) { - while (index < page.data().size) { - yield(page.data()[index++]) - } - page = page.getNextPage().getOrNull() ?: break - index = 0 - } - } - - fun stream(): Stream { - return StreamSupport.stream(spliterator(), false) - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/openai-java-core/src/main/kotlin/com/openai/models/files/FileListPageAsync.kt b/openai-java-core/src/main/kotlin/com/openai/models/files/FileListPageAsync.kt index ec8e2d6c..7f775f0c 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/files/FileListPageAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/files/FileListPageAsync.kt @@ -2,22 +2,24 @@ package com.openai.models.files +import com.openai.core.AutoPagerAsync +import com.openai.core.PageAsync import com.openai.core.checkRequired import com.openai.services.async.FileServiceAsync import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor -import java.util.function.Predicate import kotlin.jvm.optionals.getOrNull /** @see [FileServiceAsync.list] */ class FileListPageAsync private constructor( private val service: FileServiceAsync, + private val streamHandlerExecutor: Executor, private val params: FileListParams, private val response: FileListPageResponse, -) { +) : PageAsync { /** * Delegates to [FileListPageResponse], but gracefully handles missing data. @@ -33,22 +35,16 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): FileListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): CompletableFuture> = - getNextPageParams() - .map { service.list(it).thenApply { Optional.of(it) } } - .orElseGet { CompletableFuture.completedFuture(Optional.empty()) } + override fun nextPage(): CompletableFuture = service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPagerAsync = AutoPagerAsync.from(this, streamHandlerExecutor) /** The parameters that were used to request this page. */ fun params(): FileListParams = params @@ -66,6 +62,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -77,18 +74,24 @@ private constructor( class Builder internal constructor() { private var service: FileServiceAsync? = null + private var streamHandlerExecutor: Executor? = null private var params: FileListParams? = null private var response: FileListPageResponse? = null @JvmSynthetic internal fun from(fileListPageAsync: FileListPageAsync) = apply { service = fileListPageAsync.service + streamHandlerExecutor = fileListPageAsync.streamHandlerExecutor params = fileListPageAsync.params response = fileListPageAsync.response } fun service(service: FileServiceAsync) = apply { this.service = service } + fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply { + this.streamHandlerExecutor = streamHandlerExecutor + } + /** The parameters that were used to request this page. */ fun params(params: FileListParams) = apply { this.params = params } @@ -103,6 +106,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -112,47 +116,22 @@ private constructor( fun build(): FileListPageAsync = FileListPageAsync( checkRequired("service", service), + checkRequired("streamHandlerExecutor", streamHandlerExecutor), checkRequired("params", params), checkRequired("response", response), ) } - class AutoPager(private val firstPage: FileListPageAsync) { - - fun forEach(action: Predicate, executor: Executor): CompletableFuture { - fun CompletableFuture>.forEach( - action: (FileObject) -> Boolean, - executor: Executor, - ): CompletableFuture = - thenComposeAsync( - { page -> - page - .filter { it.data().all(action) } - .map { it.getNextPage().forEach(action, executor) } - .orElseGet { CompletableFuture.completedFuture(null) } - }, - executor, - ) - return CompletableFuture.completedFuture(Optional.of(firstPage)) - .forEach(action::test, executor) - } - - fun toList(executor: Executor): CompletableFuture> { - val values = mutableListOf() - return forEach(values::add, executor).thenApply { values } - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return /* spotless:off */ other is FileListPageAsync && service == other.service && params == other.params && response == other.response /* spotless:on */ + return /* spotless:off */ other is FileListPageAsync && service == other.service && streamHandlerExecutor == other.streamHandlerExecutor && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, params, response) /* spotless:on */ + override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, streamHandlerExecutor, params, response) /* spotless:on */ override fun toString() = - "FileListPageAsync{service=$service, params=$params, response=$response}" + "FileListPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, response=$response}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/files/FileRetrieveParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/files/FileRetrieveParams.kt index 379eb2f1..cb00e708 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/files/FileRetrieveParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/files/FileRetrieveParams.kt @@ -3,20 +3,21 @@ package com.openai.models.files import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** Returns information about a specific file. */ class FileRetrieveParams private constructor( - private val fileId: String, + private val fileId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun fileId(): String = fileId + fun fileId(): Optional = Optional.ofNullable(fileId) fun _additionalHeaders(): Headers = additionalHeaders @@ -26,14 +27,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [FileRetrieveParams]. - * - * The following fields are required: - * ```java - * .fileId() - * ``` - */ + @JvmStatic fun none(): FileRetrieveParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [FileRetrieveParams]. */ @JvmStatic fun builder() = Builder() } @@ -51,7 +47,10 @@ private constructor( additionalQueryParams = fileRetrieveParams.additionalQueryParams.toBuilder() } - fun fileId(fileId: String) = apply { this.fileId = fileId } + fun fileId(fileId: String?) = apply { this.fileId = fileId } + + /** Alias for calling [Builder.fileId] with `fileId.orElse(null)`. */ + fun fileId(fileId: Optional) = fileId(fileId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -155,25 +154,14 @@ private constructor( * Returns an immutable instance of [FileRetrieveParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .fileId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): FileRetrieveParams = - FileRetrieveParams( - checkRequired("fileId", fileId), - additionalHeaders.build(), - additionalQueryParams.build(), - ) + FileRetrieveParams(fileId, additionalHeaders.build(), additionalQueryParams.build()) } fun _pathParam(index: Int): String = when (index) { - 0 -> fileId + 0 -> fileId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/alpha/graders/GraderRunParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/alpha/graders/GraderRunParams.kt new file mode 100644 index 00000000..cd49645d --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/alpha/graders/GraderRunParams.kt @@ -0,0 +1,1145 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.finetuning.alpha.graders + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.BaseDeserializer +import com.openai.core.BaseSerializer +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.Params +import com.openai.core.allMaxBy +import com.openai.core.checkRequired +import com.openai.core.getOrThrow +import com.openai.core.http.Headers +import com.openai.core.http.QueryParams +import com.openai.errors.OpenAIInvalidDataException +import com.openai.models.graders.gradermodels.MultiGrader +import com.openai.models.graders.gradermodels.PythonGrader +import com.openai.models.graders.gradermodels.ScoreModelGrader +import com.openai.models.graders.gradermodels.StringCheckGrader +import com.openai.models.graders.gradermodels.TextSimilarityGrader +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Run a grader. */ +class GraderRunParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * The grader used for the fine-tuning job. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun grader(): Grader = body.grader() + + /** + * The model sample to be evaluated. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun modelSample(): String = body.modelSample() + + /** + * The reference answer for the evaluation. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun referenceAnswer(): ReferenceAnswer = body.referenceAnswer() + + /** + * Returns the raw JSON value of [grader]. + * + * Unlike [grader], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _grader(): JsonField = body._grader() + + /** + * Returns the raw JSON value of [modelSample]. + * + * Unlike [modelSample], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _modelSample(): JsonField = body._modelSample() + + /** + * Returns the raw JSON value of [referenceAnswer]. + * + * Unlike [referenceAnswer], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _referenceAnswer(): JsonField = body._referenceAnswer() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [GraderRunParams]. + * + * The following fields are required: + * ```java + * .grader() + * .modelSample() + * .referenceAnswer() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [GraderRunParams]. */ + class Builder internal constructor() { + + private var body: Body.Builder = Body.builder() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(graderRunParams: GraderRunParams) = apply { + body = graderRunParams.body.toBuilder() + additionalHeaders = graderRunParams.additionalHeaders.toBuilder() + additionalQueryParams = graderRunParams.additionalQueryParams.toBuilder() + } + + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [grader] + * - [modelSample] + * - [referenceAnswer] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** The grader used for the fine-tuning job. */ + fun grader(grader: Grader) = apply { body.grader(grader) } + + /** + * Sets [Builder.grader] to an arbitrary JSON value. + * + * You should usually call [Builder.grader] with a well-typed [Grader] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun grader(grader: JsonField) = apply { body.grader(grader) } + + /** Alias for calling [grader] with `Grader.ofStringCheck(stringCheck)`. */ + fun grader(stringCheck: StringCheckGrader) = apply { body.grader(stringCheck) } + + /** Alias for calling [grader] with `Grader.ofTextSimilarity(textSimilarity)`. */ + fun grader(textSimilarity: TextSimilarityGrader) = apply { body.grader(textSimilarity) } + + /** Alias for calling [grader] with `Grader.ofPython(python)`. */ + fun grader(python: PythonGrader) = apply { body.grader(python) } + + /** Alias for calling [grader] with `Grader.ofScoreModel(scoreModel)`. */ + fun grader(scoreModel: ScoreModelGrader) = apply { body.grader(scoreModel) } + + /** Alias for calling [grader] with `Grader.ofMulti(multi)`. */ + fun grader(multi: MultiGrader) = apply { body.grader(multi) } + + /** The model sample to be evaluated. */ + fun modelSample(modelSample: String) = apply { body.modelSample(modelSample) } + + /** + * Sets [Builder.modelSample] to an arbitrary JSON value. + * + * You should usually call [Builder.modelSample] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun modelSample(modelSample: JsonField) = apply { body.modelSample(modelSample) } + + /** The reference answer for the evaluation. */ + fun referenceAnswer(referenceAnswer: ReferenceAnswer) = apply { + body.referenceAnswer(referenceAnswer) + } + + /** + * Sets [Builder.referenceAnswer] to an arbitrary JSON value. + * + * You should usually call [Builder.referenceAnswer] with a well-typed [ReferenceAnswer] + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun referenceAnswer(referenceAnswer: JsonField) = apply { + body.referenceAnswer(referenceAnswer) + } + + /** Alias for calling [referenceAnswer] with `ReferenceAnswer.ofString(string)`. */ + fun referenceAnswer(string: String) = apply { body.referenceAnswer(string) } + + /** Alias for calling [referenceAnswer] with `ReferenceAnswer.ofJsonValue(jsonValue)`. */ + fun referenceAnswer(jsonValue: JsonValue) = apply { body.referenceAnswer(jsonValue) } + + /** Alias for calling [referenceAnswer] with `ReferenceAnswer.ofJsonValues(jsonValues)`. */ + fun referenceAnswerOfJsonValues(jsonValues: List) = apply { + body.referenceAnswerOfJsonValues(jsonValues) + } + + /** Alias for calling [referenceAnswer] with `ReferenceAnswer.ofNumber(number)`. */ + fun referenceAnswer(number: Double) = apply { body.referenceAnswer(number) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) + } + + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } + + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } + + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } + + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } + + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } + + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + /** + * Returns an immutable instance of [GraderRunParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .grader() + * .modelSample() + * .referenceAnswer() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): GraderRunParams = + GraderRunParams(body.build(), additionalHeaders.build(), additionalQueryParams.build()) + } + + fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + private constructor( + private val grader: JsonField, + private val modelSample: JsonField, + private val referenceAnswer: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("grader") @ExcludeMissing grader: JsonField = JsonMissing.of(), + @JsonProperty("model_sample") + @ExcludeMissing + modelSample: JsonField = JsonMissing.of(), + @JsonProperty("reference_answer") + @ExcludeMissing + referenceAnswer: JsonField = JsonMissing.of(), + ) : this(grader, modelSample, referenceAnswer, mutableMapOf()) + + /** + * The grader used for the fine-tuning job. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun grader(): Grader = grader.getRequired("grader") + + /** + * The model sample to be evaluated. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun modelSample(): String = modelSample.getRequired("model_sample") + + /** + * The reference answer for the evaluation. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun referenceAnswer(): ReferenceAnswer = referenceAnswer.getRequired("reference_answer") + + /** + * Returns the raw JSON value of [grader]. + * + * Unlike [grader], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("grader") @ExcludeMissing fun _grader(): JsonField = grader + + /** + * Returns the raw JSON value of [modelSample]. + * + * Unlike [modelSample], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("model_sample") + @ExcludeMissing + fun _modelSample(): JsonField = modelSample + + /** + * Returns the raw JSON value of [referenceAnswer]. + * + * Unlike [referenceAnswer], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("reference_answer") + @ExcludeMissing + fun _referenceAnswer(): JsonField = referenceAnswer + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Body]. + * + * The following fields are required: + * ```java + * .grader() + * .modelSample() + * .referenceAnswer() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var grader: JsonField? = null + private var modelSample: JsonField? = null + private var referenceAnswer: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + grader = body.grader + modelSample = body.modelSample + referenceAnswer = body.referenceAnswer + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** The grader used for the fine-tuning job. */ + fun grader(grader: Grader) = grader(JsonField.of(grader)) + + /** + * Sets [Builder.grader] to an arbitrary JSON value. + * + * You should usually call [Builder.grader] with a well-typed [Grader] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun grader(grader: JsonField) = apply { this.grader = grader } + + /** Alias for calling [grader] with `Grader.ofStringCheck(stringCheck)`. */ + fun grader(stringCheck: StringCheckGrader) = grader(Grader.ofStringCheck(stringCheck)) + + /** Alias for calling [grader] with `Grader.ofTextSimilarity(textSimilarity)`. */ + fun grader(textSimilarity: TextSimilarityGrader) = + grader(Grader.ofTextSimilarity(textSimilarity)) + + /** Alias for calling [grader] with `Grader.ofPython(python)`. */ + fun grader(python: PythonGrader) = grader(Grader.ofPython(python)) + + /** Alias for calling [grader] with `Grader.ofScoreModel(scoreModel)`. */ + fun grader(scoreModel: ScoreModelGrader) = grader(Grader.ofScoreModel(scoreModel)) + + /** Alias for calling [grader] with `Grader.ofMulti(multi)`. */ + fun grader(multi: MultiGrader) = grader(Grader.ofMulti(multi)) + + /** The model sample to be evaluated. */ + fun modelSample(modelSample: String) = modelSample(JsonField.of(modelSample)) + + /** + * Sets [Builder.modelSample] to an arbitrary JSON value. + * + * You should usually call [Builder.modelSample] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun modelSample(modelSample: JsonField) = apply { + this.modelSample = modelSample + } + + /** The reference answer for the evaluation. */ + fun referenceAnswer(referenceAnswer: ReferenceAnswer) = + referenceAnswer(JsonField.of(referenceAnswer)) + + /** + * Sets [Builder.referenceAnswer] to an arbitrary JSON value. + * + * You should usually call [Builder.referenceAnswer] with a well-typed [ReferenceAnswer] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun referenceAnswer(referenceAnswer: JsonField) = apply { + this.referenceAnswer = referenceAnswer + } + + /** Alias for calling [referenceAnswer] with `ReferenceAnswer.ofString(string)`. */ + fun referenceAnswer(string: String) = referenceAnswer(ReferenceAnswer.ofString(string)) + + /** + * Alias for calling [referenceAnswer] with `ReferenceAnswer.ofJsonValue(jsonValue)`. + */ + fun referenceAnswer(jsonValue: JsonValue) = + referenceAnswer(ReferenceAnswer.ofJsonValue(jsonValue)) + + /** + * Alias for calling [referenceAnswer] with `ReferenceAnswer.ofJsonValues(jsonValues)`. + */ + fun referenceAnswerOfJsonValues(jsonValues: List) = + referenceAnswer(ReferenceAnswer.ofJsonValues(jsonValues)) + + /** Alias for calling [referenceAnswer] with `ReferenceAnswer.ofNumber(number)`. */ + fun referenceAnswer(number: Double) = referenceAnswer(ReferenceAnswer.ofNumber(number)) + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .grader() + * .modelSample() + * .referenceAnswer() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("grader", grader), + checkRequired("modelSample", modelSample), + checkRequired("referenceAnswer", referenceAnswer), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + grader().validate() + modelSample() + referenceAnswer().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (grader.asKnown().getOrNull()?.validity() ?: 0) + + (if (modelSample.asKnown().isPresent) 1 else 0) + + (referenceAnswer.asKnown().getOrNull()?.validity() ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Body && grader == other.grader && modelSample == other.modelSample && referenceAnswer == other.referenceAnswer && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(grader, modelSample, referenceAnswer, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{grader=$grader, modelSample=$modelSample, referenceAnswer=$referenceAnswer, additionalProperties=$additionalProperties}" + } + + /** The grader used for the fine-tuning job. */ + @JsonDeserialize(using = Grader.Deserializer::class) + @JsonSerialize(using = Grader.Serializer::class) + class Grader + private constructor( + private val stringCheck: StringCheckGrader? = null, + private val textSimilarity: TextSimilarityGrader? = null, + private val python: PythonGrader? = null, + private val scoreModel: ScoreModelGrader? = null, + private val multi: MultiGrader? = null, + private val _json: JsonValue? = null, + ) { + + /** + * A StringCheckGrader object that performs a string comparison between input and reference + * using a specified operation. + */ + fun stringCheck(): Optional = Optional.ofNullable(stringCheck) + + /** A TextSimilarityGrader object which grades text based on similarity metrics. */ + fun textSimilarity(): Optional = Optional.ofNullable(textSimilarity) + + /** A PythonGrader object that runs a python script on the input. */ + fun python(): Optional = Optional.ofNullable(python) + + /** A ScoreModelGrader object that uses a model to assign a score to the input. */ + fun scoreModel(): Optional = Optional.ofNullable(scoreModel) + + /** + * A MultiGrader object combines the output of multiple graders to produce a single score. + */ + fun multi(): Optional = Optional.ofNullable(multi) + + fun isStringCheck(): Boolean = stringCheck != null + + fun isTextSimilarity(): Boolean = textSimilarity != null + + fun isPython(): Boolean = python != null + + fun isScoreModel(): Boolean = scoreModel != null + + fun isMulti(): Boolean = multi != null + + /** + * A StringCheckGrader object that performs a string comparison between input and reference + * using a specified operation. + */ + fun asStringCheck(): StringCheckGrader = stringCheck.getOrThrow("stringCheck") + + /** A TextSimilarityGrader object which grades text based on similarity metrics. */ + fun asTextSimilarity(): TextSimilarityGrader = textSimilarity.getOrThrow("textSimilarity") + + /** A PythonGrader object that runs a python script on the input. */ + fun asPython(): PythonGrader = python.getOrThrow("python") + + /** A ScoreModelGrader object that uses a model to assign a score to the input. */ + fun asScoreModel(): ScoreModelGrader = scoreModel.getOrThrow("scoreModel") + + /** + * A MultiGrader object combines the output of multiple graders to produce a single score. + */ + fun asMulti(): MultiGrader = multi.getOrThrow("multi") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + stringCheck != null -> visitor.visitStringCheck(stringCheck) + textSimilarity != null -> visitor.visitTextSimilarity(textSimilarity) + python != null -> visitor.visitPython(python) + scoreModel != null -> visitor.visitScoreModel(scoreModel) + multi != null -> visitor.visitMulti(multi) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): Grader = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitStringCheck(stringCheck: StringCheckGrader) { + stringCheck.validate() + } + + override fun visitTextSimilarity(textSimilarity: TextSimilarityGrader) { + textSimilarity.validate() + } + + override fun visitPython(python: PythonGrader) { + python.validate() + } + + override fun visitScoreModel(scoreModel: ScoreModelGrader) { + scoreModel.validate() + } + + override fun visitMulti(multi: MultiGrader) { + multi.validate() + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitStringCheck(stringCheck: StringCheckGrader) = + stringCheck.validity() + + override fun visitTextSimilarity(textSimilarity: TextSimilarityGrader) = + textSimilarity.validity() + + override fun visitPython(python: PythonGrader) = python.validity() + + override fun visitScoreModel(scoreModel: ScoreModelGrader) = + scoreModel.validity() + + override fun visitMulti(multi: MultiGrader) = multi.validity() + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Grader && stringCheck == other.stringCheck && textSimilarity == other.textSimilarity && python == other.python && scoreModel == other.scoreModel && multi == other.multi /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(stringCheck, textSimilarity, python, scoreModel, multi) /* spotless:on */ + + override fun toString(): String = + when { + stringCheck != null -> "Grader{stringCheck=$stringCheck}" + textSimilarity != null -> "Grader{textSimilarity=$textSimilarity}" + python != null -> "Grader{python=$python}" + scoreModel != null -> "Grader{scoreModel=$scoreModel}" + multi != null -> "Grader{multi=$multi}" + _json != null -> "Grader{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Grader") + } + + companion object { + + /** + * A StringCheckGrader object that performs a string comparison between input and + * reference using a specified operation. + */ + @JvmStatic + fun ofStringCheck(stringCheck: StringCheckGrader) = Grader(stringCheck = stringCheck) + + /** A TextSimilarityGrader object which grades text based on similarity metrics. */ + @JvmStatic + fun ofTextSimilarity(textSimilarity: TextSimilarityGrader) = + Grader(textSimilarity = textSimilarity) + + /** A PythonGrader object that runs a python script on the input. */ + @JvmStatic fun ofPython(python: PythonGrader) = Grader(python = python) + + /** A ScoreModelGrader object that uses a model to assign a score to the input. */ + @JvmStatic + fun ofScoreModel(scoreModel: ScoreModelGrader) = Grader(scoreModel = scoreModel) + + /** + * A MultiGrader object combines the output of multiple graders to produce a single + * score. + */ + @JvmStatic fun ofMulti(multi: MultiGrader) = Grader(multi = multi) + } + + /** An interface that defines how to map each variant of [Grader] to a value of type [T]. */ + interface Visitor { + + /** + * A StringCheckGrader object that performs a string comparison between input and + * reference using a specified operation. + */ + fun visitStringCheck(stringCheck: StringCheckGrader): T + + /** A TextSimilarityGrader object which grades text based on similarity metrics. */ + fun visitTextSimilarity(textSimilarity: TextSimilarityGrader): T + + /** A PythonGrader object that runs a python script on the input. */ + fun visitPython(python: PythonGrader): T + + /** A ScoreModelGrader object that uses a model to assign a score to the input. */ + fun visitScoreModel(scoreModel: ScoreModelGrader): T + + /** + * A MultiGrader object combines the output of multiple graders to produce a single + * score. + */ + fun visitMulti(multi: MultiGrader): T + + /** + * Maps an unknown variant of [Grader] to a value of type [T]. + * + * An instance of [Grader] can contain an unknown variant if it was deserialized from + * data that doesn't match any known variant. For example, if the SDK is on an older + * version than the API, then the API may respond with new variants that the SDK is + * unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown Grader: $json") + } + } + + internal class Deserializer : BaseDeserializer(Grader::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): Grader { + val json = JsonValue.fromJsonNode(node) + val type = json.asObject().getOrNull()?.get("type")?.asString()?.getOrNull() + + when (type) { + "string_check" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + Grader(stringCheck = it, _json = json) + } ?: Grader(_json = json) + } + "text_similarity" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + Grader(textSimilarity = it, _json = json) + } ?: Grader(_json = json) + } + "python" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + Grader(python = it, _json = json) + } ?: Grader(_json = json) + } + "score_model" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + Grader(scoreModel = it, _json = json) + } ?: Grader(_json = json) + } + "multi" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + Grader(multi = it, _json = json) + } ?: Grader(_json = json) + } + } + + return Grader(_json = json) + } + } + + internal class Serializer : BaseSerializer(Grader::class) { + + override fun serialize( + value: Grader, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.stringCheck != null -> generator.writeObject(value.stringCheck) + value.textSimilarity != null -> generator.writeObject(value.textSimilarity) + value.python != null -> generator.writeObject(value.python) + value.scoreModel != null -> generator.writeObject(value.scoreModel) + value.multi != null -> generator.writeObject(value.multi) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Grader") + } + } + } + } + + /** The reference answer for the evaluation. */ + @JsonDeserialize(using = ReferenceAnswer.Deserializer::class) + @JsonSerialize(using = ReferenceAnswer.Serializer::class) + class ReferenceAnswer + private constructor( + private val string: String? = null, + private val jsonValue: JsonValue? = null, + private val jsonValues: List? = null, + private val number: Double? = null, + private val _json: JsonValue? = null, + ) { + + fun string(): Optional = Optional.ofNullable(string) + + fun jsonValue(): Optional = Optional.ofNullable(jsonValue) + + fun jsonValues(): Optional> = Optional.ofNullable(jsonValues) + + fun number(): Optional = Optional.ofNullable(number) + + fun isString(): Boolean = string != null + + fun isJsonValue(): Boolean = jsonValue != null + + fun isJsonValues(): Boolean = jsonValues != null + + fun isNumber(): Boolean = number != null + + fun asString(): String = string.getOrThrow("string") + + fun asJsonValue(): JsonValue = jsonValue.getOrThrow("jsonValue") + + fun asJsonValues(): List = jsonValues.getOrThrow("jsonValues") + + fun asNumber(): Double = number.getOrThrow("number") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + string != null -> visitor.visitString(string) + jsonValue != null -> visitor.visitJsonValue(jsonValue) + jsonValues != null -> visitor.visitJsonValues(jsonValues) + number != null -> visitor.visitNumber(number) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): ReferenceAnswer = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitString(string: String) {} + + override fun visitJsonValue(jsonValue: JsonValue) {} + + override fun visitJsonValues(jsonValues: List) {} + + override fun visitNumber(number: Double) {} + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitString(string: String) = 1 + + override fun visitJsonValue(jsonValue: JsonValue) = 1 + + override fun visitJsonValues(jsonValues: List) = jsonValues.size + + override fun visitNumber(number: Double) = 1 + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ReferenceAnswer && string == other.string && jsonValue == other.jsonValue && jsonValues == other.jsonValues && number == other.number /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(string, jsonValue, jsonValues, number) /* spotless:on */ + + override fun toString(): String = + when { + string != null -> "ReferenceAnswer{string=$string}" + jsonValue != null -> "ReferenceAnswer{jsonValue=$jsonValue}" + jsonValues != null -> "ReferenceAnswer{jsonValues=$jsonValues}" + number != null -> "ReferenceAnswer{number=$number}" + _json != null -> "ReferenceAnswer{_unknown=$_json}" + else -> throw IllegalStateException("Invalid ReferenceAnswer") + } + + companion object { + + @JvmStatic fun ofString(string: String) = ReferenceAnswer(string = string) + + @JvmStatic + fun ofJsonValue(jsonValue: JsonValue) = ReferenceAnswer(jsonValue = jsonValue) + + @JvmStatic + fun ofJsonValues(jsonValues: List) = ReferenceAnswer(jsonValues = jsonValues) + + @JvmStatic fun ofNumber(number: Double) = ReferenceAnswer(number = number) + } + + /** + * An interface that defines how to map each variant of [ReferenceAnswer] to a value of type + * [T]. + */ + interface Visitor { + + fun visitString(string: String): T + + fun visitJsonValue(jsonValue: JsonValue): T + + fun visitJsonValues(jsonValues: List): T + + fun visitNumber(number: Double): T + + /** + * Maps an unknown variant of [ReferenceAnswer] to a value of type [T]. + * + * An instance of [ReferenceAnswer] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For example, if the SDK + * is on an older version than the API, then the API may respond with new variants that + * the SDK is unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown ReferenceAnswer: $json") + } + } + + internal class Deserializer : BaseDeserializer(ReferenceAnswer::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): ReferenceAnswer { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + ReferenceAnswer(string = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef>())?.let { + ReferenceAnswer(jsonValues = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + ReferenceAnswer(number = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + ReferenceAnswer(jsonValue = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with + // all the possible variants. + 0 -> ReferenceAnswer(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely + // valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(ReferenceAnswer::class) { + + override fun serialize( + value: ReferenceAnswer, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.string != null -> generator.writeObject(value.string) + value.jsonValue != null -> generator.writeObject(value.jsonValue) + value.jsonValues != null -> generator.writeObject(value.jsonValues) + value.number != null -> generator.writeObject(value.number) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid ReferenceAnswer") + } + } + } + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is GraderRunParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "GraderRunParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/alpha/graders/GraderRunResponse.kt b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/alpha/graders/GraderRunResponse.kt new file mode 100644 index 00000000..6523c6c5 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/alpha/graders/GraderRunResponse.kt @@ -0,0 +1,1772 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.finetuning.alpha.graders + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.checkRequired +import com.openai.core.toImmutable +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class GraderRunResponse +private constructor( + private val metadata: JsonField, + private val modelGraderTokenUsagePerModel: JsonField, + private val reward: JsonField, + private val subRewards: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("metadata") @ExcludeMissing metadata: JsonField = JsonMissing.of(), + @JsonProperty("model_grader_token_usage_per_model") + @ExcludeMissing + modelGraderTokenUsagePerModel: JsonField = JsonMissing.of(), + @JsonProperty("reward") @ExcludeMissing reward: JsonField = JsonMissing.of(), + @JsonProperty("sub_rewards") + @ExcludeMissing + subRewards: JsonField = JsonMissing.of(), + ) : this(metadata, modelGraderTokenUsagePerModel, reward, subRewards, mutableMapOf()) + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun metadata(): Metadata = metadata.getRequired("metadata") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun modelGraderTokenUsagePerModel(): ModelGraderTokenUsagePerModel = + modelGraderTokenUsagePerModel.getRequired("model_grader_token_usage_per_model") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun reward(): Double = reward.getRequired("reward") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun subRewards(): SubRewards = subRewards.getRequired("sub_rewards") + + /** + * Returns the raw JSON value of [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata + + /** + * Returns the raw JSON value of [modelGraderTokenUsagePerModel]. + * + * Unlike [modelGraderTokenUsagePerModel], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("model_grader_token_usage_per_model") + @ExcludeMissing + fun _modelGraderTokenUsagePerModel(): JsonField = + modelGraderTokenUsagePerModel + + /** + * Returns the raw JSON value of [reward]. + * + * Unlike [reward], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("reward") @ExcludeMissing fun _reward(): JsonField = reward + + /** + * Returns the raw JSON value of [subRewards]. + * + * Unlike [subRewards], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("sub_rewards") + @ExcludeMissing + fun _subRewards(): JsonField = subRewards + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [GraderRunResponse]. + * + * The following fields are required: + * ```java + * .metadata() + * .modelGraderTokenUsagePerModel() + * .reward() + * .subRewards() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [GraderRunResponse]. */ + class Builder internal constructor() { + + private var metadata: JsonField? = null + private var modelGraderTokenUsagePerModel: JsonField? = null + private var reward: JsonField? = null + private var subRewards: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(graderRunResponse: GraderRunResponse) = apply { + metadata = graderRunResponse.metadata + modelGraderTokenUsagePerModel = graderRunResponse.modelGraderTokenUsagePerModel + reward = graderRunResponse.reward + subRewards = graderRunResponse.subRewards + additionalProperties = graderRunResponse.additionalProperties.toMutableMap() + } + + fun metadata(metadata: Metadata) = metadata(JsonField.of(metadata)) + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun metadata(metadata: JsonField) = apply { this.metadata = metadata } + + fun modelGraderTokenUsagePerModel( + modelGraderTokenUsagePerModel: ModelGraderTokenUsagePerModel + ) = modelGraderTokenUsagePerModel(JsonField.of(modelGraderTokenUsagePerModel)) + + /** + * Sets [Builder.modelGraderTokenUsagePerModel] to an arbitrary JSON value. + * + * You should usually call [Builder.modelGraderTokenUsagePerModel] with a well-typed + * [ModelGraderTokenUsagePerModel] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun modelGraderTokenUsagePerModel( + modelGraderTokenUsagePerModel: JsonField + ) = apply { this.modelGraderTokenUsagePerModel = modelGraderTokenUsagePerModel } + + fun reward(reward: Double) = reward(JsonField.of(reward)) + + /** + * Sets [Builder.reward] to an arbitrary JSON value. + * + * You should usually call [Builder.reward] with a well-typed [Double] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun reward(reward: JsonField) = apply { this.reward = reward } + + fun subRewards(subRewards: SubRewards) = subRewards(JsonField.of(subRewards)) + + /** + * Sets [Builder.subRewards] to an arbitrary JSON value. + * + * You should usually call [Builder.subRewards] with a well-typed [SubRewards] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun subRewards(subRewards: JsonField) = apply { this.subRewards = subRewards } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [GraderRunResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .metadata() + * .modelGraderTokenUsagePerModel() + * .reward() + * .subRewards() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): GraderRunResponse = + GraderRunResponse( + checkRequired("metadata", metadata), + checkRequired("modelGraderTokenUsagePerModel", modelGraderTokenUsagePerModel), + checkRequired("reward", reward), + checkRequired("subRewards", subRewards), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): GraderRunResponse = apply { + if (validated) { + return@apply + } + + metadata().validate() + modelGraderTokenUsagePerModel().validate() + reward() + subRewards().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (metadata.asKnown().getOrNull()?.validity() ?: 0) + + (modelGraderTokenUsagePerModel.asKnown().getOrNull()?.validity() ?: 0) + + (if (reward.asKnown().isPresent) 1 else 0) + + (subRewards.asKnown().getOrNull()?.validity() ?: 0) + + class Metadata + private constructor( + private val errors: JsonField, + private val executionTime: JsonField, + private val name: JsonField, + private val sampledModelName: JsonField, + private val scores: JsonField, + private val tokenUsage: JsonField, + private val type: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("errors") @ExcludeMissing errors: JsonField = JsonMissing.of(), + @JsonProperty("execution_time") + @ExcludeMissing + executionTime: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("sampled_model_name") + @ExcludeMissing + sampledModelName: JsonField = JsonMissing.of(), + @JsonProperty("scores") @ExcludeMissing scores: JsonField = JsonMissing.of(), + @JsonProperty("token_usage") + @ExcludeMissing + tokenUsage: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + ) : this( + errors, + executionTime, + name, + sampledModelName, + scores, + tokenUsage, + type, + mutableMapOf(), + ) + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun errors(): Errors = errors.getRequired("errors") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun executionTime(): Double = executionTime.getRequired("execution_time") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun name(): String = name.getRequired("name") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun sampledModelName(): Optional = + sampledModelName.getOptional("sampled_model_name") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun scores(): Scores = scores.getRequired("scores") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun tokenUsage(): Optional = tokenUsage.getOptional("token_usage") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun type(): String = type.getRequired("type") + + /** + * Returns the raw JSON value of [errors]. + * + * Unlike [errors], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("errors") @ExcludeMissing fun _errors(): JsonField = errors + + /** + * Returns the raw JSON value of [executionTime]. + * + * Unlike [executionTime], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("execution_time") + @ExcludeMissing + fun _executionTime(): JsonField = executionTime + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [sampledModelName]. + * + * Unlike [sampledModelName], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("sampled_model_name") + @ExcludeMissing + fun _sampledModelName(): JsonField = sampledModelName + + /** + * Returns the raw JSON value of [scores]. + * + * Unlike [scores], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("scores") @ExcludeMissing fun _scores(): JsonField = scores + + /** + * Returns the raw JSON value of [tokenUsage]. + * + * Unlike [tokenUsage], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("token_usage") @ExcludeMissing fun _tokenUsage(): JsonField = tokenUsage + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Metadata]. + * + * The following fields are required: + * ```java + * .errors() + * .executionTime() + * .name() + * .sampledModelName() + * .scores() + * .tokenUsage() + * .type() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Metadata]. */ + class Builder internal constructor() { + + private var errors: JsonField? = null + private var executionTime: JsonField? = null + private var name: JsonField? = null + private var sampledModelName: JsonField? = null + private var scores: JsonField? = null + private var tokenUsage: JsonField? = null + private var type: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(metadata: Metadata) = apply { + errors = metadata.errors + executionTime = metadata.executionTime + name = metadata.name + sampledModelName = metadata.sampledModelName + scores = metadata.scores + tokenUsage = metadata.tokenUsage + type = metadata.type + additionalProperties = metadata.additionalProperties.toMutableMap() + } + + fun errors(errors: Errors) = errors(JsonField.of(errors)) + + /** + * Sets [Builder.errors] to an arbitrary JSON value. + * + * You should usually call [Builder.errors] with a well-typed [Errors] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun errors(errors: JsonField) = apply { this.errors = errors } + + fun executionTime(executionTime: Double) = executionTime(JsonField.of(executionTime)) + + /** + * Sets [Builder.executionTime] to an arbitrary JSON value. + * + * You should usually call [Builder.executionTime] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun executionTime(executionTime: JsonField) = apply { + this.executionTime = executionTime + } + + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun name(name: JsonField) = apply { this.name = name } + + fun sampledModelName(sampledModelName: String?) = + sampledModelName(JsonField.ofNullable(sampledModelName)) + + /** + * Alias for calling [Builder.sampledModelName] with `sampledModelName.orElse(null)`. + */ + fun sampledModelName(sampledModelName: Optional) = + sampledModelName(sampledModelName.getOrNull()) + + /** + * Sets [Builder.sampledModelName] to an arbitrary JSON value. + * + * You should usually call [Builder.sampledModelName] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun sampledModelName(sampledModelName: JsonField) = apply { + this.sampledModelName = sampledModelName + } + + fun scores(scores: Scores) = scores(JsonField.of(scores)) + + /** + * Sets [Builder.scores] to an arbitrary JSON value. + * + * You should usually call [Builder.scores] with a well-typed [Scores] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun scores(scores: JsonField) = apply { this.scores = scores } + + fun tokenUsage(tokenUsage: Long?) = tokenUsage(JsonField.ofNullable(tokenUsage)) + + /** + * Alias for [Builder.tokenUsage]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun tokenUsage(tokenUsage: Long) = tokenUsage(tokenUsage as Long?) + + /** Alias for calling [Builder.tokenUsage] with `tokenUsage.orElse(null)`. */ + fun tokenUsage(tokenUsage: Optional) = tokenUsage(tokenUsage.getOrNull()) + + /** + * Sets [Builder.tokenUsage] to an arbitrary JSON value. + * + * You should usually call [Builder.tokenUsage] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun tokenUsage(tokenUsage: JsonField) = apply { this.tokenUsage = tokenUsage } + + fun type(type: String) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonField) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Metadata]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .errors() + * .executionTime() + * .name() + * .sampledModelName() + * .scores() + * .tokenUsage() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Metadata = + Metadata( + checkRequired("errors", errors), + checkRequired("executionTime", executionTime), + checkRequired("name", name), + checkRequired("sampledModelName", sampledModelName), + checkRequired("scores", scores), + checkRequired("tokenUsage", tokenUsage), + checkRequired("type", type), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Metadata = apply { + if (validated) { + return@apply + } + + errors().validate() + executionTime() + name() + sampledModelName() + scores().validate() + tokenUsage() + type() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (errors.asKnown().getOrNull()?.validity() ?: 0) + + (if (executionTime.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (if (sampledModelName.asKnown().isPresent) 1 else 0) + + (scores.asKnown().getOrNull()?.validity() ?: 0) + + (if (tokenUsage.asKnown().isPresent) 1 else 0) + + (if (type.asKnown().isPresent) 1 else 0) + + class Errors + private constructor( + private val formulaParseError: JsonField, + private val invalidVariableError: JsonField, + private val modelGraderParseError: JsonField, + private val modelGraderRefusalError: JsonField, + private val modelGraderServerError: JsonField, + private val modelGraderServerErrorDetails: JsonField, + private val otherError: JsonField, + private val pythonGraderRuntimeError: JsonField, + private val pythonGraderRuntimeErrorDetails: JsonField, + private val pythonGraderServerError: JsonField, + private val pythonGraderServerErrorType: JsonField, + private val sampleParseError: JsonField, + private val truncatedObservationError: JsonField, + private val unresponsiveRewardError: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("formula_parse_error") + @ExcludeMissing + formulaParseError: JsonField = JsonMissing.of(), + @JsonProperty("invalid_variable_error") + @ExcludeMissing + invalidVariableError: JsonField = JsonMissing.of(), + @JsonProperty("model_grader_parse_error") + @ExcludeMissing + modelGraderParseError: JsonField = JsonMissing.of(), + @JsonProperty("model_grader_refusal_error") + @ExcludeMissing + modelGraderRefusalError: JsonField = JsonMissing.of(), + @JsonProperty("model_grader_server_error") + @ExcludeMissing + modelGraderServerError: JsonField = JsonMissing.of(), + @JsonProperty("model_grader_server_error_details") + @ExcludeMissing + modelGraderServerErrorDetails: JsonField = JsonMissing.of(), + @JsonProperty("other_error") + @ExcludeMissing + otherError: JsonField = JsonMissing.of(), + @JsonProperty("python_grader_runtime_error") + @ExcludeMissing + pythonGraderRuntimeError: JsonField = JsonMissing.of(), + @JsonProperty("python_grader_runtime_error_details") + @ExcludeMissing + pythonGraderRuntimeErrorDetails: JsonField = JsonMissing.of(), + @JsonProperty("python_grader_server_error") + @ExcludeMissing + pythonGraderServerError: JsonField = JsonMissing.of(), + @JsonProperty("python_grader_server_error_type") + @ExcludeMissing + pythonGraderServerErrorType: JsonField = JsonMissing.of(), + @JsonProperty("sample_parse_error") + @ExcludeMissing + sampleParseError: JsonField = JsonMissing.of(), + @JsonProperty("truncated_observation_error") + @ExcludeMissing + truncatedObservationError: JsonField = JsonMissing.of(), + @JsonProperty("unresponsive_reward_error") + @ExcludeMissing + unresponsiveRewardError: JsonField = JsonMissing.of(), + ) : this( + formulaParseError, + invalidVariableError, + modelGraderParseError, + modelGraderRefusalError, + modelGraderServerError, + modelGraderServerErrorDetails, + otherError, + pythonGraderRuntimeError, + pythonGraderRuntimeErrorDetails, + pythonGraderServerError, + pythonGraderServerErrorType, + sampleParseError, + truncatedObservationError, + unresponsiveRewardError, + mutableMapOf(), + ) + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun formulaParseError(): Boolean = formulaParseError.getRequired("formula_parse_error") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun invalidVariableError(): Boolean = + invalidVariableError.getRequired("invalid_variable_error") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun modelGraderParseError(): Boolean = + modelGraderParseError.getRequired("model_grader_parse_error") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun modelGraderRefusalError(): Boolean = + modelGraderRefusalError.getRequired("model_grader_refusal_error") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun modelGraderServerError(): Boolean = + modelGraderServerError.getRequired("model_grader_server_error") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun modelGraderServerErrorDetails(): Optional = + modelGraderServerErrorDetails.getOptional("model_grader_server_error_details") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun otherError(): Boolean = otherError.getRequired("other_error") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun pythonGraderRuntimeError(): Boolean = + pythonGraderRuntimeError.getRequired("python_grader_runtime_error") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun pythonGraderRuntimeErrorDetails(): Optional = + pythonGraderRuntimeErrorDetails.getOptional("python_grader_runtime_error_details") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun pythonGraderServerError(): Boolean = + pythonGraderServerError.getRequired("python_grader_server_error") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun pythonGraderServerErrorType(): Optional = + pythonGraderServerErrorType.getOptional("python_grader_server_error_type") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun sampleParseError(): Boolean = sampleParseError.getRequired("sample_parse_error") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun truncatedObservationError(): Boolean = + truncatedObservationError.getRequired("truncated_observation_error") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun unresponsiveRewardError(): Boolean = + unresponsiveRewardError.getRequired("unresponsive_reward_error") + + /** + * Returns the raw JSON value of [formulaParseError]. + * + * Unlike [formulaParseError], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("formula_parse_error") + @ExcludeMissing + fun _formulaParseError(): JsonField = formulaParseError + + /** + * Returns the raw JSON value of [invalidVariableError]. + * + * Unlike [invalidVariableError], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("invalid_variable_error") + @ExcludeMissing + fun _invalidVariableError(): JsonField = invalidVariableError + + /** + * Returns the raw JSON value of [modelGraderParseError]. + * + * Unlike [modelGraderParseError], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("model_grader_parse_error") + @ExcludeMissing + fun _modelGraderParseError(): JsonField = modelGraderParseError + + /** + * Returns the raw JSON value of [modelGraderRefusalError]. + * + * Unlike [modelGraderRefusalError], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("model_grader_refusal_error") + @ExcludeMissing + fun _modelGraderRefusalError(): JsonField = modelGraderRefusalError + + /** + * Returns the raw JSON value of [modelGraderServerError]. + * + * Unlike [modelGraderServerError], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("model_grader_server_error") + @ExcludeMissing + fun _modelGraderServerError(): JsonField = modelGraderServerError + + /** + * Returns the raw JSON value of [modelGraderServerErrorDetails]. + * + * Unlike [modelGraderServerErrorDetails], this method doesn't throw if the JSON field + * has an unexpected type. + */ + @JsonProperty("model_grader_server_error_details") + @ExcludeMissing + fun _modelGraderServerErrorDetails(): JsonField = modelGraderServerErrorDetails + + /** + * Returns the raw JSON value of [otherError]. + * + * Unlike [otherError], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("other_error") + @ExcludeMissing + fun _otherError(): JsonField = otherError + + /** + * Returns the raw JSON value of [pythonGraderRuntimeError]. + * + * Unlike [pythonGraderRuntimeError], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("python_grader_runtime_error") + @ExcludeMissing + fun _pythonGraderRuntimeError(): JsonField = pythonGraderRuntimeError + + /** + * Returns the raw JSON value of [pythonGraderRuntimeErrorDetails]. + * + * Unlike [pythonGraderRuntimeErrorDetails], this method doesn't throw if the JSON field + * has an unexpected type. + */ + @JsonProperty("python_grader_runtime_error_details") + @ExcludeMissing + fun _pythonGraderRuntimeErrorDetails(): JsonField = + pythonGraderRuntimeErrorDetails + + /** + * Returns the raw JSON value of [pythonGraderServerError]. + * + * Unlike [pythonGraderServerError], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("python_grader_server_error") + @ExcludeMissing + fun _pythonGraderServerError(): JsonField = pythonGraderServerError + + /** + * Returns the raw JSON value of [pythonGraderServerErrorType]. + * + * Unlike [pythonGraderServerErrorType], this method doesn't throw if the JSON field has + * an unexpected type. + */ + @JsonProperty("python_grader_server_error_type") + @ExcludeMissing + fun _pythonGraderServerErrorType(): JsonField = pythonGraderServerErrorType + + /** + * Returns the raw JSON value of [sampleParseError]. + * + * Unlike [sampleParseError], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("sample_parse_error") + @ExcludeMissing + fun _sampleParseError(): JsonField = sampleParseError + + /** + * Returns the raw JSON value of [truncatedObservationError]. + * + * Unlike [truncatedObservationError], this method doesn't throw if the JSON field has + * an unexpected type. + */ + @JsonProperty("truncated_observation_error") + @ExcludeMissing + fun _truncatedObservationError(): JsonField = truncatedObservationError + + /** + * Returns the raw JSON value of [unresponsiveRewardError]. + * + * Unlike [unresponsiveRewardError], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("unresponsive_reward_error") + @ExcludeMissing + fun _unresponsiveRewardError(): JsonField = unresponsiveRewardError + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Errors]. + * + * The following fields are required: + * ```java + * .formulaParseError() + * .invalidVariableError() + * .modelGraderParseError() + * .modelGraderRefusalError() + * .modelGraderServerError() + * .modelGraderServerErrorDetails() + * .otherError() + * .pythonGraderRuntimeError() + * .pythonGraderRuntimeErrorDetails() + * .pythonGraderServerError() + * .pythonGraderServerErrorType() + * .sampleParseError() + * .truncatedObservationError() + * .unresponsiveRewardError() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Errors]. */ + class Builder internal constructor() { + + private var formulaParseError: JsonField? = null + private var invalidVariableError: JsonField? = null + private var modelGraderParseError: JsonField? = null + private var modelGraderRefusalError: JsonField? = null + private var modelGraderServerError: JsonField? = null + private var modelGraderServerErrorDetails: JsonField? = null + private var otherError: JsonField? = null + private var pythonGraderRuntimeError: JsonField? = null + private var pythonGraderRuntimeErrorDetails: JsonField? = null + private var pythonGraderServerError: JsonField? = null + private var pythonGraderServerErrorType: JsonField? = null + private var sampleParseError: JsonField? = null + private var truncatedObservationError: JsonField? = null + private var unresponsiveRewardError: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(errors: Errors) = apply { + formulaParseError = errors.formulaParseError + invalidVariableError = errors.invalidVariableError + modelGraderParseError = errors.modelGraderParseError + modelGraderRefusalError = errors.modelGraderRefusalError + modelGraderServerError = errors.modelGraderServerError + modelGraderServerErrorDetails = errors.modelGraderServerErrorDetails + otherError = errors.otherError + pythonGraderRuntimeError = errors.pythonGraderRuntimeError + pythonGraderRuntimeErrorDetails = errors.pythonGraderRuntimeErrorDetails + pythonGraderServerError = errors.pythonGraderServerError + pythonGraderServerErrorType = errors.pythonGraderServerErrorType + sampleParseError = errors.sampleParseError + truncatedObservationError = errors.truncatedObservationError + unresponsiveRewardError = errors.unresponsiveRewardError + additionalProperties = errors.additionalProperties.toMutableMap() + } + + fun formulaParseError(formulaParseError: Boolean) = + formulaParseError(JsonField.of(formulaParseError)) + + /** + * Sets [Builder.formulaParseError] to an arbitrary JSON value. + * + * You should usually call [Builder.formulaParseError] with a well-typed [Boolean] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun formulaParseError(formulaParseError: JsonField) = apply { + this.formulaParseError = formulaParseError + } + + fun invalidVariableError(invalidVariableError: Boolean) = + invalidVariableError(JsonField.of(invalidVariableError)) + + /** + * Sets [Builder.invalidVariableError] to an arbitrary JSON value. + * + * You should usually call [Builder.invalidVariableError] with a well-typed + * [Boolean] value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun invalidVariableError(invalidVariableError: JsonField) = apply { + this.invalidVariableError = invalidVariableError + } + + fun modelGraderParseError(modelGraderParseError: Boolean) = + modelGraderParseError(JsonField.of(modelGraderParseError)) + + /** + * Sets [Builder.modelGraderParseError] to an arbitrary JSON value. + * + * You should usually call [Builder.modelGraderParseError] with a well-typed + * [Boolean] value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun modelGraderParseError(modelGraderParseError: JsonField) = apply { + this.modelGraderParseError = modelGraderParseError + } + + fun modelGraderRefusalError(modelGraderRefusalError: Boolean) = + modelGraderRefusalError(JsonField.of(modelGraderRefusalError)) + + /** + * Sets [Builder.modelGraderRefusalError] to an arbitrary JSON value. + * + * You should usually call [Builder.modelGraderRefusalError] with a well-typed + * [Boolean] value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun modelGraderRefusalError(modelGraderRefusalError: JsonField) = apply { + this.modelGraderRefusalError = modelGraderRefusalError + } + + fun modelGraderServerError(modelGraderServerError: Boolean) = + modelGraderServerError(JsonField.of(modelGraderServerError)) + + /** + * Sets [Builder.modelGraderServerError] to an arbitrary JSON value. + * + * You should usually call [Builder.modelGraderServerError] with a well-typed + * [Boolean] value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun modelGraderServerError(modelGraderServerError: JsonField) = apply { + this.modelGraderServerError = modelGraderServerError + } + + fun modelGraderServerErrorDetails(modelGraderServerErrorDetails: String?) = + modelGraderServerErrorDetails( + JsonField.ofNullable(modelGraderServerErrorDetails) + ) + + /** + * Alias for calling [Builder.modelGraderServerErrorDetails] with + * `modelGraderServerErrorDetails.orElse(null)`. + */ + fun modelGraderServerErrorDetails(modelGraderServerErrorDetails: Optional) = + modelGraderServerErrorDetails(modelGraderServerErrorDetails.getOrNull()) + + /** + * Sets [Builder.modelGraderServerErrorDetails] to an arbitrary JSON value. + * + * You should usually call [Builder.modelGraderServerErrorDetails] with a well-typed + * [String] value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun modelGraderServerErrorDetails( + modelGraderServerErrorDetails: JsonField + ) = apply { this.modelGraderServerErrorDetails = modelGraderServerErrorDetails } + + fun otherError(otherError: Boolean) = otherError(JsonField.of(otherError)) + + /** + * Sets [Builder.otherError] to an arbitrary JSON value. + * + * You should usually call [Builder.otherError] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun otherError(otherError: JsonField) = apply { + this.otherError = otherError + } + + fun pythonGraderRuntimeError(pythonGraderRuntimeError: Boolean) = + pythonGraderRuntimeError(JsonField.of(pythonGraderRuntimeError)) + + /** + * Sets [Builder.pythonGraderRuntimeError] to an arbitrary JSON value. + * + * You should usually call [Builder.pythonGraderRuntimeError] with a well-typed + * [Boolean] value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun pythonGraderRuntimeError(pythonGraderRuntimeError: JsonField) = apply { + this.pythonGraderRuntimeError = pythonGraderRuntimeError + } + + fun pythonGraderRuntimeErrorDetails(pythonGraderRuntimeErrorDetails: String?) = + pythonGraderRuntimeErrorDetails( + JsonField.ofNullable(pythonGraderRuntimeErrorDetails) + ) + + /** + * Alias for calling [Builder.pythonGraderRuntimeErrorDetails] with + * `pythonGraderRuntimeErrorDetails.orElse(null)`. + */ + fun pythonGraderRuntimeErrorDetails( + pythonGraderRuntimeErrorDetails: Optional + ) = pythonGraderRuntimeErrorDetails(pythonGraderRuntimeErrorDetails.getOrNull()) + + /** + * Sets [Builder.pythonGraderRuntimeErrorDetails] to an arbitrary JSON value. + * + * You should usually call [Builder.pythonGraderRuntimeErrorDetails] with a + * well-typed [String] value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ + fun pythonGraderRuntimeErrorDetails( + pythonGraderRuntimeErrorDetails: JsonField + ) = apply { this.pythonGraderRuntimeErrorDetails = pythonGraderRuntimeErrorDetails } + + fun pythonGraderServerError(pythonGraderServerError: Boolean) = + pythonGraderServerError(JsonField.of(pythonGraderServerError)) + + /** + * Sets [Builder.pythonGraderServerError] to an arbitrary JSON value. + * + * You should usually call [Builder.pythonGraderServerError] with a well-typed + * [Boolean] value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun pythonGraderServerError(pythonGraderServerError: JsonField) = apply { + this.pythonGraderServerError = pythonGraderServerError + } + + fun pythonGraderServerErrorType(pythonGraderServerErrorType: String?) = + pythonGraderServerErrorType(JsonField.ofNullable(pythonGraderServerErrorType)) + + /** + * Alias for calling [Builder.pythonGraderServerErrorType] with + * `pythonGraderServerErrorType.orElse(null)`. + */ + fun pythonGraderServerErrorType(pythonGraderServerErrorType: Optional) = + pythonGraderServerErrorType(pythonGraderServerErrorType.getOrNull()) + + /** + * Sets [Builder.pythonGraderServerErrorType] to an arbitrary JSON value. + * + * You should usually call [Builder.pythonGraderServerErrorType] with a well-typed + * [String] value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun pythonGraderServerErrorType(pythonGraderServerErrorType: JsonField) = + apply { + this.pythonGraderServerErrorType = pythonGraderServerErrorType + } + + fun sampleParseError(sampleParseError: Boolean) = + sampleParseError(JsonField.of(sampleParseError)) + + /** + * Sets [Builder.sampleParseError] to an arbitrary JSON value. + * + * You should usually call [Builder.sampleParseError] with a well-typed [Boolean] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun sampleParseError(sampleParseError: JsonField) = apply { + this.sampleParseError = sampleParseError + } + + fun truncatedObservationError(truncatedObservationError: Boolean) = + truncatedObservationError(JsonField.of(truncatedObservationError)) + + /** + * Sets [Builder.truncatedObservationError] to an arbitrary JSON value. + * + * You should usually call [Builder.truncatedObservationError] with a well-typed + * [Boolean] value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun truncatedObservationError(truncatedObservationError: JsonField) = + apply { + this.truncatedObservationError = truncatedObservationError + } + + fun unresponsiveRewardError(unresponsiveRewardError: Boolean) = + unresponsiveRewardError(JsonField.of(unresponsiveRewardError)) + + /** + * Sets [Builder.unresponsiveRewardError] to an arbitrary JSON value. + * + * You should usually call [Builder.unresponsiveRewardError] with a well-typed + * [Boolean] value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun unresponsiveRewardError(unresponsiveRewardError: JsonField) = apply { + this.unresponsiveRewardError = unresponsiveRewardError + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Errors]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .formulaParseError() + * .invalidVariableError() + * .modelGraderParseError() + * .modelGraderRefusalError() + * .modelGraderServerError() + * .modelGraderServerErrorDetails() + * .otherError() + * .pythonGraderRuntimeError() + * .pythonGraderRuntimeErrorDetails() + * .pythonGraderServerError() + * .pythonGraderServerErrorType() + * .sampleParseError() + * .truncatedObservationError() + * .unresponsiveRewardError() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Errors = + Errors( + checkRequired("formulaParseError", formulaParseError), + checkRequired("invalidVariableError", invalidVariableError), + checkRequired("modelGraderParseError", modelGraderParseError), + checkRequired("modelGraderRefusalError", modelGraderRefusalError), + checkRequired("modelGraderServerError", modelGraderServerError), + checkRequired( + "modelGraderServerErrorDetails", + modelGraderServerErrorDetails, + ), + checkRequired("otherError", otherError), + checkRequired("pythonGraderRuntimeError", pythonGraderRuntimeError), + checkRequired( + "pythonGraderRuntimeErrorDetails", + pythonGraderRuntimeErrorDetails, + ), + checkRequired("pythonGraderServerError", pythonGraderServerError), + checkRequired("pythonGraderServerErrorType", pythonGraderServerErrorType), + checkRequired("sampleParseError", sampleParseError), + checkRequired("truncatedObservationError", truncatedObservationError), + checkRequired("unresponsiveRewardError", unresponsiveRewardError), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Errors = apply { + if (validated) { + return@apply + } + + formulaParseError() + invalidVariableError() + modelGraderParseError() + modelGraderRefusalError() + modelGraderServerError() + modelGraderServerErrorDetails() + otherError() + pythonGraderRuntimeError() + pythonGraderRuntimeErrorDetails() + pythonGraderServerError() + pythonGraderServerErrorType() + sampleParseError() + truncatedObservationError() + unresponsiveRewardError() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (formulaParseError.asKnown().isPresent) 1 else 0) + + (if (invalidVariableError.asKnown().isPresent) 1 else 0) + + (if (modelGraderParseError.asKnown().isPresent) 1 else 0) + + (if (modelGraderRefusalError.asKnown().isPresent) 1 else 0) + + (if (modelGraderServerError.asKnown().isPresent) 1 else 0) + + (if (modelGraderServerErrorDetails.asKnown().isPresent) 1 else 0) + + (if (otherError.asKnown().isPresent) 1 else 0) + + (if (pythonGraderRuntimeError.asKnown().isPresent) 1 else 0) + + (if (pythonGraderRuntimeErrorDetails.asKnown().isPresent) 1 else 0) + + (if (pythonGraderServerError.asKnown().isPresent) 1 else 0) + + (if (pythonGraderServerErrorType.asKnown().isPresent) 1 else 0) + + (if (sampleParseError.asKnown().isPresent) 1 else 0) + + (if (truncatedObservationError.asKnown().isPresent) 1 else 0) + + (if (unresponsiveRewardError.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Errors && formulaParseError == other.formulaParseError && invalidVariableError == other.invalidVariableError && modelGraderParseError == other.modelGraderParseError && modelGraderRefusalError == other.modelGraderRefusalError && modelGraderServerError == other.modelGraderServerError && modelGraderServerErrorDetails == other.modelGraderServerErrorDetails && otherError == other.otherError && pythonGraderRuntimeError == other.pythonGraderRuntimeError && pythonGraderRuntimeErrorDetails == other.pythonGraderRuntimeErrorDetails && pythonGraderServerError == other.pythonGraderServerError && pythonGraderServerErrorType == other.pythonGraderServerErrorType && sampleParseError == other.sampleParseError && truncatedObservationError == other.truncatedObservationError && unresponsiveRewardError == other.unresponsiveRewardError && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(formulaParseError, invalidVariableError, modelGraderParseError, modelGraderRefusalError, modelGraderServerError, modelGraderServerErrorDetails, otherError, pythonGraderRuntimeError, pythonGraderRuntimeErrorDetails, pythonGraderServerError, pythonGraderServerErrorType, sampleParseError, truncatedObservationError, unresponsiveRewardError, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Errors{formulaParseError=$formulaParseError, invalidVariableError=$invalidVariableError, modelGraderParseError=$modelGraderParseError, modelGraderRefusalError=$modelGraderRefusalError, modelGraderServerError=$modelGraderServerError, modelGraderServerErrorDetails=$modelGraderServerErrorDetails, otherError=$otherError, pythonGraderRuntimeError=$pythonGraderRuntimeError, pythonGraderRuntimeErrorDetails=$pythonGraderRuntimeErrorDetails, pythonGraderServerError=$pythonGraderServerError, pythonGraderServerErrorType=$pythonGraderServerErrorType, sampleParseError=$sampleParseError, truncatedObservationError=$truncatedObservationError, unresponsiveRewardError=$unresponsiveRewardError, additionalProperties=$additionalProperties}" + } + + class Scores + @JsonCreator + private constructor( + @com.fasterxml.jackson.annotation.JsonValue + private val additionalProperties: Map + ) { + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Scores]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Scores]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(scores: Scores) = apply { + additionalProperties = scores.additionalProperties.toMutableMap() + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Scores]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Scores = Scores(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Scores = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + additionalProperties.count { (_, value) -> !value.isNull() && !value.isMissing() } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Scores && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = "Scores{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Metadata && errors == other.errors && executionTime == other.executionTime && name == other.name && sampledModelName == other.sampledModelName && scores == other.scores && tokenUsage == other.tokenUsage && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(errors, executionTime, name, sampledModelName, scores, tokenUsage, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Metadata{errors=$errors, executionTime=$executionTime, name=$name, sampledModelName=$sampledModelName, scores=$scores, tokenUsage=$tokenUsage, type=$type, additionalProperties=$additionalProperties}" + } + + class ModelGraderTokenUsagePerModel + @JsonCreator + private constructor( + @com.fasterxml.jackson.annotation.JsonValue + private val additionalProperties: Map + ) { + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [ModelGraderTokenUsagePerModel]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ModelGraderTokenUsagePerModel]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(modelGraderTokenUsagePerModel: ModelGraderTokenUsagePerModel) = + apply { + additionalProperties = + modelGraderTokenUsagePerModel.additionalProperties.toMutableMap() + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [ModelGraderTokenUsagePerModel]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): ModelGraderTokenUsagePerModel = + ModelGraderTokenUsagePerModel(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): ModelGraderTokenUsagePerModel = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + additionalProperties.count { (_, value) -> !value.isNull() && !value.isMissing() } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ModelGraderTokenUsagePerModel && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ModelGraderTokenUsagePerModel{additionalProperties=$additionalProperties}" + } + + class SubRewards + @JsonCreator + private constructor( + @com.fasterxml.jackson.annotation.JsonValue + private val additionalProperties: Map + ) { + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [SubRewards]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SubRewards]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(subRewards: SubRewards) = apply { + additionalProperties = subRewards.additionalProperties.toMutableMap() + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [SubRewards]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): SubRewards = SubRewards(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): SubRewards = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + additionalProperties.count { (_, value) -> !value.isNull() && !value.isMissing() } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is SubRewards && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = "SubRewards{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is GraderRunResponse && metadata == other.metadata && modelGraderTokenUsagePerModel == other.modelGraderTokenUsagePerModel && reward == other.reward && subRewards == other.subRewards && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(metadata, modelGraderTokenUsagePerModel, reward, subRewards, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "GraderRunResponse{metadata=$metadata, modelGraderTokenUsagePerModel=$modelGraderTokenUsagePerModel, reward=$reward, subRewards=$subRewards, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/alpha/graders/GraderValidateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/alpha/graders/GraderValidateParams.kt new file mode 100644 index 00000000..329bf9cb --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/alpha/graders/GraderValidateParams.kt @@ -0,0 +1,747 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.finetuning.alpha.graders + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.BaseDeserializer +import com.openai.core.BaseSerializer +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.Params +import com.openai.core.allMaxBy +import com.openai.core.checkRequired +import com.openai.core.getOrThrow +import com.openai.core.http.Headers +import com.openai.core.http.QueryParams +import com.openai.errors.OpenAIInvalidDataException +import com.openai.models.graders.gradermodels.MultiGrader +import com.openai.models.graders.gradermodels.PythonGrader +import com.openai.models.graders.gradermodels.ScoreModelGrader +import com.openai.models.graders.gradermodels.StringCheckGrader +import com.openai.models.graders.gradermodels.TextSimilarityGrader +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Validate a grader. */ +class GraderValidateParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * The grader used for the fine-tuning job. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun grader(): Grader = body.grader() + + /** + * Returns the raw JSON value of [grader]. + * + * Unlike [grader], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _grader(): JsonField = body._grader() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [GraderValidateParams]. + * + * The following fields are required: + * ```java + * .grader() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [GraderValidateParams]. */ + class Builder internal constructor() { + + private var body: Body.Builder = Body.builder() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(graderValidateParams: GraderValidateParams) = apply { + body = graderValidateParams.body.toBuilder() + additionalHeaders = graderValidateParams.additionalHeaders.toBuilder() + additionalQueryParams = graderValidateParams.additionalQueryParams.toBuilder() + } + + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [grader] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** The grader used for the fine-tuning job. */ + fun grader(grader: Grader) = apply { body.grader(grader) } + + /** + * Sets [Builder.grader] to an arbitrary JSON value. + * + * You should usually call [Builder.grader] with a well-typed [Grader] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun grader(grader: JsonField) = apply { body.grader(grader) } + + /** Alias for calling [grader] with `Grader.ofStringCheck(stringCheck)`. */ + fun grader(stringCheck: StringCheckGrader) = apply { body.grader(stringCheck) } + + /** Alias for calling [grader] with `Grader.ofTextSimilarity(textSimilarity)`. */ + fun grader(textSimilarity: TextSimilarityGrader) = apply { body.grader(textSimilarity) } + + /** Alias for calling [grader] with `Grader.ofPython(python)`. */ + fun grader(python: PythonGrader) = apply { body.grader(python) } + + /** Alias for calling [grader] with `Grader.ofScoreModel(scoreModel)`. */ + fun grader(scoreModel: ScoreModelGrader) = apply { body.grader(scoreModel) } + + /** Alias for calling [grader] with `Grader.ofMulti(multi)`. */ + fun grader(multi: MultiGrader) = apply { body.grader(multi) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) + } + + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } + + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } + + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } + + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } + + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } + + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + /** + * Returns an immutable instance of [GraderValidateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .grader() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): GraderValidateParams = + GraderValidateParams( + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + private constructor( + private val grader: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("grader") @ExcludeMissing grader: JsonField = JsonMissing.of() + ) : this(grader, mutableMapOf()) + + /** + * The grader used for the fine-tuning job. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun grader(): Grader = grader.getRequired("grader") + + /** + * Returns the raw JSON value of [grader]. + * + * Unlike [grader], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("grader") @ExcludeMissing fun _grader(): JsonField = grader + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Body]. + * + * The following fields are required: + * ```java + * .grader() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var grader: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + grader = body.grader + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** The grader used for the fine-tuning job. */ + fun grader(grader: Grader) = grader(JsonField.of(grader)) + + /** + * Sets [Builder.grader] to an arbitrary JSON value. + * + * You should usually call [Builder.grader] with a well-typed [Grader] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun grader(grader: JsonField) = apply { this.grader = grader } + + /** Alias for calling [grader] with `Grader.ofStringCheck(stringCheck)`. */ + fun grader(stringCheck: StringCheckGrader) = grader(Grader.ofStringCheck(stringCheck)) + + /** Alias for calling [grader] with `Grader.ofTextSimilarity(textSimilarity)`. */ + fun grader(textSimilarity: TextSimilarityGrader) = + grader(Grader.ofTextSimilarity(textSimilarity)) + + /** Alias for calling [grader] with `Grader.ofPython(python)`. */ + fun grader(python: PythonGrader) = grader(Grader.ofPython(python)) + + /** Alias for calling [grader] with `Grader.ofScoreModel(scoreModel)`. */ + fun grader(scoreModel: ScoreModelGrader) = grader(Grader.ofScoreModel(scoreModel)) + + /** Alias for calling [grader] with `Grader.ofMulti(multi)`. */ + fun grader(multi: MultiGrader) = grader(Grader.ofMulti(multi)) + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .grader() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body(checkRequired("grader", grader), additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + grader().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = (grader.asKnown().getOrNull()?.validity() ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Body && grader == other.grader && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(grader, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = "Body{grader=$grader, additionalProperties=$additionalProperties}" + } + + /** The grader used for the fine-tuning job. */ + @JsonDeserialize(using = Grader.Deserializer::class) + @JsonSerialize(using = Grader.Serializer::class) + class Grader + private constructor( + private val stringCheck: StringCheckGrader? = null, + private val textSimilarity: TextSimilarityGrader? = null, + private val python: PythonGrader? = null, + private val scoreModel: ScoreModelGrader? = null, + private val multi: MultiGrader? = null, + private val _json: JsonValue? = null, + ) { + + /** + * A StringCheckGrader object that performs a string comparison between input and reference + * using a specified operation. + */ + fun stringCheck(): Optional = Optional.ofNullable(stringCheck) + + /** A TextSimilarityGrader object which grades text based on similarity metrics. */ + fun textSimilarity(): Optional = Optional.ofNullable(textSimilarity) + + /** A PythonGrader object that runs a python script on the input. */ + fun python(): Optional = Optional.ofNullable(python) + + /** A ScoreModelGrader object that uses a model to assign a score to the input. */ + fun scoreModel(): Optional = Optional.ofNullable(scoreModel) + + /** + * A MultiGrader object combines the output of multiple graders to produce a single score. + */ + fun multi(): Optional = Optional.ofNullable(multi) + + fun isStringCheck(): Boolean = stringCheck != null + + fun isTextSimilarity(): Boolean = textSimilarity != null + + fun isPython(): Boolean = python != null + + fun isScoreModel(): Boolean = scoreModel != null + + fun isMulti(): Boolean = multi != null + + /** + * A StringCheckGrader object that performs a string comparison between input and reference + * using a specified operation. + */ + fun asStringCheck(): StringCheckGrader = stringCheck.getOrThrow("stringCheck") + + /** A TextSimilarityGrader object which grades text based on similarity metrics. */ + fun asTextSimilarity(): TextSimilarityGrader = textSimilarity.getOrThrow("textSimilarity") + + /** A PythonGrader object that runs a python script on the input. */ + fun asPython(): PythonGrader = python.getOrThrow("python") + + /** A ScoreModelGrader object that uses a model to assign a score to the input. */ + fun asScoreModel(): ScoreModelGrader = scoreModel.getOrThrow("scoreModel") + + /** + * A MultiGrader object combines the output of multiple graders to produce a single score. + */ + fun asMulti(): MultiGrader = multi.getOrThrow("multi") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + stringCheck != null -> visitor.visitStringCheck(stringCheck) + textSimilarity != null -> visitor.visitTextSimilarity(textSimilarity) + python != null -> visitor.visitPython(python) + scoreModel != null -> visitor.visitScoreModel(scoreModel) + multi != null -> visitor.visitMulti(multi) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): Grader = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitStringCheck(stringCheck: StringCheckGrader) { + stringCheck.validate() + } + + override fun visitTextSimilarity(textSimilarity: TextSimilarityGrader) { + textSimilarity.validate() + } + + override fun visitPython(python: PythonGrader) { + python.validate() + } + + override fun visitScoreModel(scoreModel: ScoreModelGrader) { + scoreModel.validate() + } + + override fun visitMulti(multi: MultiGrader) { + multi.validate() + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitStringCheck(stringCheck: StringCheckGrader) = + stringCheck.validity() + + override fun visitTextSimilarity(textSimilarity: TextSimilarityGrader) = + textSimilarity.validity() + + override fun visitPython(python: PythonGrader) = python.validity() + + override fun visitScoreModel(scoreModel: ScoreModelGrader) = + scoreModel.validity() + + override fun visitMulti(multi: MultiGrader) = multi.validity() + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Grader && stringCheck == other.stringCheck && textSimilarity == other.textSimilarity && python == other.python && scoreModel == other.scoreModel && multi == other.multi /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(stringCheck, textSimilarity, python, scoreModel, multi) /* spotless:on */ + + override fun toString(): String = + when { + stringCheck != null -> "Grader{stringCheck=$stringCheck}" + textSimilarity != null -> "Grader{textSimilarity=$textSimilarity}" + python != null -> "Grader{python=$python}" + scoreModel != null -> "Grader{scoreModel=$scoreModel}" + multi != null -> "Grader{multi=$multi}" + _json != null -> "Grader{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Grader") + } + + companion object { + + /** + * A StringCheckGrader object that performs a string comparison between input and + * reference using a specified operation. + */ + @JvmStatic + fun ofStringCheck(stringCheck: StringCheckGrader) = Grader(stringCheck = stringCheck) + + /** A TextSimilarityGrader object which grades text based on similarity metrics. */ + @JvmStatic + fun ofTextSimilarity(textSimilarity: TextSimilarityGrader) = + Grader(textSimilarity = textSimilarity) + + /** A PythonGrader object that runs a python script on the input. */ + @JvmStatic fun ofPython(python: PythonGrader) = Grader(python = python) + + /** A ScoreModelGrader object that uses a model to assign a score to the input. */ + @JvmStatic + fun ofScoreModel(scoreModel: ScoreModelGrader) = Grader(scoreModel = scoreModel) + + /** + * A MultiGrader object combines the output of multiple graders to produce a single + * score. + */ + @JvmStatic fun ofMulti(multi: MultiGrader) = Grader(multi = multi) + } + + /** An interface that defines how to map each variant of [Grader] to a value of type [T]. */ + interface Visitor { + + /** + * A StringCheckGrader object that performs a string comparison between input and + * reference using a specified operation. + */ + fun visitStringCheck(stringCheck: StringCheckGrader): T + + /** A TextSimilarityGrader object which grades text based on similarity metrics. */ + fun visitTextSimilarity(textSimilarity: TextSimilarityGrader): T + + /** A PythonGrader object that runs a python script on the input. */ + fun visitPython(python: PythonGrader): T + + /** A ScoreModelGrader object that uses a model to assign a score to the input. */ + fun visitScoreModel(scoreModel: ScoreModelGrader): T + + /** + * A MultiGrader object combines the output of multiple graders to produce a single + * score. + */ + fun visitMulti(multi: MultiGrader): T + + /** + * Maps an unknown variant of [Grader] to a value of type [T]. + * + * An instance of [Grader] can contain an unknown variant if it was deserialized from + * data that doesn't match any known variant. For example, if the SDK is on an older + * version than the API, then the API may respond with new variants that the SDK is + * unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown Grader: $json") + } + } + + internal class Deserializer : BaseDeserializer(Grader::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): Grader { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + Grader(stringCheck = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + Grader(textSimilarity = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + Grader(python = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + Grader(scoreModel = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + Grader(multi = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with + // all the possible variants (e.g. deserializing from boolean). + 0 -> Grader(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely + // valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(Grader::class) { + + override fun serialize( + value: Grader, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.stringCheck != null -> generator.writeObject(value.stringCheck) + value.textSimilarity != null -> generator.writeObject(value.textSimilarity) + value.python != null -> generator.writeObject(value.python) + value.scoreModel != null -> generator.writeObject(value.scoreModel) + value.multi != null -> generator.writeObject(value.multi) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Grader") + } + } + } + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is GraderValidateParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "GraderValidateParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/alpha/graders/GraderValidateResponse.kt b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/alpha/graders/GraderValidateResponse.kt new file mode 100644 index 00000000..c3229eb5 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/alpha/graders/GraderValidateResponse.kt @@ -0,0 +1,478 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.finetuning.alpha.graders + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.BaseDeserializer +import com.openai.core.BaseSerializer +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.allMaxBy +import com.openai.core.getOrThrow +import com.openai.errors.OpenAIInvalidDataException +import com.openai.models.graders.gradermodels.MultiGrader +import com.openai.models.graders.gradermodels.PythonGrader +import com.openai.models.graders.gradermodels.ScoreModelGrader +import com.openai.models.graders.gradermodels.StringCheckGrader +import com.openai.models.graders.gradermodels.TextSimilarityGrader +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class GraderValidateResponse +private constructor( + private val grader: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("grader") @ExcludeMissing grader: JsonField = JsonMissing.of() + ) : this(grader, mutableMapOf()) + + /** + * The grader used for the fine-tuning job. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun grader(): Optional = grader.getOptional("grader") + + /** + * Returns the raw JSON value of [grader]. + * + * Unlike [grader], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("grader") @ExcludeMissing fun _grader(): JsonField = grader + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [GraderValidateResponse]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [GraderValidateResponse]. */ + class Builder internal constructor() { + + private var grader: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(graderValidateResponse: GraderValidateResponse) = apply { + grader = graderValidateResponse.grader + additionalProperties = graderValidateResponse.additionalProperties.toMutableMap() + } + + /** The grader used for the fine-tuning job. */ + fun grader(grader: Grader) = grader(JsonField.of(grader)) + + /** + * Sets [Builder.grader] to an arbitrary JSON value. + * + * You should usually call [Builder.grader] with a well-typed [Grader] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun grader(grader: JsonField) = apply { this.grader = grader } + + /** Alias for calling [grader] with `Grader.ofStringCheck(stringCheck)`. */ + fun grader(stringCheck: StringCheckGrader) = grader(Grader.ofStringCheck(stringCheck)) + + /** Alias for calling [grader] with `Grader.ofTextSimilarity(textSimilarity)`. */ + fun grader(textSimilarity: TextSimilarityGrader) = + grader(Grader.ofTextSimilarity(textSimilarity)) + + /** Alias for calling [grader] with `Grader.ofPython(python)`. */ + fun grader(python: PythonGrader) = grader(Grader.ofPython(python)) + + /** Alias for calling [grader] with `Grader.ofScoreModel(scoreModel)`. */ + fun grader(scoreModel: ScoreModelGrader) = grader(Grader.ofScoreModel(scoreModel)) + + /** Alias for calling [grader] with `Grader.ofMulti(multi)`. */ + fun grader(multi: MultiGrader) = grader(Grader.ofMulti(multi)) + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [GraderValidateResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): GraderValidateResponse = + GraderValidateResponse(grader, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): GraderValidateResponse = apply { + if (validated) { + return@apply + } + + grader().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = (grader.asKnown().getOrNull()?.validity() ?: 0) + + /** The grader used for the fine-tuning job. */ + @JsonDeserialize(using = Grader.Deserializer::class) + @JsonSerialize(using = Grader.Serializer::class) + class Grader + private constructor( + private val stringCheck: StringCheckGrader? = null, + private val textSimilarity: TextSimilarityGrader? = null, + private val python: PythonGrader? = null, + private val scoreModel: ScoreModelGrader? = null, + private val multi: MultiGrader? = null, + private val _json: JsonValue? = null, + ) { + + /** + * A StringCheckGrader object that performs a string comparison between input and reference + * using a specified operation. + */ + fun stringCheck(): Optional = Optional.ofNullable(stringCheck) + + /** A TextSimilarityGrader object which grades text based on similarity metrics. */ + fun textSimilarity(): Optional = Optional.ofNullable(textSimilarity) + + /** A PythonGrader object that runs a python script on the input. */ + fun python(): Optional = Optional.ofNullable(python) + + /** A ScoreModelGrader object that uses a model to assign a score to the input. */ + fun scoreModel(): Optional = Optional.ofNullable(scoreModel) + + /** + * A MultiGrader object combines the output of multiple graders to produce a single score. + */ + fun multi(): Optional = Optional.ofNullable(multi) + + fun isStringCheck(): Boolean = stringCheck != null + + fun isTextSimilarity(): Boolean = textSimilarity != null + + fun isPython(): Boolean = python != null + + fun isScoreModel(): Boolean = scoreModel != null + + fun isMulti(): Boolean = multi != null + + /** + * A StringCheckGrader object that performs a string comparison between input and reference + * using a specified operation. + */ + fun asStringCheck(): StringCheckGrader = stringCheck.getOrThrow("stringCheck") + + /** A TextSimilarityGrader object which grades text based on similarity metrics. */ + fun asTextSimilarity(): TextSimilarityGrader = textSimilarity.getOrThrow("textSimilarity") + + /** A PythonGrader object that runs a python script on the input. */ + fun asPython(): PythonGrader = python.getOrThrow("python") + + /** A ScoreModelGrader object that uses a model to assign a score to the input. */ + fun asScoreModel(): ScoreModelGrader = scoreModel.getOrThrow("scoreModel") + + /** + * A MultiGrader object combines the output of multiple graders to produce a single score. + */ + fun asMulti(): MultiGrader = multi.getOrThrow("multi") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + stringCheck != null -> visitor.visitStringCheck(stringCheck) + textSimilarity != null -> visitor.visitTextSimilarity(textSimilarity) + python != null -> visitor.visitPython(python) + scoreModel != null -> visitor.visitScoreModel(scoreModel) + multi != null -> visitor.visitMulti(multi) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): Grader = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitStringCheck(stringCheck: StringCheckGrader) { + stringCheck.validate() + } + + override fun visitTextSimilarity(textSimilarity: TextSimilarityGrader) { + textSimilarity.validate() + } + + override fun visitPython(python: PythonGrader) { + python.validate() + } + + override fun visitScoreModel(scoreModel: ScoreModelGrader) { + scoreModel.validate() + } + + override fun visitMulti(multi: MultiGrader) { + multi.validate() + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitStringCheck(stringCheck: StringCheckGrader) = + stringCheck.validity() + + override fun visitTextSimilarity(textSimilarity: TextSimilarityGrader) = + textSimilarity.validity() + + override fun visitPython(python: PythonGrader) = python.validity() + + override fun visitScoreModel(scoreModel: ScoreModelGrader) = + scoreModel.validity() + + override fun visitMulti(multi: MultiGrader) = multi.validity() + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Grader && stringCheck == other.stringCheck && textSimilarity == other.textSimilarity && python == other.python && scoreModel == other.scoreModel && multi == other.multi /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(stringCheck, textSimilarity, python, scoreModel, multi) /* spotless:on */ + + override fun toString(): String = + when { + stringCheck != null -> "Grader{stringCheck=$stringCheck}" + textSimilarity != null -> "Grader{textSimilarity=$textSimilarity}" + python != null -> "Grader{python=$python}" + scoreModel != null -> "Grader{scoreModel=$scoreModel}" + multi != null -> "Grader{multi=$multi}" + _json != null -> "Grader{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Grader") + } + + companion object { + + /** + * A StringCheckGrader object that performs a string comparison between input and + * reference using a specified operation. + */ + @JvmStatic + fun ofStringCheck(stringCheck: StringCheckGrader) = Grader(stringCheck = stringCheck) + + /** A TextSimilarityGrader object which grades text based on similarity metrics. */ + @JvmStatic + fun ofTextSimilarity(textSimilarity: TextSimilarityGrader) = + Grader(textSimilarity = textSimilarity) + + /** A PythonGrader object that runs a python script on the input. */ + @JvmStatic fun ofPython(python: PythonGrader) = Grader(python = python) + + /** A ScoreModelGrader object that uses a model to assign a score to the input. */ + @JvmStatic + fun ofScoreModel(scoreModel: ScoreModelGrader) = Grader(scoreModel = scoreModel) + + /** + * A MultiGrader object combines the output of multiple graders to produce a single + * score. + */ + @JvmStatic fun ofMulti(multi: MultiGrader) = Grader(multi = multi) + } + + /** An interface that defines how to map each variant of [Grader] to a value of type [T]. */ + interface Visitor { + + /** + * A StringCheckGrader object that performs a string comparison between input and + * reference using a specified operation. + */ + fun visitStringCheck(stringCheck: StringCheckGrader): T + + /** A TextSimilarityGrader object which grades text based on similarity metrics. */ + fun visitTextSimilarity(textSimilarity: TextSimilarityGrader): T + + /** A PythonGrader object that runs a python script on the input. */ + fun visitPython(python: PythonGrader): T + + /** A ScoreModelGrader object that uses a model to assign a score to the input. */ + fun visitScoreModel(scoreModel: ScoreModelGrader): T + + /** + * A MultiGrader object combines the output of multiple graders to produce a single + * score. + */ + fun visitMulti(multi: MultiGrader): T + + /** + * Maps an unknown variant of [Grader] to a value of type [T]. + * + * An instance of [Grader] can contain an unknown variant if it was deserialized from + * data that doesn't match any known variant. For example, if the SDK is on an older + * version than the API, then the API may respond with new variants that the SDK is + * unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown Grader: $json") + } + } + + internal class Deserializer : BaseDeserializer(Grader::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): Grader { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + Grader(stringCheck = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + Grader(textSimilarity = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + Grader(python = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + Grader(scoreModel = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + Grader(multi = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with + // all the possible variants (e.g. deserializing from boolean). + 0 -> Grader(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely + // valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(Grader::class) { + + override fun serialize( + value: Grader, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.stringCheck != null -> generator.writeObject(value.stringCheck) + value.textSimilarity != null -> generator.writeObject(value.textSimilarity) + value.python != null -> generator.writeObject(value.python) + value.scoreModel != null -> generator.writeObject(value.scoreModel) + value.multi != null -> generator.writeObject(value.multi) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Grader") + } + } + } + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is GraderValidateResponse && grader == other.grader && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(grader, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "GraderValidateResponse{grader=$grader, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/checkpoints/permissions/PermissionCreatePage.kt b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/checkpoints/permissions/PermissionCreatePage.kt index ea6aeac9..fd72758d 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/checkpoints/permissions/PermissionCreatePage.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/checkpoints/permissions/PermissionCreatePage.kt @@ -2,13 +2,12 @@ package com.openai.models.finetuning.checkpoints.permissions +import com.openai.core.AutoPager import com.openai.core.JsonValue +import com.openai.core.Page import com.openai.core.checkRequired import com.openai.services.blocking.finetuning.checkpoints.PermissionService import java.util.Objects -import java.util.Optional -import java.util.stream.Stream -import java.util.stream.StreamSupport import kotlin.jvm.optionals.getOrNull /** @see [PermissionService.create] */ @@ -17,7 +16,7 @@ private constructor( private val service: PermissionService, private val params: PermissionCreateParams, private val response: PermissionCreatePageResponse, -) { +) : Page { /** * Delegates to [PermissionCreatePageResponse], but gracefully handles missing data. @@ -30,14 +29,16 @@ private constructor( /** @see [PermissionCreatePageResponse.object_] */ fun object_(): JsonValue = response._object_() - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional = Optional.empty() + override fun hasNextPage(): Boolean = items().isNotEmpty() - fun getNextPage(): Optional = - getNextPageParams().map { service.create(it) } + fun nextPageParams(): PermissionCreateParams = + throw IllegalStateException("Cannot construct next page params") - fun autoPager(): AutoPager = AutoPager(this) + override fun nextPage(): PermissionCreatePage = service.create(nextPageParams()) + + fun autoPager(): AutoPager = AutoPager.from(this) /** The parameters that were used to request this page. */ fun params(): PermissionCreateParams = params @@ -106,26 +107,6 @@ private constructor( ) } - class AutoPager(private val firstPage: PermissionCreatePage) : - Iterable { - - override fun iterator(): Iterator = iterator { - var page = firstPage - var index = 0 - while (true) { - while (index < page.data().size) { - yield(page.data()[index++]) - } - page = page.getNextPage().getOrNull() ?: break - index = 0 - } - } - - fun stream(): Stream { - return StreamSupport.stream(spliterator(), false) - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/checkpoints/permissions/PermissionCreatePageAsync.kt b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/checkpoints/permissions/PermissionCreatePageAsync.kt index 174dc4c7..c67b8a80 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/checkpoints/permissions/PermissionCreatePageAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/checkpoints/permissions/PermissionCreatePageAsync.kt @@ -2,23 +2,24 @@ package com.openai.models.finetuning.checkpoints.permissions +import com.openai.core.AutoPagerAsync import com.openai.core.JsonValue +import com.openai.core.PageAsync import com.openai.core.checkRequired import com.openai.services.async.finetuning.checkpoints.PermissionServiceAsync import java.util.Objects -import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor -import java.util.function.Predicate import kotlin.jvm.optionals.getOrNull /** @see [PermissionServiceAsync.create] */ class PermissionCreatePageAsync private constructor( private val service: PermissionServiceAsync, + private val streamHandlerExecutor: Executor, private val params: PermissionCreateParams, private val response: PermissionCreatePageResponse, -) { +) : PageAsync { /** * Delegates to [PermissionCreatePageResponse], but gracefully handles missing data. @@ -31,16 +32,18 @@ private constructor( /** @see [PermissionCreatePageResponse.object_] */ fun object_(): JsonValue = response._object_() - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional = Optional.empty() + override fun hasNextPage(): Boolean = items().isNotEmpty() - fun getNextPage(): CompletableFuture> = - getNextPageParams() - .map { service.create(it).thenApply { Optional.of(it) } } - .orElseGet { CompletableFuture.completedFuture(Optional.empty()) } + fun nextPageParams(): PermissionCreateParams = + throw IllegalStateException("Cannot construct next page params") - fun autoPager(): AutoPager = AutoPager(this) + override fun nextPage(): CompletableFuture = + service.create(nextPageParams()) + + fun autoPager(): AutoPagerAsync = + AutoPagerAsync.from(this, streamHandlerExecutor) /** The parameters that were used to request this page. */ fun params(): PermissionCreateParams = params @@ -58,6 +61,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -69,18 +73,24 @@ private constructor( class Builder internal constructor() { private var service: PermissionServiceAsync? = null + private var streamHandlerExecutor: Executor? = null private var params: PermissionCreateParams? = null private var response: PermissionCreatePageResponse? = null @JvmSynthetic internal fun from(permissionCreatePageAsync: PermissionCreatePageAsync) = apply { service = permissionCreatePageAsync.service + streamHandlerExecutor = permissionCreatePageAsync.streamHandlerExecutor params = permissionCreatePageAsync.params response = permissionCreatePageAsync.response } fun service(service: PermissionServiceAsync) = apply { this.service = service } + fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply { + this.streamHandlerExecutor = streamHandlerExecutor + } + /** The parameters that were used to request this page. */ fun params(params: PermissionCreateParams) = apply { this.params = params } @@ -95,6 +105,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -104,50 +115,22 @@ private constructor( fun build(): PermissionCreatePageAsync = PermissionCreatePageAsync( checkRequired("service", service), + checkRequired("streamHandlerExecutor", streamHandlerExecutor), checkRequired("params", params), checkRequired("response", response), ) } - class AutoPager(private val firstPage: PermissionCreatePageAsync) { - - fun forEach( - action: Predicate, - executor: Executor, - ): CompletableFuture { - fun CompletableFuture>.forEach( - action: (PermissionCreateResponse) -> Boolean, - executor: Executor, - ): CompletableFuture = - thenComposeAsync( - { page -> - page - .filter { it.data().all(action) } - .map { it.getNextPage().forEach(action, executor) } - .orElseGet { CompletableFuture.completedFuture(null) } - }, - executor, - ) - return CompletableFuture.completedFuture(Optional.of(firstPage)) - .forEach(action::test, executor) - } - - fun toList(executor: Executor): CompletableFuture> { - val values = mutableListOf() - return forEach(values::add, executor).thenApply { values } - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return /* spotless:off */ other is PermissionCreatePageAsync && service == other.service && params == other.params && response == other.response /* spotless:on */ + return /* spotless:off */ other is PermissionCreatePageAsync && service == other.service && streamHandlerExecutor == other.streamHandlerExecutor && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, params, response) /* spotless:on */ + override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, streamHandlerExecutor, params, response) /* spotless:on */ override fun toString() = - "PermissionCreatePageAsync{service=$service, params=$params, response=$response}" + "PermissionCreatePageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, response=$response}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/checkpoints/permissions/PermissionCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/checkpoints/permissions/PermissionCreateParams.kt index 6346ac32..dcbd6ccd 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/checkpoints/permissions/PermissionCreateParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/checkpoints/permissions/PermissionCreateParams.kt @@ -19,6 +19,7 @@ import com.openai.core.toImmutable import com.openai.errors.OpenAIInvalidDataException import java.util.Collections import java.util.Objects +import java.util.Optional import kotlin.jvm.optionals.getOrNull /** @@ -29,13 +30,13 @@ import kotlin.jvm.optionals.getOrNull */ class PermissionCreateParams private constructor( - private val fineTunedModelCheckpoint: String, + private val fineTunedModelCheckpoint: String?, private val body: Body, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun fineTunedModelCheckpoint(): String = fineTunedModelCheckpoint + fun fineTunedModelCheckpoint(): Optional = Optional.ofNullable(fineTunedModelCheckpoint) /** * The project identifiers to grant access to. @@ -67,7 +68,6 @@ private constructor( * * The following fields are required: * ```java - * .fineTunedModelCheckpoint() * .projectIds() * ``` */ @@ -90,10 +90,17 @@ private constructor( additionalQueryParams = permissionCreateParams.additionalQueryParams.toBuilder() } - fun fineTunedModelCheckpoint(fineTunedModelCheckpoint: String) = apply { + fun fineTunedModelCheckpoint(fineTunedModelCheckpoint: String?) = apply { this.fineTunedModelCheckpoint = fineTunedModelCheckpoint } + /** + * Alias for calling [Builder.fineTunedModelCheckpoint] with + * `fineTunedModelCheckpoint.orElse(null)`. + */ + fun fineTunedModelCheckpoint(fineTunedModelCheckpoint: Optional) = + fineTunedModelCheckpoint(fineTunedModelCheckpoint.getOrNull()) + /** * Sets the entire request body. * @@ -246,7 +253,6 @@ private constructor( * * The following fields are required: * ```java - * .fineTunedModelCheckpoint() * .projectIds() * ``` * @@ -254,7 +260,7 @@ private constructor( */ fun build(): PermissionCreateParams = PermissionCreateParams( - checkRequired("fineTunedModelCheckpoint", fineTunedModelCheckpoint), + fineTunedModelCheckpoint, body.build(), additionalHeaders.build(), additionalQueryParams.build(), @@ -265,7 +271,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> fineTunedModelCheckpoint + 0 -> fineTunedModelCheckpoint ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/checkpoints/permissions/PermissionDeleteParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/checkpoints/permissions/PermissionDeleteParams.kt index bf8173c5..ce09abfc 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/checkpoints/permissions/PermissionDeleteParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/checkpoints/permissions/PermissionDeleteParams.kt @@ -10,6 +10,7 @@ import com.openai.core.http.QueryParams import com.openai.core.toImmutable import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** * **NOTE:** This endpoint requires an [admin API key](../admin-api-keys). @@ -20,7 +21,7 @@ import java.util.Optional class PermissionDeleteParams private constructor( private val fineTunedModelCheckpoint: String, - private val permissionId: String, + private val permissionId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, @@ -28,7 +29,7 @@ private constructor( fun fineTunedModelCheckpoint(): String = fineTunedModelCheckpoint - fun permissionId(): String = permissionId + fun permissionId(): Optional = Optional.ofNullable(permissionId) fun _additionalBodyProperties(): Map = additionalBodyProperties @@ -46,7 +47,6 @@ private constructor( * The following fields are required: * ```java * .fineTunedModelCheckpoint() - * .permissionId() * ``` */ @JvmStatic fun builder() = Builder() @@ -75,7 +75,10 @@ private constructor( this.fineTunedModelCheckpoint = fineTunedModelCheckpoint } - fun permissionId(permissionId: String) = apply { this.permissionId = permissionId } + fun permissionId(permissionId: String?) = apply { this.permissionId = permissionId } + + /** Alias for calling [Builder.permissionId] with `permissionId.orElse(null)`. */ + fun permissionId(permissionId: Optional) = permissionId(permissionId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -205,7 +208,6 @@ private constructor( * The following fields are required: * ```java * .fineTunedModelCheckpoint() - * .permissionId() * ``` * * @throws IllegalStateException if any required field is unset. @@ -213,7 +215,7 @@ private constructor( fun build(): PermissionDeleteParams = PermissionDeleteParams( checkRequired("fineTunedModelCheckpoint", fineTunedModelCheckpoint), - checkRequired("permissionId", permissionId), + permissionId, additionalHeaders.build(), additionalQueryParams.build(), additionalBodyProperties.toImmutable(), @@ -226,7 +228,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { 0 -> fineTunedModelCheckpoint - 1 -> permissionId + 1 -> permissionId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/checkpoints/permissions/PermissionRetrieveParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/checkpoints/permissions/PermissionRetrieveParams.kt index e9276fee..2205d767 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/checkpoints/permissions/PermissionRetrieveParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/checkpoints/permissions/PermissionRetrieveParams.kt @@ -6,7 +6,6 @@ import com.fasterxml.jackson.annotation.JsonCreator import com.openai.core.Enum import com.openai.core.JsonField import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import com.openai.errors.OpenAIInvalidDataException @@ -22,7 +21,7 @@ import kotlin.jvm.optionals.getOrNull */ class PermissionRetrieveParams private constructor( - private val fineTunedModelCheckpoint: String, + private val fineTunedModelCheckpoint: String?, private val after: String?, private val limit: Long?, private val order: Order?, @@ -31,7 +30,7 @@ private constructor( private val additionalQueryParams: QueryParams, ) : Params { - fun fineTunedModelCheckpoint(): String = fineTunedModelCheckpoint + fun fineTunedModelCheckpoint(): Optional = Optional.ofNullable(fineTunedModelCheckpoint) /** Identifier for the last permission ID from the previous pagination request. */ fun after(): Optional = Optional.ofNullable(after) @@ -53,14 +52,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [PermissionRetrieveParams]. - * - * The following fields are required: - * ```java - * .fineTunedModelCheckpoint() - * ``` - */ + @JvmStatic fun none(): PermissionRetrieveParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [PermissionRetrieveParams]. */ @JvmStatic fun builder() = Builder() } @@ -86,10 +80,17 @@ private constructor( additionalQueryParams = permissionRetrieveParams.additionalQueryParams.toBuilder() } - fun fineTunedModelCheckpoint(fineTunedModelCheckpoint: String) = apply { + fun fineTunedModelCheckpoint(fineTunedModelCheckpoint: String?) = apply { this.fineTunedModelCheckpoint = fineTunedModelCheckpoint } + /** + * Alias for calling [Builder.fineTunedModelCheckpoint] with + * `fineTunedModelCheckpoint.orElse(null)`. + */ + fun fineTunedModelCheckpoint(fineTunedModelCheckpoint: Optional) = + fineTunedModelCheckpoint(fineTunedModelCheckpoint.getOrNull()) + /** Identifier for the last permission ID from the previous pagination request. */ fun after(after: String?) = apply { this.after = after } @@ -223,17 +224,10 @@ private constructor( * Returns an immutable instance of [PermissionRetrieveParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .fineTunedModelCheckpoint() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): PermissionRetrieveParams = PermissionRetrieveParams( - checkRequired("fineTunedModelCheckpoint", fineTunedModelCheckpoint), + fineTunedModelCheckpoint, after, limit, order, @@ -245,7 +239,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> fineTunedModelCheckpoint + 0 -> fineTunedModelCheckpoint ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/FineTuningJob.kt b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/FineTuningJob.kt index 9c99d13c..5780ac73 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/FineTuningJob.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/FineTuningJob.kt @@ -26,6 +26,9 @@ import com.openai.core.checkRequired import com.openai.core.getOrThrow import com.openai.core.toImmutable import com.openai.errors.OpenAIInvalidDataException +import com.openai.models.finetuning.methods.DpoMethod +import com.openai.models.finetuning.methods.ReinforcementMethod +import com.openai.models.finetuning.methods.SupervisedMethod import java.util.Collections import java.util.Objects import java.util.Optional @@ -2357,20 +2360,32 @@ private constructor( /** The method used for fine-tuning. */ class Method private constructor( - private val dpo: JsonField, - private val supervised: JsonField, private val type: JsonField, + private val dpo: JsonField, + private val reinforcement: JsonField, + private val supervised: JsonField, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( - @JsonProperty("dpo") @ExcludeMissing dpo: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + @JsonProperty("dpo") @ExcludeMissing dpo: JsonField = JsonMissing.of(), + @JsonProperty("reinforcement") + @ExcludeMissing + reinforcement: JsonField = JsonMissing.of(), @JsonProperty("supervised") @ExcludeMissing - supervised: JsonField = JsonMissing.of(), - @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), - ) : this(dpo, supervised, type, mutableMapOf()) + supervised: JsonField = JsonMissing.of(), + ) : this(type, dpo, reinforcement, supervised, mutableMapOf()) + + /** + * The type of method. Is either `supervised`, `dpo`, or `reinforcement`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun type(): Type = type.getRequired("type") /** * Configuration for the DPO fine-tuning method. @@ -2378,46 +2393,57 @@ private constructor( * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). */ - fun dpo(): Optional = dpo.getOptional("dpo") + fun dpo(): Optional = dpo.getOptional("dpo") /** - * Configuration for the supervised fine-tuning method. + * Configuration for the reinforcement fine-tuning method. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). */ - fun supervised(): Optional = supervised.getOptional("supervised") + fun reinforcement(): Optional = + reinforcement.getOptional("reinforcement") /** - * The type of method. Is either `supervised` or `dpo`. + * Configuration for the supervised fine-tuning method. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). */ - fun type(): Optional = type.getOptional("type") + fun supervised(): Optional = supervised.getOptional("supervised") + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type /** * Returns the raw JSON value of [dpo]. * * Unlike [dpo], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("dpo") @ExcludeMissing fun _dpo(): JsonField = dpo + @JsonProperty("dpo") @ExcludeMissing fun _dpo(): JsonField = dpo /** - * Returns the raw JSON value of [supervised]. + * Returns the raw JSON value of [reinforcement]. * - * Unlike [supervised], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [reinforcement], this method doesn't throw if the JSON field has an unexpected + * type. */ - @JsonProperty("supervised") + @JsonProperty("reinforcement") @ExcludeMissing - fun _supervised(): JsonField = supervised + fun _reinforcement(): JsonField = reinforcement /** - * Returns the raw JSON value of [type]. + * Returns the raw JSON value of [supervised]. * - * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [supervised], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + @JsonProperty("supervised") + @ExcludeMissing + fun _supervised(): JsonField = supervised @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { @@ -2433,63 +2459,87 @@ private constructor( companion object { - /** Returns a mutable builder for constructing an instance of [Method]. */ + /** + * Returns a mutable builder for constructing an instance of [Method]. + * + * The following fields are required: + * ```java + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } /** A builder for [Method]. */ class Builder internal constructor() { - private var dpo: JsonField = JsonMissing.of() - private var supervised: JsonField = JsonMissing.of() - private var type: JsonField = JsonMissing.of() + private var type: JsonField? = null + private var dpo: JsonField = JsonMissing.of() + private var reinforcement: JsonField = JsonMissing.of() + private var supervised: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(method: Method) = apply { + type = method.type dpo = method.dpo + reinforcement = method.reinforcement supervised = method.supervised - type = method.type additionalProperties = method.additionalProperties.toMutableMap() } - /** Configuration for the DPO fine-tuning method. */ - fun dpo(dpo: Dpo) = dpo(JsonField.of(dpo)) + /** The type of method. Is either `supervised`, `dpo`, or `reinforcement`. */ + fun type(type: Type) = type(JsonField.of(type)) /** - * Sets [Builder.dpo] to an arbitrary JSON value. + * Sets [Builder.type] to an arbitrary JSON value. * - * You should usually call [Builder.dpo] with a well-typed [Dpo] value instead. This + * You should usually call [Builder.type] with a well-typed [Type] value instead. This * method is primarily for setting the field to an undocumented or not yet supported * value. */ - fun dpo(dpo: JsonField) = apply { this.dpo = dpo } + fun type(type: JsonField) = apply { this.type = type } - /** Configuration for the supervised fine-tuning method. */ - fun supervised(supervised: Supervised) = supervised(JsonField.of(supervised)) + /** Configuration for the DPO fine-tuning method. */ + fun dpo(dpo: DpoMethod) = dpo(JsonField.of(dpo)) /** - * Sets [Builder.supervised] to an arbitrary JSON value. + * Sets [Builder.dpo] to an arbitrary JSON value. * - * You should usually call [Builder.supervised] with a well-typed [Supervised] value - * instead. This method is primarily for setting the field to an undocumented or not yet + * You should usually call [Builder.dpo] with a well-typed [DpoMethod] value instead. + * This method is primarily for setting the field to an undocumented or not yet * supported value. */ - fun supervised(supervised: JsonField) = apply { - this.supervised = supervised + fun dpo(dpo: JsonField) = apply { this.dpo = dpo } + + /** Configuration for the reinforcement fine-tuning method. */ + fun reinforcement(reinforcement: ReinforcementMethod) = + reinforcement(JsonField.of(reinforcement)) + + /** + * Sets [Builder.reinforcement] to an arbitrary JSON value. + * + * You should usually call [Builder.reinforcement] with a well-typed + * [ReinforcementMethod] value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ + fun reinforcement(reinforcement: JsonField) = apply { + this.reinforcement = reinforcement } - /** The type of method. Is either `supervised` or `dpo`. */ - fun type(type: Type) = type(JsonField.of(type)) + /** Configuration for the supervised fine-tuning method. */ + fun supervised(supervised: SupervisedMethod) = supervised(JsonField.of(supervised)) /** - * Sets [Builder.type] to an arbitrary JSON value. + * Sets [Builder.supervised] to an arbitrary JSON value. * - * You should usually call [Builder.type] with a well-typed [Type] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported - * value. + * You should usually call [Builder.supervised] with a well-typed [SupervisedMethod] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. */ - fun type(type: JsonField) = apply { this.type = type } + fun supervised(supervised: JsonField) = apply { + this.supervised = supervised + } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() @@ -2514,8 +2564,22 @@ private constructor( * Returns an immutable instance of [Method]. * * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. */ - fun build(): Method = Method(dpo, supervised, type, additionalProperties.toMutableMap()) + fun build(): Method = + Method( + checkRequired("type", type), + dpo, + reinforcement, + supervised, + additionalProperties.toMutableMap(), + ) } private var validated: Boolean = false @@ -2525,9 +2589,10 @@ private constructor( return@apply } + type().validate() dpo().ifPresent { it.validate() } + reinforcement().ifPresent { it.validate() } supervised().ifPresent { it.validate() } - type().ifPresent { it.validate() } validated = true } @@ -2547,2263 +2612,31 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (dpo.asKnown().getOrNull()?.validity() ?: 0) + - (supervised.asKnown().getOrNull()?.validity() ?: 0) + - (type.asKnown().getOrNull()?.validity() ?: 0) + (type.asKnown().getOrNull()?.validity() ?: 0) + + (dpo.asKnown().getOrNull()?.validity() ?: 0) + + (reinforcement.asKnown().getOrNull()?.validity() ?: 0) + + (supervised.asKnown().getOrNull()?.validity() ?: 0) - /** Configuration for the DPO fine-tuning method. */ - class Dpo - private constructor( - private val hyperparameters: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("hyperparameters") - @ExcludeMissing - hyperparameters: JsonField = JsonMissing.of() - ) : this(hyperparameters, mutableMapOf()) - - /** - * The hyperparameters used for the fine-tuning job. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun hyperparameters(): Optional = - hyperparameters.getOptional("hyperparameters") + /** The type of method. Is either `supervised`, `dpo`, or `reinforcement`. */ + class Type @JsonCreator private constructor(private val value: JsonField) : Enum { /** - * Returns the raw JSON value of [hyperparameters]. + * Returns this class instance's raw value. * - * Unlike [hyperparameters], this method doesn't throw if the JSON field has an - * unexpected type. + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. */ - @JsonProperty("hyperparameters") - @ExcludeMissing - fun _hyperparameters(): JsonField = hyperparameters - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value companion object { - /** Returns a mutable builder for constructing an instance of [Dpo]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Dpo]. */ - class Builder internal constructor() { - - private var hyperparameters: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(dpo: Dpo) = apply { - hyperparameters = dpo.hyperparameters - additionalProperties = dpo.additionalProperties.toMutableMap() - } - - /** The hyperparameters used for the fine-tuning job. */ - fun hyperparameters(hyperparameters: Hyperparameters) = - hyperparameters(JsonField.of(hyperparameters)) - - /** - * Sets [Builder.hyperparameters] to an arbitrary JSON value. - * - * You should usually call [Builder.hyperparameters] with a well-typed - * [Hyperparameters] value instead. This method is primarily for setting the field - * to an undocumented or not yet supported value. - */ - fun hyperparameters(hyperparameters: JsonField) = apply { - this.hyperparameters = hyperparameters - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [Dpo]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Dpo = Dpo(hyperparameters, additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false - - fun validate(): Dpo = apply { - if (validated) { - return@apply - } - - hyperparameters().ifPresent { it.validate() } - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = (hyperparameters.asKnown().getOrNull()?.validity() ?: 0) - - /** The hyperparameters used for the fine-tuning job. */ - class Hyperparameters - private constructor( - private val batchSize: JsonField, - private val beta: JsonField, - private val learningRateMultiplier: JsonField, - private val nEpochs: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("batch_size") - @ExcludeMissing - batchSize: JsonField = JsonMissing.of(), - @JsonProperty("beta") @ExcludeMissing beta: JsonField = JsonMissing.of(), - @JsonProperty("learning_rate_multiplier") - @ExcludeMissing - learningRateMultiplier: JsonField = JsonMissing.of(), - @JsonProperty("n_epochs") - @ExcludeMissing - nEpochs: JsonField = JsonMissing.of(), - ) : this(batchSize, beta, learningRateMultiplier, nEpochs, mutableMapOf()) - - /** - * Number of examples in each batch. A larger batch size means that model parameters - * are updated less frequently, but with lower variance. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun batchSize(): Optional = batchSize.getOptional("batch_size") - - /** - * The beta value for the DPO method. A higher beta value will increase the weight - * of the penalty between the policy and reference model. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun beta(): Optional = beta.getOptional("beta") - - /** - * Scaling factor for the learning rate. A smaller learning rate may be useful to - * avoid overfitting. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun learningRateMultiplier(): Optional = - learningRateMultiplier.getOptional("learning_rate_multiplier") - - /** - * The number of epochs to train the model for. An epoch refers to one full cycle - * through the training dataset. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun nEpochs(): Optional = nEpochs.getOptional("n_epochs") - - /** - * Returns the raw JSON value of [batchSize]. - * - * Unlike [batchSize], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("batch_size") - @ExcludeMissing - fun _batchSize(): JsonField = batchSize - - /** - * Returns the raw JSON value of [beta]. - * - * Unlike [beta], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("beta") @ExcludeMissing fun _beta(): JsonField = beta - - /** - * Returns the raw JSON value of [learningRateMultiplier]. - * - * Unlike [learningRateMultiplier], this method doesn't throw if the JSON field has - * an unexpected type. - */ - @JsonProperty("learning_rate_multiplier") - @ExcludeMissing - fun _learningRateMultiplier(): JsonField = - learningRateMultiplier - - /** - * Returns the raw JSON value of [nEpochs]. - * - * Unlike [nEpochs], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("n_epochs") - @ExcludeMissing - fun _nEpochs(): JsonField = nEpochs - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** - * Returns a mutable builder for constructing an instance of [Hyperparameters]. - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Hyperparameters]. */ - class Builder internal constructor() { - - private var batchSize: JsonField = JsonMissing.of() - private var beta: JsonField = JsonMissing.of() - private var learningRateMultiplier: JsonField = - JsonMissing.of() - private var nEpochs: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(hyperparameters: Hyperparameters) = apply { - batchSize = hyperparameters.batchSize - beta = hyperparameters.beta - learningRateMultiplier = hyperparameters.learningRateMultiplier - nEpochs = hyperparameters.nEpochs - additionalProperties = hyperparameters.additionalProperties.toMutableMap() - } - - /** - * Number of examples in each batch. A larger batch size means that model - * parameters are updated less frequently, but with lower variance. - */ - fun batchSize(batchSize: BatchSize) = batchSize(JsonField.of(batchSize)) - - /** - * Sets [Builder.batchSize] to an arbitrary JSON value. - * - * You should usually call [Builder.batchSize] with a well-typed [BatchSize] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun batchSize(batchSize: JsonField) = apply { - this.batchSize = batchSize - } - - /** Alias for calling [batchSize] with `BatchSize.ofAuto()`. */ - fun batchSizeAuto() = batchSize(BatchSize.ofAuto()) - - /** Alias for calling [batchSize] with `BatchSize.ofManual(manual)`. */ - fun batchSize(manual: Long) = batchSize(BatchSize.ofManual(manual)) - - /** - * The beta value for the DPO method. A higher beta value will increase the - * weight of the penalty between the policy and reference model. - */ - fun beta(beta: Beta) = beta(JsonField.of(beta)) - - /** - * Sets [Builder.beta] to an arbitrary JSON value. - * - * You should usually call [Builder.beta] with a well-typed [Beta] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun beta(beta: JsonField) = apply { this.beta = beta } - - /** Alias for calling [beta] with `Beta.ofAuto()`. */ - fun betaAuto() = beta(Beta.ofAuto()) - - /** Alias for calling [beta] with `Beta.ofManual(manual)`. */ - fun beta(manual: Double) = beta(Beta.ofManual(manual)) - - /** - * Scaling factor for the learning rate. A smaller learning rate may be useful - * to avoid overfitting. - */ - fun learningRateMultiplier(learningRateMultiplier: LearningRateMultiplier) = - learningRateMultiplier(JsonField.of(learningRateMultiplier)) - - /** - * Sets [Builder.learningRateMultiplier] to an arbitrary JSON value. - * - * You should usually call [Builder.learningRateMultiplier] with a well-typed - * [LearningRateMultiplier] value instead. This method is primarily for setting - * the field to an undocumented or not yet supported value. - */ - fun learningRateMultiplier( - learningRateMultiplier: JsonField - ) = apply { this.learningRateMultiplier = learningRateMultiplier } - - /** - * Alias for calling [learningRateMultiplier] with - * `LearningRateMultiplier.ofAuto()`. - */ - fun learningRateMultiplierAuto() = - learningRateMultiplier(LearningRateMultiplier.ofAuto()) - - /** - * Alias for calling [learningRateMultiplier] with - * `LearningRateMultiplier.ofManual(manual)`. - */ - fun learningRateMultiplier(manual: Double) = - learningRateMultiplier(LearningRateMultiplier.ofManual(manual)) - - /** - * The number of epochs to train the model for. An epoch refers to one full - * cycle through the training dataset. - */ - fun nEpochs(nEpochs: NEpochs) = nEpochs(JsonField.of(nEpochs)) - - /** - * Sets [Builder.nEpochs] to an arbitrary JSON value. - * - * You should usually call [Builder.nEpochs] with a well-typed [NEpochs] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun nEpochs(nEpochs: JsonField) = apply { this.nEpochs = nEpochs } - - /** Alias for calling [nEpochs] with `NEpochs.ofAuto()`. */ - fun nEpochsAuto() = nEpochs(NEpochs.ofAuto()) - - /** Alias for calling [nEpochs] with `NEpochs.ofManual(manual)`. */ - fun nEpochs(manual: Long) = nEpochs(NEpochs.ofManual(manual)) - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [Hyperparameters]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Hyperparameters = - Hyperparameters( - batchSize, - beta, - learningRateMultiplier, - nEpochs, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): Hyperparameters = apply { - if (validated) { - return@apply - } - - batchSize().ifPresent { it.validate() } - beta().ifPresent { it.validate() } - learningRateMultiplier().ifPresent { it.validate() } - nEpochs().ifPresent { it.validate() } - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (batchSize.asKnown().getOrNull()?.validity() ?: 0) + - (beta.asKnown().getOrNull()?.validity() ?: 0) + - (learningRateMultiplier.asKnown().getOrNull()?.validity() ?: 0) + - (nEpochs.asKnown().getOrNull()?.validity() ?: 0) - - /** - * Number of examples in each batch. A larger batch size means that model parameters - * are updated less frequently, but with lower variance. - */ - @JsonDeserialize(using = BatchSize.Deserializer::class) - @JsonSerialize(using = BatchSize.Serializer::class) - class BatchSize - private constructor( - private val auto: JsonValue? = null, - private val manual: Long? = null, - private val _json: JsonValue? = null, - ) { - - fun auto(): Optional = Optional.ofNullable(auto) - - fun manual(): Optional = Optional.ofNullable(manual) - - fun isAuto(): Boolean = auto != null - - fun isManual(): Boolean = manual != null - - fun asAuto(): JsonValue = auto.getOrThrow("auto") - - fun asManual(): Long = manual.getOrThrow("manual") - - fun _json(): Optional = Optional.ofNullable(_json) - - fun accept(visitor: Visitor): T = - when { - auto != null -> visitor.visitAuto(auto) - manual != null -> visitor.visitManual(manual) - else -> visitor.unknown(_json) - } - - private var validated: Boolean = false - - fun validate(): BatchSize = apply { - if (validated) { - return@apply - } - - accept( - object : Visitor { - override fun visitAuto(auto: JsonValue) { - auto.let { - if (it != JsonValue.from("auto")) { - throw OpenAIInvalidDataException( - "'auto' is invalid, received $it" - ) - } - } - } - - override fun visitManual(manual: Long) {} - } - ) - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - accept( - object : Visitor { - override fun visitAuto(auto: JsonValue) = - auto.let { if (it == JsonValue.from("auto")) 1 else 0 } - - override fun visitManual(manual: Long) = 1 - - override fun unknown(json: JsonValue?) = 0 - } - ) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is BatchSize && auto == other.auto && manual == other.manual /* spotless:on */ - } - - override fun hashCode(): Int = /* spotless:off */ Objects.hash(auto, manual) /* spotless:on */ - - override fun toString(): String = - when { - auto != null -> "BatchSize{auto=$auto}" - manual != null -> "BatchSize{manual=$manual}" - _json != null -> "BatchSize{_unknown=$_json}" - else -> throw IllegalStateException("Invalid BatchSize") - } - - companion object { - - @JvmStatic fun ofAuto() = BatchSize(auto = JsonValue.from("auto")) - - @JvmStatic fun ofManual(manual: Long) = BatchSize(manual = manual) - } - - /** - * An interface that defines how to map each variant of [BatchSize] to a value - * of type [T]. - */ - interface Visitor { - - fun visitAuto(auto: JsonValue): T - - fun visitManual(manual: Long): T - - /** - * Maps an unknown variant of [BatchSize] to a value of type [T]. - * - * An instance of [BatchSize] can contain an unknown variant if it was - * deserialized from data that doesn't match any known variant. For example, - * if the SDK is on an older version than the API, then the API may respond - * with new variants that the SDK is unaware of. - * - * @throws OpenAIInvalidDataException in the default implementation. - */ - fun unknown(json: JsonValue?): T { - throw OpenAIInvalidDataException("Unknown BatchSize: $json") - } - } - - internal class Deserializer : BaseDeserializer(BatchSize::class) { + @JvmField val SUPERVISED = of("supervised") - override fun ObjectCodec.deserialize(node: JsonNode): BatchSize { - val json = JsonValue.fromJsonNode(node) + @JvmField val DPO = of("dpo") - val bestMatches = - sequenceOf( - tryDeserialize(node, jacksonTypeRef()) - ?.let { BatchSize(auto = it, _json = json) } - ?.takeIf { it.isValid() }, - tryDeserialize(node, jacksonTypeRef())?.let { - BatchSize(manual = it, _json = json) - }, - ) - .filterNotNull() - .allMaxBy { it.validity() } - .toList() - return when (bestMatches.size) { - // This can happen if what we're deserializing is completely - // incompatible with all the possible variants (e.g. deserializing - // from object). - 0 -> BatchSize(_json = json) - 1 -> bestMatches.single() - // If there's more than one match with the highest validity, then - // use the first completely valid match, or simply the first match - // if none are completely valid. - else -> - bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() - } - } - } - - internal class Serializer : BaseSerializer(BatchSize::class) { - - override fun serialize( - value: BatchSize, - generator: JsonGenerator, - provider: SerializerProvider, - ) { - when { - value.auto != null -> generator.writeObject(value.auto) - value.manual != null -> generator.writeObject(value.manual) - value._json != null -> generator.writeObject(value._json) - else -> throw IllegalStateException("Invalid BatchSize") - } - } - } - } - - /** - * The beta value for the DPO method. A higher beta value will increase the weight - * of the penalty between the policy and reference model. - */ - @JsonDeserialize(using = Beta.Deserializer::class) - @JsonSerialize(using = Beta.Serializer::class) - class Beta - private constructor( - private val auto: JsonValue? = null, - private val manual: Double? = null, - private val _json: JsonValue? = null, - ) { - - fun auto(): Optional = Optional.ofNullable(auto) - - fun manual(): Optional = Optional.ofNullable(manual) - - fun isAuto(): Boolean = auto != null - - fun isManual(): Boolean = manual != null - - fun asAuto(): JsonValue = auto.getOrThrow("auto") - - fun asManual(): Double = manual.getOrThrow("manual") - - fun _json(): Optional = Optional.ofNullable(_json) - - fun accept(visitor: Visitor): T = - when { - auto != null -> visitor.visitAuto(auto) - manual != null -> visitor.visitManual(manual) - else -> visitor.unknown(_json) - } - - private var validated: Boolean = false - - fun validate(): Beta = apply { - if (validated) { - return@apply - } - - accept( - object : Visitor { - override fun visitAuto(auto: JsonValue) { - auto.let { - if (it != JsonValue.from("auto")) { - throw OpenAIInvalidDataException( - "'auto' is invalid, received $it" - ) - } - } - } - - override fun visitManual(manual: Double) {} - } - ) - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - accept( - object : Visitor { - override fun visitAuto(auto: JsonValue) = - auto.let { if (it == JsonValue.from("auto")) 1 else 0 } - - override fun visitManual(manual: Double) = 1 - - override fun unknown(json: JsonValue?) = 0 - } - ) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is Beta && auto == other.auto && manual == other.manual /* spotless:on */ - } - - override fun hashCode(): Int = /* spotless:off */ Objects.hash(auto, manual) /* spotless:on */ - - override fun toString(): String = - when { - auto != null -> "Beta{auto=$auto}" - manual != null -> "Beta{manual=$manual}" - _json != null -> "Beta{_unknown=$_json}" - else -> throw IllegalStateException("Invalid Beta") - } - - companion object { - - @JvmStatic fun ofAuto() = Beta(auto = JsonValue.from("auto")) - - @JvmStatic fun ofManual(manual: Double) = Beta(manual = manual) - } - - /** - * An interface that defines how to map each variant of [Beta] to a value of - * type [T]. - */ - interface Visitor { - - fun visitAuto(auto: JsonValue): T - - fun visitManual(manual: Double): T - - /** - * Maps an unknown variant of [Beta] to a value of type [T]. - * - * An instance of [Beta] can contain an unknown variant if it was - * deserialized from data that doesn't match any known variant. For example, - * if the SDK is on an older version than the API, then the API may respond - * with new variants that the SDK is unaware of. - * - * @throws OpenAIInvalidDataException in the default implementation. - */ - fun unknown(json: JsonValue?): T { - throw OpenAIInvalidDataException("Unknown Beta: $json") - } - } - - internal class Deserializer : BaseDeserializer(Beta::class) { - - override fun ObjectCodec.deserialize(node: JsonNode): Beta { - val json = JsonValue.fromJsonNode(node) - - val bestMatches = - sequenceOf( - tryDeserialize(node, jacksonTypeRef()) - ?.let { Beta(auto = it, _json = json) } - ?.takeIf { it.isValid() }, - tryDeserialize(node, jacksonTypeRef())?.let { - Beta(manual = it, _json = json) - }, - ) - .filterNotNull() - .allMaxBy { it.validity() } - .toList() - return when (bestMatches.size) { - // This can happen if what we're deserializing is completely - // incompatible with all the possible variants (e.g. deserializing - // from object). - 0 -> Beta(_json = json) - 1 -> bestMatches.single() - // If there's more than one match with the highest validity, then - // use the first completely valid match, or simply the first match - // if none are completely valid. - else -> - bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() - } - } - } - - internal class Serializer : BaseSerializer(Beta::class) { - - override fun serialize( - value: Beta, - generator: JsonGenerator, - provider: SerializerProvider, - ) { - when { - value.auto != null -> generator.writeObject(value.auto) - value.manual != null -> generator.writeObject(value.manual) - value._json != null -> generator.writeObject(value._json) - else -> throw IllegalStateException("Invalid Beta") - } - } - } - } - - /** - * Scaling factor for the learning rate. A smaller learning rate may be useful to - * avoid overfitting. - */ - @JsonDeserialize(using = LearningRateMultiplier.Deserializer::class) - @JsonSerialize(using = LearningRateMultiplier.Serializer::class) - class LearningRateMultiplier - private constructor( - private val auto: JsonValue? = null, - private val manual: Double? = null, - private val _json: JsonValue? = null, - ) { - - fun auto(): Optional = Optional.ofNullable(auto) - - fun manual(): Optional = Optional.ofNullable(manual) - - fun isAuto(): Boolean = auto != null - - fun isManual(): Boolean = manual != null - - fun asAuto(): JsonValue = auto.getOrThrow("auto") - - fun asManual(): Double = manual.getOrThrow("manual") - - fun _json(): Optional = Optional.ofNullable(_json) - - fun accept(visitor: Visitor): T = - when { - auto != null -> visitor.visitAuto(auto) - manual != null -> visitor.visitManual(manual) - else -> visitor.unknown(_json) - } - - private var validated: Boolean = false - - fun validate(): LearningRateMultiplier = apply { - if (validated) { - return@apply - } - - accept( - object : Visitor { - override fun visitAuto(auto: JsonValue) { - auto.let { - if (it != JsonValue.from("auto")) { - throw OpenAIInvalidDataException( - "'auto' is invalid, received $it" - ) - } - } - } - - override fun visitManual(manual: Double) {} - } - ) - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - accept( - object : Visitor { - override fun visitAuto(auto: JsonValue) = - auto.let { if (it == JsonValue.from("auto")) 1 else 0 } - - override fun visitManual(manual: Double) = 1 - - override fun unknown(json: JsonValue?) = 0 - } - ) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is LearningRateMultiplier && auto == other.auto && manual == other.manual /* spotless:on */ - } - - override fun hashCode(): Int = /* spotless:off */ Objects.hash(auto, manual) /* spotless:on */ - - override fun toString(): String = - when { - auto != null -> "LearningRateMultiplier{auto=$auto}" - manual != null -> "LearningRateMultiplier{manual=$manual}" - _json != null -> "LearningRateMultiplier{_unknown=$_json}" - else -> throw IllegalStateException("Invalid LearningRateMultiplier") - } - - companion object { - - @JvmStatic - fun ofAuto() = LearningRateMultiplier(auto = JsonValue.from("auto")) - - @JvmStatic - fun ofManual(manual: Double) = LearningRateMultiplier(manual = manual) - } - - /** - * An interface that defines how to map each variant of [LearningRateMultiplier] - * to a value of type [T]. - */ - interface Visitor { - - fun visitAuto(auto: JsonValue): T - - fun visitManual(manual: Double): T - - /** - * Maps an unknown variant of [LearningRateMultiplier] to a value of type - * [T]. - * - * An instance of [LearningRateMultiplier] can contain an unknown variant if - * it was deserialized from data that doesn't match any known variant. For - * example, if the SDK is on an older version than the API, then the API may - * respond with new variants that the SDK is unaware of. - * - * @throws OpenAIInvalidDataException in the default implementation. - */ - fun unknown(json: JsonValue?): T { - throw OpenAIInvalidDataException( - "Unknown LearningRateMultiplier: $json" - ) - } - } - - internal class Deserializer : - BaseDeserializer(LearningRateMultiplier::class) { - - override fun ObjectCodec.deserialize( - node: JsonNode - ): LearningRateMultiplier { - val json = JsonValue.fromJsonNode(node) - - val bestMatches = - sequenceOf( - tryDeserialize(node, jacksonTypeRef()) - ?.let { - LearningRateMultiplier(auto = it, _json = json) - } - ?.takeIf { it.isValid() }, - tryDeserialize(node, jacksonTypeRef())?.let { - LearningRateMultiplier(manual = it, _json = json) - }, - ) - .filterNotNull() - .allMaxBy { it.validity() } - .toList() - return when (bestMatches.size) { - // This can happen if what we're deserializing is completely - // incompatible with all the possible variants (e.g. deserializing - // from object). - 0 -> LearningRateMultiplier(_json = json) - 1 -> bestMatches.single() - // If there's more than one match with the highest validity, then - // use the first completely valid match, or simply the first match - // if none are completely valid. - else -> - bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() - } - } - } - - internal class Serializer : - BaseSerializer(LearningRateMultiplier::class) { - - override fun serialize( - value: LearningRateMultiplier, - generator: JsonGenerator, - provider: SerializerProvider, - ) { - when { - value.auto != null -> generator.writeObject(value.auto) - value.manual != null -> generator.writeObject(value.manual) - value._json != null -> generator.writeObject(value._json) - else -> - throw IllegalStateException("Invalid LearningRateMultiplier") - } - } - } - } - - /** - * The number of epochs to train the model for. An epoch refers to one full cycle - * through the training dataset. - */ - @JsonDeserialize(using = NEpochs.Deserializer::class) - @JsonSerialize(using = NEpochs.Serializer::class) - class NEpochs - private constructor( - private val auto: JsonValue? = null, - private val manual: Long? = null, - private val _json: JsonValue? = null, - ) { - - fun auto(): Optional = Optional.ofNullable(auto) - - fun manual(): Optional = Optional.ofNullable(manual) - - fun isAuto(): Boolean = auto != null - - fun isManual(): Boolean = manual != null - - fun asAuto(): JsonValue = auto.getOrThrow("auto") - - fun asManual(): Long = manual.getOrThrow("manual") - - fun _json(): Optional = Optional.ofNullable(_json) - - fun accept(visitor: Visitor): T = - when { - auto != null -> visitor.visitAuto(auto) - manual != null -> visitor.visitManual(manual) - else -> visitor.unknown(_json) - } - - private var validated: Boolean = false - - fun validate(): NEpochs = apply { - if (validated) { - return@apply - } - - accept( - object : Visitor { - override fun visitAuto(auto: JsonValue) { - auto.let { - if (it != JsonValue.from("auto")) { - throw OpenAIInvalidDataException( - "'auto' is invalid, received $it" - ) - } - } - } - - override fun visitManual(manual: Long) {} - } - ) - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - accept( - object : Visitor { - override fun visitAuto(auto: JsonValue) = - auto.let { if (it == JsonValue.from("auto")) 1 else 0 } - - override fun visitManual(manual: Long) = 1 - - override fun unknown(json: JsonValue?) = 0 - } - ) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is NEpochs && auto == other.auto && manual == other.manual /* spotless:on */ - } - - override fun hashCode(): Int = /* spotless:off */ Objects.hash(auto, manual) /* spotless:on */ - - override fun toString(): String = - when { - auto != null -> "NEpochs{auto=$auto}" - manual != null -> "NEpochs{manual=$manual}" - _json != null -> "NEpochs{_unknown=$_json}" - else -> throw IllegalStateException("Invalid NEpochs") - } - - companion object { - - @JvmStatic fun ofAuto() = NEpochs(auto = JsonValue.from("auto")) - - @JvmStatic fun ofManual(manual: Long) = NEpochs(manual = manual) - } - - /** - * An interface that defines how to map each variant of [NEpochs] to a value of - * type [T]. - */ - interface Visitor { - - fun visitAuto(auto: JsonValue): T - - fun visitManual(manual: Long): T - - /** - * Maps an unknown variant of [NEpochs] to a value of type [T]. - * - * An instance of [NEpochs] can contain an unknown variant if it was - * deserialized from data that doesn't match any known variant. For example, - * if the SDK is on an older version than the API, then the API may respond - * with new variants that the SDK is unaware of. - * - * @throws OpenAIInvalidDataException in the default implementation. - */ - fun unknown(json: JsonValue?): T { - throw OpenAIInvalidDataException("Unknown NEpochs: $json") - } - } - - internal class Deserializer : BaseDeserializer(NEpochs::class) { - - override fun ObjectCodec.deserialize(node: JsonNode): NEpochs { - val json = JsonValue.fromJsonNode(node) - - val bestMatches = - sequenceOf( - tryDeserialize(node, jacksonTypeRef()) - ?.let { NEpochs(auto = it, _json = json) } - ?.takeIf { it.isValid() }, - tryDeserialize(node, jacksonTypeRef())?.let { - NEpochs(manual = it, _json = json) - }, - ) - .filterNotNull() - .allMaxBy { it.validity() } - .toList() - return when (bestMatches.size) { - // This can happen if what we're deserializing is completely - // incompatible with all the possible variants (e.g. deserializing - // from object). - 0 -> NEpochs(_json = json) - 1 -> bestMatches.single() - // If there's more than one match with the highest validity, then - // use the first completely valid match, or simply the first match - // if none are completely valid. - else -> - bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() - } - } - } - - internal class Serializer : BaseSerializer(NEpochs::class) { - - override fun serialize( - value: NEpochs, - generator: JsonGenerator, - provider: SerializerProvider, - ) { - when { - value.auto != null -> generator.writeObject(value.auto) - value.manual != null -> generator.writeObject(value.manual) - value._json != null -> generator.writeObject(value._json) - else -> throw IllegalStateException("Invalid NEpochs") - } - } - } - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is Hyperparameters && batchSize == other.batchSize && beta == other.beta && learningRateMultiplier == other.learningRateMultiplier && nEpochs == other.nEpochs && additionalProperties == other.additionalProperties /* spotless:on */ - } - - /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(batchSize, beta, learningRateMultiplier, nEpochs, additionalProperties) } - /* spotless:on */ - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Hyperparameters{batchSize=$batchSize, beta=$beta, learningRateMultiplier=$learningRateMultiplier, nEpochs=$nEpochs, additionalProperties=$additionalProperties}" - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is Dpo && hyperparameters == other.hyperparameters && additionalProperties == other.additionalProperties /* spotless:on */ - } - - /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(hyperparameters, additionalProperties) } - /* spotless:on */ - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Dpo{hyperparameters=$hyperparameters, additionalProperties=$additionalProperties}" - } - - /** Configuration for the supervised fine-tuning method. */ - class Supervised - private constructor( - private val hyperparameters: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("hyperparameters") - @ExcludeMissing - hyperparameters: JsonField = JsonMissing.of() - ) : this(hyperparameters, mutableMapOf()) - - /** - * The hyperparameters used for the fine-tuning job. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun hyperparameters(): Optional = - hyperparameters.getOptional("hyperparameters") - - /** - * Returns the raw JSON value of [hyperparameters]. - * - * Unlike [hyperparameters], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("hyperparameters") - @ExcludeMissing - fun _hyperparameters(): JsonField = hyperparameters - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** Returns a mutable builder for constructing an instance of [Supervised]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Supervised]. */ - class Builder internal constructor() { - - private var hyperparameters: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(supervised: Supervised) = apply { - hyperparameters = supervised.hyperparameters - additionalProperties = supervised.additionalProperties.toMutableMap() - } - - /** The hyperparameters used for the fine-tuning job. */ - fun hyperparameters(hyperparameters: Hyperparameters) = - hyperparameters(JsonField.of(hyperparameters)) - - /** - * Sets [Builder.hyperparameters] to an arbitrary JSON value. - * - * You should usually call [Builder.hyperparameters] with a well-typed - * [Hyperparameters] value instead. This method is primarily for setting the field - * to an undocumented or not yet supported value. - */ - fun hyperparameters(hyperparameters: JsonField) = apply { - this.hyperparameters = hyperparameters - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [Supervised]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Supervised = - Supervised(hyperparameters, additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false - - fun validate(): Supervised = apply { - if (validated) { - return@apply - } - - hyperparameters().ifPresent { it.validate() } - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = (hyperparameters.asKnown().getOrNull()?.validity() ?: 0) - - /** The hyperparameters used for the fine-tuning job. */ - class Hyperparameters - private constructor( - private val batchSize: JsonField, - private val learningRateMultiplier: JsonField, - private val nEpochs: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("batch_size") - @ExcludeMissing - batchSize: JsonField = JsonMissing.of(), - @JsonProperty("learning_rate_multiplier") - @ExcludeMissing - learningRateMultiplier: JsonField = JsonMissing.of(), - @JsonProperty("n_epochs") - @ExcludeMissing - nEpochs: JsonField = JsonMissing.of(), - ) : this(batchSize, learningRateMultiplier, nEpochs, mutableMapOf()) - - /** - * Number of examples in each batch. A larger batch size means that model parameters - * are updated less frequently, but with lower variance. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun batchSize(): Optional = batchSize.getOptional("batch_size") - - /** - * Scaling factor for the learning rate. A smaller learning rate may be useful to - * avoid overfitting. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun learningRateMultiplier(): Optional = - learningRateMultiplier.getOptional("learning_rate_multiplier") - - /** - * The number of epochs to train the model for. An epoch refers to one full cycle - * through the training dataset. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun nEpochs(): Optional = nEpochs.getOptional("n_epochs") - - /** - * Returns the raw JSON value of [batchSize]. - * - * Unlike [batchSize], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("batch_size") - @ExcludeMissing - fun _batchSize(): JsonField = batchSize - - /** - * Returns the raw JSON value of [learningRateMultiplier]. - * - * Unlike [learningRateMultiplier], this method doesn't throw if the JSON field has - * an unexpected type. - */ - @JsonProperty("learning_rate_multiplier") - @ExcludeMissing - fun _learningRateMultiplier(): JsonField = - learningRateMultiplier - - /** - * Returns the raw JSON value of [nEpochs]. - * - * Unlike [nEpochs], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("n_epochs") - @ExcludeMissing - fun _nEpochs(): JsonField = nEpochs - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** - * Returns a mutable builder for constructing an instance of [Hyperparameters]. - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Hyperparameters]. */ - class Builder internal constructor() { - - private var batchSize: JsonField = JsonMissing.of() - private var learningRateMultiplier: JsonField = - JsonMissing.of() - private var nEpochs: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(hyperparameters: Hyperparameters) = apply { - batchSize = hyperparameters.batchSize - learningRateMultiplier = hyperparameters.learningRateMultiplier - nEpochs = hyperparameters.nEpochs - additionalProperties = hyperparameters.additionalProperties.toMutableMap() - } - - /** - * Number of examples in each batch. A larger batch size means that model - * parameters are updated less frequently, but with lower variance. - */ - fun batchSize(batchSize: BatchSize) = batchSize(JsonField.of(batchSize)) - - /** - * Sets [Builder.batchSize] to an arbitrary JSON value. - * - * You should usually call [Builder.batchSize] with a well-typed [BatchSize] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun batchSize(batchSize: JsonField) = apply { - this.batchSize = batchSize - } - - /** Alias for calling [batchSize] with `BatchSize.ofAuto()`. */ - fun batchSizeAuto() = batchSize(BatchSize.ofAuto()) - - /** Alias for calling [batchSize] with `BatchSize.ofManual(manual)`. */ - fun batchSize(manual: Long) = batchSize(BatchSize.ofManual(manual)) - - /** - * Scaling factor for the learning rate. A smaller learning rate may be useful - * to avoid overfitting. - */ - fun learningRateMultiplier(learningRateMultiplier: LearningRateMultiplier) = - learningRateMultiplier(JsonField.of(learningRateMultiplier)) - - /** - * Sets [Builder.learningRateMultiplier] to an arbitrary JSON value. - * - * You should usually call [Builder.learningRateMultiplier] with a well-typed - * [LearningRateMultiplier] value instead. This method is primarily for setting - * the field to an undocumented or not yet supported value. - */ - fun learningRateMultiplier( - learningRateMultiplier: JsonField - ) = apply { this.learningRateMultiplier = learningRateMultiplier } - - /** - * Alias for calling [learningRateMultiplier] with - * `LearningRateMultiplier.ofAuto()`. - */ - fun learningRateMultiplierAuto() = - learningRateMultiplier(LearningRateMultiplier.ofAuto()) - - /** - * Alias for calling [learningRateMultiplier] with - * `LearningRateMultiplier.ofManual(manual)`. - */ - fun learningRateMultiplier(manual: Double) = - learningRateMultiplier(LearningRateMultiplier.ofManual(manual)) - - /** - * The number of epochs to train the model for. An epoch refers to one full - * cycle through the training dataset. - */ - fun nEpochs(nEpochs: NEpochs) = nEpochs(JsonField.of(nEpochs)) - - /** - * Sets [Builder.nEpochs] to an arbitrary JSON value. - * - * You should usually call [Builder.nEpochs] with a well-typed [NEpochs] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun nEpochs(nEpochs: JsonField) = apply { this.nEpochs = nEpochs } - - /** Alias for calling [nEpochs] with `NEpochs.ofAuto()`. */ - fun nEpochsAuto() = nEpochs(NEpochs.ofAuto()) - - /** Alias for calling [nEpochs] with `NEpochs.ofManual(manual)`. */ - fun nEpochs(manual: Long) = nEpochs(NEpochs.ofManual(manual)) - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [Hyperparameters]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Hyperparameters = - Hyperparameters( - batchSize, - learningRateMultiplier, - nEpochs, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): Hyperparameters = apply { - if (validated) { - return@apply - } - - batchSize().ifPresent { it.validate() } - learningRateMultiplier().ifPresent { it.validate() } - nEpochs().ifPresent { it.validate() } - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (batchSize.asKnown().getOrNull()?.validity() ?: 0) + - (learningRateMultiplier.asKnown().getOrNull()?.validity() ?: 0) + - (nEpochs.asKnown().getOrNull()?.validity() ?: 0) - - /** - * Number of examples in each batch. A larger batch size means that model parameters - * are updated less frequently, but with lower variance. - */ - @JsonDeserialize(using = BatchSize.Deserializer::class) - @JsonSerialize(using = BatchSize.Serializer::class) - class BatchSize - private constructor( - private val auto: JsonValue? = null, - private val manual: Long? = null, - private val _json: JsonValue? = null, - ) { - - fun auto(): Optional = Optional.ofNullable(auto) - - fun manual(): Optional = Optional.ofNullable(manual) - - fun isAuto(): Boolean = auto != null - - fun isManual(): Boolean = manual != null - - fun asAuto(): JsonValue = auto.getOrThrow("auto") - - fun asManual(): Long = manual.getOrThrow("manual") - - fun _json(): Optional = Optional.ofNullable(_json) - - fun accept(visitor: Visitor): T = - when { - auto != null -> visitor.visitAuto(auto) - manual != null -> visitor.visitManual(manual) - else -> visitor.unknown(_json) - } - - private var validated: Boolean = false - - fun validate(): BatchSize = apply { - if (validated) { - return@apply - } - - accept( - object : Visitor { - override fun visitAuto(auto: JsonValue) { - auto.let { - if (it != JsonValue.from("auto")) { - throw OpenAIInvalidDataException( - "'auto' is invalid, received $it" - ) - } - } - } - - override fun visitManual(manual: Long) {} - } - ) - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - accept( - object : Visitor { - override fun visitAuto(auto: JsonValue) = - auto.let { if (it == JsonValue.from("auto")) 1 else 0 } - - override fun visitManual(manual: Long) = 1 - - override fun unknown(json: JsonValue?) = 0 - } - ) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is BatchSize && auto == other.auto && manual == other.manual /* spotless:on */ - } - - override fun hashCode(): Int = /* spotless:off */ Objects.hash(auto, manual) /* spotless:on */ - - override fun toString(): String = - when { - auto != null -> "BatchSize{auto=$auto}" - manual != null -> "BatchSize{manual=$manual}" - _json != null -> "BatchSize{_unknown=$_json}" - else -> throw IllegalStateException("Invalid BatchSize") - } - - companion object { - - @JvmStatic fun ofAuto() = BatchSize(auto = JsonValue.from("auto")) - - @JvmStatic fun ofManual(manual: Long) = BatchSize(manual = manual) - } - - /** - * An interface that defines how to map each variant of [BatchSize] to a value - * of type [T]. - */ - interface Visitor { - - fun visitAuto(auto: JsonValue): T - - fun visitManual(manual: Long): T - - /** - * Maps an unknown variant of [BatchSize] to a value of type [T]. - * - * An instance of [BatchSize] can contain an unknown variant if it was - * deserialized from data that doesn't match any known variant. For example, - * if the SDK is on an older version than the API, then the API may respond - * with new variants that the SDK is unaware of. - * - * @throws OpenAIInvalidDataException in the default implementation. - */ - fun unknown(json: JsonValue?): T { - throw OpenAIInvalidDataException("Unknown BatchSize: $json") - } - } - - internal class Deserializer : BaseDeserializer(BatchSize::class) { - - override fun ObjectCodec.deserialize(node: JsonNode): BatchSize { - val json = JsonValue.fromJsonNode(node) - - val bestMatches = - sequenceOf( - tryDeserialize(node, jacksonTypeRef()) - ?.let { BatchSize(auto = it, _json = json) } - ?.takeIf { it.isValid() }, - tryDeserialize(node, jacksonTypeRef())?.let { - BatchSize(manual = it, _json = json) - }, - ) - .filterNotNull() - .allMaxBy { it.validity() } - .toList() - return when (bestMatches.size) { - // This can happen if what we're deserializing is completely - // incompatible with all the possible variants (e.g. deserializing - // from object). - 0 -> BatchSize(_json = json) - 1 -> bestMatches.single() - // If there's more than one match with the highest validity, then - // use the first completely valid match, or simply the first match - // if none are completely valid. - else -> - bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() - } - } - } - - internal class Serializer : BaseSerializer(BatchSize::class) { - - override fun serialize( - value: BatchSize, - generator: JsonGenerator, - provider: SerializerProvider, - ) { - when { - value.auto != null -> generator.writeObject(value.auto) - value.manual != null -> generator.writeObject(value.manual) - value._json != null -> generator.writeObject(value._json) - else -> throw IllegalStateException("Invalid BatchSize") - } - } - } - } - - /** - * Scaling factor for the learning rate. A smaller learning rate may be useful to - * avoid overfitting. - */ - @JsonDeserialize(using = LearningRateMultiplier.Deserializer::class) - @JsonSerialize(using = LearningRateMultiplier.Serializer::class) - class LearningRateMultiplier - private constructor( - private val auto: JsonValue? = null, - private val manual: Double? = null, - private val _json: JsonValue? = null, - ) { - - fun auto(): Optional = Optional.ofNullable(auto) - - fun manual(): Optional = Optional.ofNullable(manual) - - fun isAuto(): Boolean = auto != null - - fun isManual(): Boolean = manual != null - - fun asAuto(): JsonValue = auto.getOrThrow("auto") - - fun asManual(): Double = manual.getOrThrow("manual") - - fun _json(): Optional = Optional.ofNullable(_json) - - fun accept(visitor: Visitor): T = - when { - auto != null -> visitor.visitAuto(auto) - manual != null -> visitor.visitManual(manual) - else -> visitor.unknown(_json) - } - - private var validated: Boolean = false - - fun validate(): LearningRateMultiplier = apply { - if (validated) { - return@apply - } - - accept( - object : Visitor { - override fun visitAuto(auto: JsonValue) { - auto.let { - if (it != JsonValue.from("auto")) { - throw OpenAIInvalidDataException( - "'auto' is invalid, received $it" - ) - } - } - } - - override fun visitManual(manual: Double) {} - } - ) - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - accept( - object : Visitor { - override fun visitAuto(auto: JsonValue) = - auto.let { if (it == JsonValue.from("auto")) 1 else 0 } - - override fun visitManual(manual: Double) = 1 - - override fun unknown(json: JsonValue?) = 0 - } - ) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is LearningRateMultiplier && auto == other.auto && manual == other.manual /* spotless:on */ - } - - override fun hashCode(): Int = /* spotless:off */ Objects.hash(auto, manual) /* spotless:on */ - - override fun toString(): String = - when { - auto != null -> "LearningRateMultiplier{auto=$auto}" - manual != null -> "LearningRateMultiplier{manual=$manual}" - _json != null -> "LearningRateMultiplier{_unknown=$_json}" - else -> throw IllegalStateException("Invalid LearningRateMultiplier") - } - - companion object { - - @JvmStatic - fun ofAuto() = LearningRateMultiplier(auto = JsonValue.from("auto")) - - @JvmStatic - fun ofManual(manual: Double) = LearningRateMultiplier(manual = manual) - } - - /** - * An interface that defines how to map each variant of [LearningRateMultiplier] - * to a value of type [T]. - */ - interface Visitor { - - fun visitAuto(auto: JsonValue): T - - fun visitManual(manual: Double): T - - /** - * Maps an unknown variant of [LearningRateMultiplier] to a value of type - * [T]. - * - * An instance of [LearningRateMultiplier] can contain an unknown variant if - * it was deserialized from data that doesn't match any known variant. For - * example, if the SDK is on an older version than the API, then the API may - * respond with new variants that the SDK is unaware of. - * - * @throws OpenAIInvalidDataException in the default implementation. - */ - fun unknown(json: JsonValue?): T { - throw OpenAIInvalidDataException( - "Unknown LearningRateMultiplier: $json" - ) - } - } - - internal class Deserializer : - BaseDeserializer(LearningRateMultiplier::class) { - - override fun ObjectCodec.deserialize( - node: JsonNode - ): LearningRateMultiplier { - val json = JsonValue.fromJsonNode(node) - - val bestMatches = - sequenceOf( - tryDeserialize(node, jacksonTypeRef()) - ?.let { - LearningRateMultiplier(auto = it, _json = json) - } - ?.takeIf { it.isValid() }, - tryDeserialize(node, jacksonTypeRef())?.let { - LearningRateMultiplier(manual = it, _json = json) - }, - ) - .filterNotNull() - .allMaxBy { it.validity() } - .toList() - return when (bestMatches.size) { - // This can happen if what we're deserializing is completely - // incompatible with all the possible variants (e.g. deserializing - // from object). - 0 -> LearningRateMultiplier(_json = json) - 1 -> bestMatches.single() - // If there's more than one match with the highest validity, then - // use the first completely valid match, or simply the first match - // if none are completely valid. - else -> - bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() - } - } - } - - internal class Serializer : - BaseSerializer(LearningRateMultiplier::class) { - - override fun serialize( - value: LearningRateMultiplier, - generator: JsonGenerator, - provider: SerializerProvider, - ) { - when { - value.auto != null -> generator.writeObject(value.auto) - value.manual != null -> generator.writeObject(value.manual) - value._json != null -> generator.writeObject(value._json) - else -> - throw IllegalStateException("Invalid LearningRateMultiplier") - } - } - } - } - - /** - * The number of epochs to train the model for. An epoch refers to one full cycle - * through the training dataset. - */ - @JsonDeserialize(using = NEpochs.Deserializer::class) - @JsonSerialize(using = NEpochs.Serializer::class) - class NEpochs - private constructor( - private val auto: JsonValue? = null, - private val manual: Long? = null, - private val _json: JsonValue? = null, - ) { - - fun auto(): Optional = Optional.ofNullable(auto) - - fun manual(): Optional = Optional.ofNullable(manual) - - fun isAuto(): Boolean = auto != null - - fun isManual(): Boolean = manual != null - - fun asAuto(): JsonValue = auto.getOrThrow("auto") - - fun asManual(): Long = manual.getOrThrow("manual") - - fun _json(): Optional = Optional.ofNullable(_json) - - fun accept(visitor: Visitor): T = - when { - auto != null -> visitor.visitAuto(auto) - manual != null -> visitor.visitManual(manual) - else -> visitor.unknown(_json) - } - - private var validated: Boolean = false - - fun validate(): NEpochs = apply { - if (validated) { - return@apply - } - - accept( - object : Visitor { - override fun visitAuto(auto: JsonValue) { - auto.let { - if (it != JsonValue.from("auto")) { - throw OpenAIInvalidDataException( - "'auto' is invalid, received $it" - ) - } - } - } - - override fun visitManual(manual: Long) {} - } - ) - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - accept( - object : Visitor { - override fun visitAuto(auto: JsonValue) = - auto.let { if (it == JsonValue.from("auto")) 1 else 0 } - - override fun visitManual(manual: Long) = 1 - - override fun unknown(json: JsonValue?) = 0 - } - ) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is NEpochs && auto == other.auto && manual == other.manual /* spotless:on */ - } - - override fun hashCode(): Int = /* spotless:off */ Objects.hash(auto, manual) /* spotless:on */ - - override fun toString(): String = - when { - auto != null -> "NEpochs{auto=$auto}" - manual != null -> "NEpochs{manual=$manual}" - _json != null -> "NEpochs{_unknown=$_json}" - else -> throw IllegalStateException("Invalid NEpochs") - } - - companion object { - - @JvmStatic fun ofAuto() = NEpochs(auto = JsonValue.from("auto")) - - @JvmStatic fun ofManual(manual: Long) = NEpochs(manual = manual) - } - - /** - * An interface that defines how to map each variant of [NEpochs] to a value of - * type [T]. - */ - interface Visitor { - - fun visitAuto(auto: JsonValue): T - - fun visitManual(manual: Long): T - - /** - * Maps an unknown variant of [NEpochs] to a value of type [T]. - * - * An instance of [NEpochs] can contain an unknown variant if it was - * deserialized from data that doesn't match any known variant. For example, - * if the SDK is on an older version than the API, then the API may respond - * with new variants that the SDK is unaware of. - * - * @throws OpenAIInvalidDataException in the default implementation. - */ - fun unknown(json: JsonValue?): T { - throw OpenAIInvalidDataException("Unknown NEpochs: $json") - } - } - - internal class Deserializer : BaseDeserializer(NEpochs::class) { - - override fun ObjectCodec.deserialize(node: JsonNode): NEpochs { - val json = JsonValue.fromJsonNode(node) - - val bestMatches = - sequenceOf( - tryDeserialize(node, jacksonTypeRef()) - ?.let { NEpochs(auto = it, _json = json) } - ?.takeIf { it.isValid() }, - tryDeserialize(node, jacksonTypeRef())?.let { - NEpochs(manual = it, _json = json) - }, - ) - .filterNotNull() - .allMaxBy { it.validity() } - .toList() - return when (bestMatches.size) { - // This can happen if what we're deserializing is completely - // incompatible with all the possible variants (e.g. deserializing - // from object). - 0 -> NEpochs(_json = json) - 1 -> bestMatches.single() - // If there's more than one match with the highest validity, then - // use the first completely valid match, or simply the first match - // if none are completely valid. - else -> - bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() - } - } - } - - internal class Serializer : BaseSerializer(NEpochs::class) { - - override fun serialize( - value: NEpochs, - generator: JsonGenerator, - provider: SerializerProvider, - ) { - when { - value.auto != null -> generator.writeObject(value.auto) - value.manual != null -> generator.writeObject(value.manual) - value._json != null -> generator.writeObject(value._json) - else -> throw IllegalStateException("Invalid NEpochs") - } - } - } - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is Hyperparameters && batchSize == other.batchSize && learningRateMultiplier == other.learningRateMultiplier && nEpochs == other.nEpochs && additionalProperties == other.additionalProperties /* spotless:on */ - } - - /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(batchSize, learningRateMultiplier, nEpochs, additionalProperties) } - /* spotless:on */ - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Hyperparameters{batchSize=$batchSize, learningRateMultiplier=$learningRateMultiplier, nEpochs=$nEpochs, additionalProperties=$additionalProperties}" - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is Supervised && hyperparameters == other.hyperparameters && additionalProperties == other.additionalProperties /* spotless:on */ - } - - /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(hyperparameters, additionalProperties) } - /* spotless:on */ - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Supervised{hyperparameters=$hyperparameters, additionalProperties=$additionalProperties}" - } - - /** The type of method. Is either `supervised` or `dpo`. */ - class Type @JsonCreator private constructor(private val value: JsonField) : Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that doesn't - * match any known member, and you want to know that value. For example, if the SDK is - * on an older version than the API, then the API may respond with new members that the - * SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val SUPERVISED = of("supervised") - - @JvmField val DPO = of("dpo") + @JvmField val REINFORCEMENT = of("reinforcement") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } @@ -4812,6 +2645,7 @@ private constructor( enum class Known { SUPERVISED, DPO, + REINFORCEMENT, } /** @@ -4826,6 +2660,7 @@ private constructor( enum class Value { SUPERVISED, DPO, + REINFORCEMENT, /** An enum member indicating that [Type] was instantiated with an unknown value. */ _UNKNOWN, } @@ -4841,6 +2676,7 @@ private constructor( when (this) { SUPERVISED -> Value.SUPERVISED DPO -> Value.DPO + REINFORCEMENT -> Value.REINFORCEMENT else -> Value._UNKNOWN } @@ -4857,6 +2693,7 @@ private constructor( when (this) { SUPERVISED -> Known.SUPERVISED DPO -> Known.DPO + REINFORCEMENT -> Known.REINFORCEMENT else -> throw OpenAIInvalidDataException("Unknown Type: $value") } @@ -4919,17 +2756,17 @@ private constructor( return true } - return /* spotless:off */ other is Method && dpo == other.dpo && supervised == other.supervised && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ + return /* spotless:off */ other is Method && type == other.type && dpo == other.dpo && reinforcement == other.reinforcement && supervised == other.supervised && additionalProperties == other.additionalProperties /* spotless:on */ } /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(dpo, supervised, type, additionalProperties) } + private val hashCode: Int by lazy { Objects.hash(type, dpo, reinforcement, supervised, additionalProperties) } /* spotless:on */ override fun hashCode(): Int = hashCode override fun toString() = - "Method{dpo=$dpo, supervised=$supervised, type=$type, additionalProperties=$additionalProperties}" + "Method{type=$type, dpo=$dpo, reinforcement=$reinforcement, supervised=$supervised, additionalProperties=$additionalProperties}" } override fun equals(other: Any?): Boolean { diff --git a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobCancelParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobCancelParams.kt index 4d7c9f96..a4fbd422 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobCancelParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobCancelParams.kt @@ -4,23 +4,23 @@ package com.openai.models.finetuning.jobs import com.openai.core.JsonValue import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import com.openai.core.toImmutable import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** Immediately cancel a fine-tune job. */ class JobCancelParams private constructor( - private val fineTuningJobId: String, + private val fineTuningJobId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, ) : Params { - fun fineTuningJobId(): String = fineTuningJobId + fun fineTuningJobId(): Optional = Optional.ofNullable(fineTuningJobId) fun _additionalBodyProperties(): Map = additionalBodyProperties @@ -32,14 +32,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [JobCancelParams]. - * - * The following fields are required: - * ```java - * .fineTuningJobId() - * ``` - */ + @JvmStatic fun none(): JobCancelParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [JobCancelParams]. */ @JvmStatic fun builder() = Builder() } @@ -59,10 +54,14 @@ private constructor( additionalBodyProperties = jobCancelParams.additionalBodyProperties.toMutableMap() } - fun fineTuningJobId(fineTuningJobId: String) = apply { + fun fineTuningJobId(fineTuningJobId: String?) = apply { this.fineTuningJobId = fineTuningJobId } + /** Alias for calling [Builder.fineTuningJobId] with `fineTuningJobId.orElse(null)`. */ + fun fineTuningJobId(fineTuningJobId: Optional) = + fineTuningJobId(fineTuningJobId.getOrNull()) + fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() putAllAdditionalHeaders(additionalHeaders) @@ -187,17 +186,10 @@ private constructor( * Returns an immutable instance of [JobCancelParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .fineTuningJobId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): JobCancelParams = JobCancelParams( - checkRequired("fineTuningJobId", fineTuningJobId), + fineTuningJobId, additionalHeaders.build(), additionalQueryParams.build(), additionalBodyProperties.toImmutable(), @@ -209,7 +201,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> fineTuningJobId + 0 -> fineTuningJobId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobCreateParams.kt index 345624c2..f08fe5de 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobCreateParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobCreateParams.kt @@ -29,6 +29,9 @@ import com.openai.core.http.Headers import com.openai.core.http.QueryParams import com.openai.core.toImmutable import com.openai.errors.OpenAIInvalidDataException +import com.openai.models.finetuning.methods.DpoMethod +import com.openai.models.finetuning.methods.ReinforcementMethod +import com.openai.models.finetuning.methods.SupervisedMethod import java.util.Collections import java.util.Objects import java.util.Optional @@ -2835,20 +2838,32 @@ private constructor( /** The method used for fine-tuning. */ class Method private constructor( - private val dpo: JsonField, - private val supervised: JsonField, private val type: JsonField, + private val dpo: JsonField, + private val reinforcement: JsonField, + private val supervised: JsonField, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( - @JsonProperty("dpo") @ExcludeMissing dpo: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + @JsonProperty("dpo") @ExcludeMissing dpo: JsonField = JsonMissing.of(), + @JsonProperty("reinforcement") + @ExcludeMissing + reinforcement: JsonField = JsonMissing.of(), @JsonProperty("supervised") @ExcludeMissing - supervised: JsonField = JsonMissing.of(), - @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), - ) : this(dpo, supervised, type, mutableMapOf()) + supervised: JsonField = JsonMissing.of(), + ) : this(type, dpo, reinforcement, supervised, mutableMapOf()) + + /** + * The type of method. Is either `supervised`, `dpo`, or `reinforcement`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun type(): Type = type.getRequired("type") /** * Configuration for the DPO fine-tuning method. @@ -2856,46 +2871,57 @@ private constructor( * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). */ - fun dpo(): Optional = dpo.getOptional("dpo") + fun dpo(): Optional = dpo.getOptional("dpo") /** - * Configuration for the supervised fine-tuning method. + * Configuration for the reinforcement fine-tuning method. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). */ - fun supervised(): Optional = supervised.getOptional("supervised") + fun reinforcement(): Optional = + reinforcement.getOptional("reinforcement") /** - * The type of method. Is either `supervised` or `dpo`. + * Configuration for the supervised fine-tuning method. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). */ - fun type(): Optional = type.getOptional("type") + fun supervised(): Optional = supervised.getOptional("supervised") + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type /** * Returns the raw JSON value of [dpo]. * * Unlike [dpo], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("dpo") @ExcludeMissing fun _dpo(): JsonField = dpo + @JsonProperty("dpo") @ExcludeMissing fun _dpo(): JsonField = dpo /** - * Returns the raw JSON value of [supervised]. + * Returns the raw JSON value of [reinforcement]. * - * Unlike [supervised], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [reinforcement], this method doesn't throw if the JSON field has an unexpected + * type. */ - @JsonProperty("supervised") + @JsonProperty("reinforcement") @ExcludeMissing - fun _supervised(): JsonField = supervised + fun _reinforcement(): JsonField = reinforcement /** - * Returns the raw JSON value of [type]. + * Returns the raw JSON value of [supervised]. * - * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [supervised], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + @JsonProperty("supervised") + @ExcludeMissing + fun _supervised(): JsonField = supervised @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { @@ -2911,63 +2937,87 @@ private constructor( companion object { - /** Returns a mutable builder for constructing an instance of [Method]. */ + /** + * Returns a mutable builder for constructing an instance of [Method]. + * + * The following fields are required: + * ```java + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } /** A builder for [Method]. */ class Builder internal constructor() { - private var dpo: JsonField = JsonMissing.of() - private var supervised: JsonField = JsonMissing.of() - private var type: JsonField = JsonMissing.of() + private var type: JsonField? = null + private var dpo: JsonField = JsonMissing.of() + private var reinforcement: JsonField = JsonMissing.of() + private var supervised: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(method: Method) = apply { + type = method.type dpo = method.dpo + reinforcement = method.reinforcement supervised = method.supervised - type = method.type additionalProperties = method.additionalProperties.toMutableMap() } - /** Configuration for the DPO fine-tuning method. */ - fun dpo(dpo: Dpo) = dpo(JsonField.of(dpo)) + /** The type of method. Is either `supervised`, `dpo`, or `reinforcement`. */ + fun type(type: Type) = type(JsonField.of(type)) /** - * Sets [Builder.dpo] to an arbitrary JSON value. + * Sets [Builder.type] to an arbitrary JSON value. * - * You should usually call [Builder.dpo] with a well-typed [Dpo] value instead. This + * You should usually call [Builder.type] with a well-typed [Type] value instead. This * method is primarily for setting the field to an undocumented or not yet supported * value. */ - fun dpo(dpo: JsonField) = apply { this.dpo = dpo } + fun type(type: JsonField) = apply { this.type = type } - /** Configuration for the supervised fine-tuning method. */ - fun supervised(supervised: Supervised) = supervised(JsonField.of(supervised)) + /** Configuration for the DPO fine-tuning method. */ + fun dpo(dpo: DpoMethod) = dpo(JsonField.of(dpo)) /** - * Sets [Builder.supervised] to an arbitrary JSON value. + * Sets [Builder.dpo] to an arbitrary JSON value. * - * You should usually call [Builder.supervised] with a well-typed [Supervised] value - * instead. This method is primarily for setting the field to an undocumented or not yet + * You should usually call [Builder.dpo] with a well-typed [DpoMethod] value instead. + * This method is primarily for setting the field to an undocumented or not yet * supported value. */ - fun supervised(supervised: JsonField) = apply { - this.supervised = supervised + fun dpo(dpo: JsonField) = apply { this.dpo = dpo } + + /** Configuration for the reinforcement fine-tuning method. */ + fun reinforcement(reinforcement: ReinforcementMethod) = + reinforcement(JsonField.of(reinforcement)) + + /** + * Sets [Builder.reinforcement] to an arbitrary JSON value. + * + * You should usually call [Builder.reinforcement] with a well-typed + * [ReinforcementMethod] value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ + fun reinforcement(reinforcement: JsonField) = apply { + this.reinforcement = reinforcement } - /** The type of method. Is either `supervised` or `dpo`. */ - fun type(type: Type) = type(JsonField.of(type)) + /** Configuration for the supervised fine-tuning method. */ + fun supervised(supervised: SupervisedMethod) = supervised(JsonField.of(supervised)) /** - * Sets [Builder.type] to an arbitrary JSON value. + * Sets [Builder.supervised] to an arbitrary JSON value. * - * You should usually call [Builder.type] with a well-typed [Type] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported - * value. + * You should usually call [Builder.supervised] with a well-typed [SupervisedMethod] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. */ - fun type(type: JsonField) = apply { this.type = type } + fun supervised(supervised: JsonField) = apply { + this.supervised = supervised + } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() @@ -2992,8 +3042,22 @@ private constructor( * Returns an immutable instance of [Method]. * * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. */ - fun build(): Method = Method(dpo, supervised, type, additionalProperties.toMutableMap()) + fun build(): Method = + Method( + checkRequired("type", type), + dpo, + reinforcement, + supervised, + additionalProperties.toMutableMap(), + ) } private var validated: Boolean = false @@ -3003,9 +3067,10 @@ private constructor( return@apply } + type().validate() dpo().ifPresent { it.validate() } + reinforcement().ifPresent { it.validate() } supervised().ifPresent { it.validate() } - type().ifPresent { it.validate() } validated = true } @@ -3025,2263 +3090,31 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (dpo.asKnown().getOrNull()?.validity() ?: 0) + - (supervised.asKnown().getOrNull()?.validity() ?: 0) + - (type.asKnown().getOrNull()?.validity() ?: 0) - - /** Configuration for the DPO fine-tuning method. */ - class Dpo - private constructor( - private val hyperparameters: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("hyperparameters") - @ExcludeMissing - hyperparameters: JsonField = JsonMissing.of() - ) : this(hyperparameters, mutableMapOf()) + (type.asKnown().getOrNull()?.validity() ?: 0) + + (dpo.asKnown().getOrNull()?.validity() ?: 0) + + (reinforcement.asKnown().getOrNull()?.validity() ?: 0) + + (supervised.asKnown().getOrNull()?.validity() ?: 0) - /** - * The hyperparameters used for the fine-tuning job. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun hyperparameters(): Optional = - hyperparameters.getOptional("hyperparameters") + /** The type of method. Is either `supervised`, `dpo`, or `reinforcement`. */ + class Type @JsonCreator private constructor(private val value: JsonField) : Enum { /** - * Returns the raw JSON value of [hyperparameters]. + * Returns this class instance's raw value. * - * Unlike [hyperparameters], this method doesn't throw if the JSON field has an - * unexpected type. + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. */ - @JsonProperty("hyperparameters") - @ExcludeMissing - fun _hyperparameters(): JsonField = hyperparameters - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value companion object { - /** Returns a mutable builder for constructing an instance of [Dpo]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Dpo]. */ - class Builder internal constructor() { - - private var hyperparameters: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(dpo: Dpo) = apply { - hyperparameters = dpo.hyperparameters - additionalProperties = dpo.additionalProperties.toMutableMap() - } - - /** The hyperparameters used for the fine-tuning job. */ - fun hyperparameters(hyperparameters: Hyperparameters) = - hyperparameters(JsonField.of(hyperparameters)) - - /** - * Sets [Builder.hyperparameters] to an arbitrary JSON value. - * - * You should usually call [Builder.hyperparameters] with a well-typed - * [Hyperparameters] value instead. This method is primarily for setting the field - * to an undocumented or not yet supported value. - */ - fun hyperparameters(hyperparameters: JsonField) = apply { - this.hyperparameters = hyperparameters - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [Dpo]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Dpo = Dpo(hyperparameters, additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false - - fun validate(): Dpo = apply { - if (validated) { - return@apply - } - - hyperparameters().ifPresent { it.validate() } - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = (hyperparameters.asKnown().getOrNull()?.validity() ?: 0) - - /** The hyperparameters used for the fine-tuning job. */ - class Hyperparameters - private constructor( - private val batchSize: JsonField, - private val beta: JsonField, - private val learningRateMultiplier: JsonField, - private val nEpochs: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("batch_size") - @ExcludeMissing - batchSize: JsonField = JsonMissing.of(), - @JsonProperty("beta") @ExcludeMissing beta: JsonField = JsonMissing.of(), - @JsonProperty("learning_rate_multiplier") - @ExcludeMissing - learningRateMultiplier: JsonField = JsonMissing.of(), - @JsonProperty("n_epochs") - @ExcludeMissing - nEpochs: JsonField = JsonMissing.of(), - ) : this(batchSize, beta, learningRateMultiplier, nEpochs, mutableMapOf()) - - /** - * Number of examples in each batch. A larger batch size means that model parameters - * are updated less frequently, but with lower variance. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun batchSize(): Optional = batchSize.getOptional("batch_size") - - /** - * The beta value for the DPO method. A higher beta value will increase the weight - * of the penalty between the policy and reference model. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun beta(): Optional = beta.getOptional("beta") - - /** - * Scaling factor for the learning rate. A smaller learning rate may be useful to - * avoid overfitting. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun learningRateMultiplier(): Optional = - learningRateMultiplier.getOptional("learning_rate_multiplier") - - /** - * The number of epochs to train the model for. An epoch refers to one full cycle - * through the training dataset. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun nEpochs(): Optional = nEpochs.getOptional("n_epochs") - - /** - * Returns the raw JSON value of [batchSize]. - * - * Unlike [batchSize], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("batch_size") - @ExcludeMissing - fun _batchSize(): JsonField = batchSize - - /** - * Returns the raw JSON value of [beta]. - * - * Unlike [beta], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("beta") @ExcludeMissing fun _beta(): JsonField = beta - - /** - * Returns the raw JSON value of [learningRateMultiplier]. - * - * Unlike [learningRateMultiplier], this method doesn't throw if the JSON field has - * an unexpected type. - */ - @JsonProperty("learning_rate_multiplier") - @ExcludeMissing - fun _learningRateMultiplier(): JsonField = - learningRateMultiplier - - /** - * Returns the raw JSON value of [nEpochs]. - * - * Unlike [nEpochs], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("n_epochs") - @ExcludeMissing - fun _nEpochs(): JsonField = nEpochs - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** - * Returns a mutable builder for constructing an instance of [Hyperparameters]. - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Hyperparameters]. */ - class Builder internal constructor() { - - private var batchSize: JsonField = JsonMissing.of() - private var beta: JsonField = JsonMissing.of() - private var learningRateMultiplier: JsonField = - JsonMissing.of() - private var nEpochs: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(hyperparameters: Hyperparameters) = apply { - batchSize = hyperparameters.batchSize - beta = hyperparameters.beta - learningRateMultiplier = hyperparameters.learningRateMultiplier - nEpochs = hyperparameters.nEpochs - additionalProperties = hyperparameters.additionalProperties.toMutableMap() - } - - /** - * Number of examples in each batch. A larger batch size means that model - * parameters are updated less frequently, but with lower variance. - */ - fun batchSize(batchSize: BatchSize) = batchSize(JsonField.of(batchSize)) - - /** - * Sets [Builder.batchSize] to an arbitrary JSON value. - * - * You should usually call [Builder.batchSize] with a well-typed [BatchSize] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun batchSize(batchSize: JsonField) = apply { - this.batchSize = batchSize - } - - /** Alias for calling [batchSize] with `BatchSize.ofAuto()`. */ - fun batchSizeAuto() = batchSize(BatchSize.ofAuto()) - - /** Alias for calling [batchSize] with `BatchSize.ofManual(manual)`. */ - fun batchSize(manual: Long) = batchSize(BatchSize.ofManual(manual)) - - /** - * The beta value for the DPO method. A higher beta value will increase the - * weight of the penalty between the policy and reference model. - */ - fun beta(beta: Beta) = beta(JsonField.of(beta)) - - /** - * Sets [Builder.beta] to an arbitrary JSON value. - * - * You should usually call [Builder.beta] with a well-typed [Beta] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun beta(beta: JsonField) = apply { this.beta = beta } - - /** Alias for calling [beta] with `Beta.ofAuto()`. */ - fun betaAuto() = beta(Beta.ofAuto()) - - /** Alias for calling [beta] with `Beta.ofManual(manual)`. */ - fun beta(manual: Double) = beta(Beta.ofManual(manual)) - - /** - * Scaling factor for the learning rate. A smaller learning rate may be useful - * to avoid overfitting. - */ - fun learningRateMultiplier(learningRateMultiplier: LearningRateMultiplier) = - learningRateMultiplier(JsonField.of(learningRateMultiplier)) - - /** - * Sets [Builder.learningRateMultiplier] to an arbitrary JSON value. - * - * You should usually call [Builder.learningRateMultiplier] with a well-typed - * [LearningRateMultiplier] value instead. This method is primarily for setting - * the field to an undocumented or not yet supported value. - */ - fun learningRateMultiplier( - learningRateMultiplier: JsonField - ) = apply { this.learningRateMultiplier = learningRateMultiplier } - - /** - * Alias for calling [learningRateMultiplier] with - * `LearningRateMultiplier.ofAuto()`. - */ - fun learningRateMultiplierAuto() = - learningRateMultiplier(LearningRateMultiplier.ofAuto()) - - /** - * Alias for calling [learningRateMultiplier] with - * `LearningRateMultiplier.ofManual(manual)`. - */ - fun learningRateMultiplier(manual: Double) = - learningRateMultiplier(LearningRateMultiplier.ofManual(manual)) - - /** - * The number of epochs to train the model for. An epoch refers to one full - * cycle through the training dataset. - */ - fun nEpochs(nEpochs: NEpochs) = nEpochs(JsonField.of(nEpochs)) - - /** - * Sets [Builder.nEpochs] to an arbitrary JSON value. - * - * You should usually call [Builder.nEpochs] with a well-typed [NEpochs] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun nEpochs(nEpochs: JsonField) = apply { this.nEpochs = nEpochs } - - /** Alias for calling [nEpochs] with `NEpochs.ofAuto()`. */ - fun nEpochsAuto() = nEpochs(NEpochs.ofAuto()) - - /** Alias for calling [nEpochs] with `NEpochs.ofManual(manual)`. */ - fun nEpochs(manual: Long) = nEpochs(NEpochs.ofManual(manual)) - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [Hyperparameters]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Hyperparameters = - Hyperparameters( - batchSize, - beta, - learningRateMultiplier, - nEpochs, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): Hyperparameters = apply { - if (validated) { - return@apply - } - - batchSize().ifPresent { it.validate() } - beta().ifPresent { it.validate() } - learningRateMultiplier().ifPresent { it.validate() } - nEpochs().ifPresent { it.validate() } - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (batchSize.asKnown().getOrNull()?.validity() ?: 0) + - (beta.asKnown().getOrNull()?.validity() ?: 0) + - (learningRateMultiplier.asKnown().getOrNull()?.validity() ?: 0) + - (nEpochs.asKnown().getOrNull()?.validity() ?: 0) + @JvmField val SUPERVISED = of("supervised") - /** - * Number of examples in each batch. A larger batch size means that model parameters - * are updated less frequently, but with lower variance. - */ - @JsonDeserialize(using = BatchSize.Deserializer::class) - @JsonSerialize(using = BatchSize.Serializer::class) - class BatchSize - private constructor( - private val auto: JsonValue? = null, - private val manual: Long? = null, - private val _json: JsonValue? = null, - ) { + @JvmField val DPO = of("dpo") - fun auto(): Optional = Optional.ofNullable(auto) - - fun manual(): Optional = Optional.ofNullable(manual) - - fun isAuto(): Boolean = auto != null - - fun isManual(): Boolean = manual != null - - fun asAuto(): JsonValue = auto.getOrThrow("auto") - - fun asManual(): Long = manual.getOrThrow("manual") - - fun _json(): Optional = Optional.ofNullable(_json) - - fun accept(visitor: Visitor): T = - when { - auto != null -> visitor.visitAuto(auto) - manual != null -> visitor.visitManual(manual) - else -> visitor.unknown(_json) - } - - private var validated: Boolean = false - - fun validate(): BatchSize = apply { - if (validated) { - return@apply - } - - accept( - object : Visitor { - override fun visitAuto(auto: JsonValue) { - auto.let { - if (it != JsonValue.from("auto")) { - throw OpenAIInvalidDataException( - "'auto' is invalid, received $it" - ) - } - } - } - - override fun visitManual(manual: Long) {} - } - ) - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - accept( - object : Visitor { - override fun visitAuto(auto: JsonValue) = - auto.let { if (it == JsonValue.from("auto")) 1 else 0 } - - override fun visitManual(manual: Long) = 1 - - override fun unknown(json: JsonValue?) = 0 - } - ) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is BatchSize && auto == other.auto && manual == other.manual /* spotless:on */ - } - - override fun hashCode(): Int = /* spotless:off */ Objects.hash(auto, manual) /* spotless:on */ - - override fun toString(): String = - when { - auto != null -> "BatchSize{auto=$auto}" - manual != null -> "BatchSize{manual=$manual}" - _json != null -> "BatchSize{_unknown=$_json}" - else -> throw IllegalStateException("Invalid BatchSize") - } - - companion object { - - @JvmStatic fun ofAuto() = BatchSize(auto = JsonValue.from("auto")) - - @JvmStatic fun ofManual(manual: Long) = BatchSize(manual = manual) - } - - /** - * An interface that defines how to map each variant of [BatchSize] to a value - * of type [T]. - */ - interface Visitor { - - fun visitAuto(auto: JsonValue): T - - fun visitManual(manual: Long): T - - /** - * Maps an unknown variant of [BatchSize] to a value of type [T]. - * - * An instance of [BatchSize] can contain an unknown variant if it was - * deserialized from data that doesn't match any known variant. For example, - * if the SDK is on an older version than the API, then the API may respond - * with new variants that the SDK is unaware of. - * - * @throws OpenAIInvalidDataException in the default implementation. - */ - fun unknown(json: JsonValue?): T { - throw OpenAIInvalidDataException("Unknown BatchSize: $json") - } - } - - internal class Deserializer : BaseDeserializer(BatchSize::class) { - - override fun ObjectCodec.deserialize(node: JsonNode): BatchSize { - val json = JsonValue.fromJsonNode(node) - - val bestMatches = - sequenceOf( - tryDeserialize(node, jacksonTypeRef()) - ?.let { BatchSize(auto = it, _json = json) } - ?.takeIf { it.isValid() }, - tryDeserialize(node, jacksonTypeRef())?.let { - BatchSize(manual = it, _json = json) - }, - ) - .filterNotNull() - .allMaxBy { it.validity() } - .toList() - return when (bestMatches.size) { - // This can happen if what we're deserializing is completely - // incompatible with all the possible variants (e.g. deserializing - // from object). - 0 -> BatchSize(_json = json) - 1 -> bestMatches.single() - // If there's more than one match with the highest validity, then - // use the first completely valid match, or simply the first match - // if none are completely valid. - else -> - bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() - } - } - } - - internal class Serializer : BaseSerializer(BatchSize::class) { - - override fun serialize( - value: BatchSize, - generator: JsonGenerator, - provider: SerializerProvider, - ) { - when { - value.auto != null -> generator.writeObject(value.auto) - value.manual != null -> generator.writeObject(value.manual) - value._json != null -> generator.writeObject(value._json) - else -> throw IllegalStateException("Invalid BatchSize") - } - } - } - } - - /** - * The beta value for the DPO method. A higher beta value will increase the weight - * of the penalty between the policy and reference model. - */ - @JsonDeserialize(using = Beta.Deserializer::class) - @JsonSerialize(using = Beta.Serializer::class) - class Beta - private constructor( - private val auto: JsonValue? = null, - private val manual: Double? = null, - private val _json: JsonValue? = null, - ) { - - fun auto(): Optional = Optional.ofNullable(auto) - - fun manual(): Optional = Optional.ofNullable(manual) - - fun isAuto(): Boolean = auto != null - - fun isManual(): Boolean = manual != null - - fun asAuto(): JsonValue = auto.getOrThrow("auto") - - fun asManual(): Double = manual.getOrThrow("manual") - - fun _json(): Optional = Optional.ofNullable(_json) - - fun accept(visitor: Visitor): T = - when { - auto != null -> visitor.visitAuto(auto) - manual != null -> visitor.visitManual(manual) - else -> visitor.unknown(_json) - } - - private var validated: Boolean = false - - fun validate(): Beta = apply { - if (validated) { - return@apply - } - - accept( - object : Visitor { - override fun visitAuto(auto: JsonValue) { - auto.let { - if (it != JsonValue.from("auto")) { - throw OpenAIInvalidDataException( - "'auto' is invalid, received $it" - ) - } - } - } - - override fun visitManual(manual: Double) {} - } - ) - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - accept( - object : Visitor { - override fun visitAuto(auto: JsonValue) = - auto.let { if (it == JsonValue.from("auto")) 1 else 0 } - - override fun visitManual(manual: Double) = 1 - - override fun unknown(json: JsonValue?) = 0 - } - ) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is Beta && auto == other.auto && manual == other.manual /* spotless:on */ - } - - override fun hashCode(): Int = /* spotless:off */ Objects.hash(auto, manual) /* spotless:on */ - - override fun toString(): String = - when { - auto != null -> "Beta{auto=$auto}" - manual != null -> "Beta{manual=$manual}" - _json != null -> "Beta{_unknown=$_json}" - else -> throw IllegalStateException("Invalid Beta") - } - - companion object { - - @JvmStatic fun ofAuto() = Beta(auto = JsonValue.from("auto")) - - @JvmStatic fun ofManual(manual: Double) = Beta(manual = manual) - } - - /** - * An interface that defines how to map each variant of [Beta] to a value of - * type [T]. - */ - interface Visitor { - - fun visitAuto(auto: JsonValue): T - - fun visitManual(manual: Double): T - - /** - * Maps an unknown variant of [Beta] to a value of type [T]. - * - * An instance of [Beta] can contain an unknown variant if it was - * deserialized from data that doesn't match any known variant. For example, - * if the SDK is on an older version than the API, then the API may respond - * with new variants that the SDK is unaware of. - * - * @throws OpenAIInvalidDataException in the default implementation. - */ - fun unknown(json: JsonValue?): T { - throw OpenAIInvalidDataException("Unknown Beta: $json") - } - } - - internal class Deserializer : BaseDeserializer(Beta::class) { - - override fun ObjectCodec.deserialize(node: JsonNode): Beta { - val json = JsonValue.fromJsonNode(node) - - val bestMatches = - sequenceOf( - tryDeserialize(node, jacksonTypeRef()) - ?.let { Beta(auto = it, _json = json) } - ?.takeIf { it.isValid() }, - tryDeserialize(node, jacksonTypeRef())?.let { - Beta(manual = it, _json = json) - }, - ) - .filterNotNull() - .allMaxBy { it.validity() } - .toList() - return when (bestMatches.size) { - // This can happen if what we're deserializing is completely - // incompatible with all the possible variants (e.g. deserializing - // from object). - 0 -> Beta(_json = json) - 1 -> bestMatches.single() - // If there's more than one match with the highest validity, then - // use the first completely valid match, or simply the first match - // if none are completely valid. - else -> - bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() - } - } - } - - internal class Serializer : BaseSerializer(Beta::class) { - - override fun serialize( - value: Beta, - generator: JsonGenerator, - provider: SerializerProvider, - ) { - when { - value.auto != null -> generator.writeObject(value.auto) - value.manual != null -> generator.writeObject(value.manual) - value._json != null -> generator.writeObject(value._json) - else -> throw IllegalStateException("Invalid Beta") - } - } - } - } - - /** - * Scaling factor for the learning rate. A smaller learning rate may be useful to - * avoid overfitting. - */ - @JsonDeserialize(using = LearningRateMultiplier.Deserializer::class) - @JsonSerialize(using = LearningRateMultiplier.Serializer::class) - class LearningRateMultiplier - private constructor( - private val auto: JsonValue? = null, - private val manual: Double? = null, - private val _json: JsonValue? = null, - ) { - - fun auto(): Optional = Optional.ofNullable(auto) - - fun manual(): Optional = Optional.ofNullable(manual) - - fun isAuto(): Boolean = auto != null - - fun isManual(): Boolean = manual != null - - fun asAuto(): JsonValue = auto.getOrThrow("auto") - - fun asManual(): Double = manual.getOrThrow("manual") - - fun _json(): Optional = Optional.ofNullable(_json) - - fun accept(visitor: Visitor): T = - when { - auto != null -> visitor.visitAuto(auto) - manual != null -> visitor.visitManual(manual) - else -> visitor.unknown(_json) - } - - private var validated: Boolean = false - - fun validate(): LearningRateMultiplier = apply { - if (validated) { - return@apply - } - - accept( - object : Visitor { - override fun visitAuto(auto: JsonValue) { - auto.let { - if (it != JsonValue.from("auto")) { - throw OpenAIInvalidDataException( - "'auto' is invalid, received $it" - ) - } - } - } - - override fun visitManual(manual: Double) {} - } - ) - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - accept( - object : Visitor { - override fun visitAuto(auto: JsonValue) = - auto.let { if (it == JsonValue.from("auto")) 1 else 0 } - - override fun visitManual(manual: Double) = 1 - - override fun unknown(json: JsonValue?) = 0 - } - ) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is LearningRateMultiplier && auto == other.auto && manual == other.manual /* spotless:on */ - } - - override fun hashCode(): Int = /* spotless:off */ Objects.hash(auto, manual) /* spotless:on */ - - override fun toString(): String = - when { - auto != null -> "LearningRateMultiplier{auto=$auto}" - manual != null -> "LearningRateMultiplier{manual=$manual}" - _json != null -> "LearningRateMultiplier{_unknown=$_json}" - else -> throw IllegalStateException("Invalid LearningRateMultiplier") - } - - companion object { - - @JvmStatic - fun ofAuto() = LearningRateMultiplier(auto = JsonValue.from("auto")) - - @JvmStatic - fun ofManual(manual: Double) = LearningRateMultiplier(manual = manual) - } - - /** - * An interface that defines how to map each variant of [LearningRateMultiplier] - * to a value of type [T]. - */ - interface Visitor { - - fun visitAuto(auto: JsonValue): T - - fun visitManual(manual: Double): T - - /** - * Maps an unknown variant of [LearningRateMultiplier] to a value of type - * [T]. - * - * An instance of [LearningRateMultiplier] can contain an unknown variant if - * it was deserialized from data that doesn't match any known variant. For - * example, if the SDK is on an older version than the API, then the API may - * respond with new variants that the SDK is unaware of. - * - * @throws OpenAIInvalidDataException in the default implementation. - */ - fun unknown(json: JsonValue?): T { - throw OpenAIInvalidDataException( - "Unknown LearningRateMultiplier: $json" - ) - } - } - - internal class Deserializer : - BaseDeserializer(LearningRateMultiplier::class) { - - override fun ObjectCodec.deserialize( - node: JsonNode - ): LearningRateMultiplier { - val json = JsonValue.fromJsonNode(node) - - val bestMatches = - sequenceOf( - tryDeserialize(node, jacksonTypeRef()) - ?.let { - LearningRateMultiplier(auto = it, _json = json) - } - ?.takeIf { it.isValid() }, - tryDeserialize(node, jacksonTypeRef())?.let { - LearningRateMultiplier(manual = it, _json = json) - }, - ) - .filterNotNull() - .allMaxBy { it.validity() } - .toList() - return when (bestMatches.size) { - // This can happen if what we're deserializing is completely - // incompatible with all the possible variants (e.g. deserializing - // from object). - 0 -> LearningRateMultiplier(_json = json) - 1 -> bestMatches.single() - // If there's more than one match with the highest validity, then - // use the first completely valid match, or simply the first match - // if none are completely valid. - else -> - bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() - } - } - } - - internal class Serializer : - BaseSerializer(LearningRateMultiplier::class) { - - override fun serialize( - value: LearningRateMultiplier, - generator: JsonGenerator, - provider: SerializerProvider, - ) { - when { - value.auto != null -> generator.writeObject(value.auto) - value.manual != null -> generator.writeObject(value.manual) - value._json != null -> generator.writeObject(value._json) - else -> - throw IllegalStateException("Invalid LearningRateMultiplier") - } - } - } - } - - /** - * The number of epochs to train the model for. An epoch refers to one full cycle - * through the training dataset. - */ - @JsonDeserialize(using = NEpochs.Deserializer::class) - @JsonSerialize(using = NEpochs.Serializer::class) - class NEpochs - private constructor( - private val auto: JsonValue? = null, - private val manual: Long? = null, - private val _json: JsonValue? = null, - ) { - - fun auto(): Optional = Optional.ofNullable(auto) - - fun manual(): Optional = Optional.ofNullable(manual) - - fun isAuto(): Boolean = auto != null - - fun isManual(): Boolean = manual != null - - fun asAuto(): JsonValue = auto.getOrThrow("auto") - - fun asManual(): Long = manual.getOrThrow("manual") - - fun _json(): Optional = Optional.ofNullable(_json) - - fun accept(visitor: Visitor): T = - when { - auto != null -> visitor.visitAuto(auto) - manual != null -> visitor.visitManual(manual) - else -> visitor.unknown(_json) - } - - private var validated: Boolean = false - - fun validate(): NEpochs = apply { - if (validated) { - return@apply - } - - accept( - object : Visitor { - override fun visitAuto(auto: JsonValue) { - auto.let { - if (it != JsonValue.from("auto")) { - throw OpenAIInvalidDataException( - "'auto' is invalid, received $it" - ) - } - } - } - - override fun visitManual(manual: Long) {} - } - ) - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - accept( - object : Visitor { - override fun visitAuto(auto: JsonValue) = - auto.let { if (it == JsonValue.from("auto")) 1 else 0 } - - override fun visitManual(manual: Long) = 1 - - override fun unknown(json: JsonValue?) = 0 - } - ) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is NEpochs && auto == other.auto && manual == other.manual /* spotless:on */ - } - - override fun hashCode(): Int = /* spotless:off */ Objects.hash(auto, manual) /* spotless:on */ - - override fun toString(): String = - when { - auto != null -> "NEpochs{auto=$auto}" - manual != null -> "NEpochs{manual=$manual}" - _json != null -> "NEpochs{_unknown=$_json}" - else -> throw IllegalStateException("Invalid NEpochs") - } - - companion object { - - @JvmStatic fun ofAuto() = NEpochs(auto = JsonValue.from("auto")) - - @JvmStatic fun ofManual(manual: Long) = NEpochs(manual = manual) - } - - /** - * An interface that defines how to map each variant of [NEpochs] to a value of - * type [T]. - */ - interface Visitor { - - fun visitAuto(auto: JsonValue): T - - fun visitManual(manual: Long): T - - /** - * Maps an unknown variant of [NEpochs] to a value of type [T]. - * - * An instance of [NEpochs] can contain an unknown variant if it was - * deserialized from data that doesn't match any known variant. For example, - * if the SDK is on an older version than the API, then the API may respond - * with new variants that the SDK is unaware of. - * - * @throws OpenAIInvalidDataException in the default implementation. - */ - fun unknown(json: JsonValue?): T { - throw OpenAIInvalidDataException("Unknown NEpochs: $json") - } - } - - internal class Deserializer : BaseDeserializer(NEpochs::class) { - - override fun ObjectCodec.deserialize(node: JsonNode): NEpochs { - val json = JsonValue.fromJsonNode(node) - - val bestMatches = - sequenceOf( - tryDeserialize(node, jacksonTypeRef()) - ?.let { NEpochs(auto = it, _json = json) } - ?.takeIf { it.isValid() }, - tryDeserialize(node, jacksonTypeRef())?.let { - NEpochs(manual = it, _json = json) - }, - ) - .filterNotNull() - .allMaxBy { it.validity() } - .toList() - return when (bestMatches.size) { - // This can happen if what we're deserializing is completely - // incompatible with all the possible variants (e.g. deserializing - // from object). - 0 -> NEpochs(_json = json) - 1 -> bestMatches.single() - // If there's more than one match with the highest validity, then - // use the first completely valid match, or simply the first match - // if none are completely valid. - else -> - bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() - } - } - } - - internal class Serializer : BaseSerializer(NEpochs::class) { - - override fun serialize( - value: NEpochs, - generator: JsonGenerator, - provider: SerializerProvider, - ) { - when { - value.auto != null -> generator.writeObject(value.auto) - value.manual != null -> generator.writeObject(value.manual) - value._json != null -> generator.writeObject(value._json) - else -> throw IllegalStateException("Invalid NEpochs") - } - } - } - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is Hyperparameters && batchSize == other.batchSize && beta == other.beta && learningRateMultiplier == other.learningRateMultiplier && nEpochs == other.nEpochs && additionalProperties == other.additionalProperties /* spotless:on */ - } - - /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(batchSize, beta, learningRateMultiplier, nEpochs, additionalProperties) } - /* spotless:on */ - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Hyperparameters{batchSize=$batchSize, beta=$beta, learningRateMultiplier=$learningRateMultiplier, nEpochs=$nEpochs, additionalProperties=$additionalProperties}" - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is Dpo && hyperparameters == other.hyperparameters && additionalProperties == other.additionalProperties /* spotless:on */ - } - - /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(hyperparameters, additionalProperties) } - /* spotless:on */ - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Dpo{hyperparameters=$hyperparameters, additionalProperties=$additionalProperties}" - } - - /** Configuration for the supervised fine-tuning method. */ - class Supervised - private constructor( - private val hyperparameters: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("hyperparameters") - @ExcludeMissing - hyperparameters: JsonField = JsonMissing.of() - ) : this(hyperparameters, mutableMapOf()) - - /** - * The hyperparameters used for the fine-tuning job. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun hyperparameters(): Optional = - hyperparameters.getOptional("hyperparameters") - - /** - * Returns the raw JSON value of [hyperparameters]. - * - * Unlike [hyperparameters], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("hyperparameters") - @ExcludeMissing - fun _hyperparameters(): JsonField = hyperparameters - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** Returns a mutable builder for constructing an instance of [Supervised]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Supervised]. */ - class Builder internal constructor() { - - private var hyperparameters: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(supervised: Supervised) = apply { - hyperparameters = supervised.hyperparameters - additionalProperties = supervised.additionalProperties.toMutableMap() - } - - /** The hyperparameters used for the fine-tuning job. */ - fun hyperparameters(hyperparameters: Hyperparameters) = - hyperparameters(JsonField.of(hyperparameters)) - - /** - * Sets [Builder.hyperparameters] to an arbitrary JSON value. - * - * You should usually call [Builder.hyperparameters] with a well-typed - * [Hyperparameters] value instead. This method is primarily for setting the field - * to an undocumented or not yet supported value. - */ - fun hyperparameters(hyperparameters: JsonField) = apply { - this.hyperparameters = hyperparameters - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [Supervised]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Supervised = - Supervised(hyperparameters, additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false - - fun validate(): Supervised = apply { - if (validated) { - return@apply - } - - hyperparameters().ifPresent { it.validate() } - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = (hyperparameters.asKnown().getOrNull()?.validity() ?: 0) - - /** The hyperparameters used for the fine-tuning job. */ - class Hyperparameters - private constructor( - private val batchSize: JsonField, - private val learningRateMultiplier: JsonField, - private val nEpochs: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("batch_size") - @ExcludeMissing - batchSize: JsonField = JsonMissing.of(), - @JsonProperty("learning_rate_multiplier") - @ExcludeMissing - learningRateMultiplier: JsonField = JsonMissing.of(), - @JsonProperty("n_epochs") - @ExcludeMissing - nEpochs: JsonField = JsonMissing.of(), - ) : this(batchSize, learningRateMultiplier, nEpochs, mutableMapOf()) - - /** - * Number of examples in each batch. A larger batch size means that model parameters - * are updated less frequently, but with lower variance. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun batchSize(): Optional = batchSize.getOptional("batch_size") - - /** - * Scaling factor for the learning rate. A smaller learning rate may be useful to - * avoid overfitting. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun learningRateMultiplier(): Optional = - learningRateMultiplier.getOptional("learning_rate_multiplier") - - /** - * The number of epochs to train the model for. An epoch refers to one full cycle - * through the training dataset. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun nEpochs(): Optional = nEpochs.getOptional("n_epochs") - - /** - * Returns the raw JSON value of [batchSize]. - * - * Unlike [batchSize], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("batch_size") - @ExcludeMissing - fun _batchSize(): JsonField = batchSize - - /** - * Returns the raw JSON value of [learningRateMultiplier]. - * - * Unlike [learningRateMultiplier], this method doesn't throw if the JSON field has - * an unexpected type. - */ - @JsonProperty("learning_rate_multiplier") - @ExcludeMissing - fun _learningRateMultiplier(): JsonField = - learningRateMultiplier - - /** - * Returns the raw JSON value of [nEpochs]. - * - * Unlike [nEpochs], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("n_epochs") - @ExcludeMissing - fun _nEpochs(): JsonField = nEpochs - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** - * Returns a mutable builder for constructing an instance of [Hyperparameters]. - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Hyperparameters]. */ - class Builder internal constructor() { - - private var batchSize: JsonField = JsonMissing.of() - private var learningRateMultiplier: JsonField = - JsonMissing.of() - private var nEpochs: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(hyperparameters: Hyperparameters) = apply { - batchSize = hyperparameters.batchSize - learningRateMultiplier = hyperparameters.learningRateMultiplier - nEpochs = hyperparameters.nEpochs - additionalProperties = hyperparameters.additionalProperties.toMutableMap() - } - - /** - * Number of examples in each batch. A larger batch size means that model - * parameters are updated less frequently, but with lower variance. - */ - fun batchSize(batchSize: BatchSize) = batchSize(JsonField.of(batchSize)) - - /** - * Sets [Builder.batchSize] to an arbitrary JSON value. - * - * You should usually call [Builder.batchSize] with a well-typed [BatchSize] - * value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. - */ - fun batchSize(batchSize: JsonField) = apply { - this.batchSize = batchSize - } - - /** Alias for calling [batchSize] with `BatchSize.ofAuto()`. */ - fun batchSizeAuto() = batchSize(BatchSize.ofAuto()) - - /** Alias for calling [batchSize] with `BatchSize.ofManual(manual)`. */ - fun batchSize(manual: Long) = batchSize(BatchSize.ofManual(manual)) - - /** - * Scaling factor for the learning rate. A smaller learning rate may be useful - * to avoid overfitting. - */ - fun learningRateMultiplier(learningRateMultiplier: LearningRateMultiplier) = - learningRateMultiplier(JsonField.of(learningRateMultiplier)) - - /** - * Sets [Builder.learningRateMultiplier] to an arbitrary JSON value. - * - * You should usually call [Builder.learningRateMultiplier] with a well-typed - * [LearningRateMultiplier] value instead. This method is primarily for setting - * the field to an undocumented or not yet supported value. - */ - fun learningRateMultiplier( - learningRateMultiplier: JsonField - ) = apply { this.learningRateMultiplier = learningRateMultiplier } - - /** - * Alias for calling [learningRateMultiplier] with - * `LearningRateMultiplier.ofAuto()`. - */ - fun learningRateMultiplierAuto() = - learningRateMultiplier(LearningRateMultiplier.ofAuto()) - - /** - * Alias for calling [learningRateMultiplier] with - * `LearningRateMultiplier.ofManual(manual)`. - */ - fun learningRateMultiplier(manual: Double) = - learningRateMultiplier(LearningRateMultiplier.ofManual(manual)) - - /** - * The number of epochs to train the model for. An epoch refers to one full - * cycle through the training dataset. - */ - fun nEpochs(nEpochs: NEpochs) = nEpochs(JsonField.of(nEpochs)) - - /** - * Sets [Builder.nEpochs] to an arbitrary JSON value. - * - * You should usually call [Builder.nEpochs] with a well-typed [NEpochs] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun nEpochs(nEpochs: JsonField) = apply { this.nEpochs = nEpochs } - - /** Alias for calling [nEpochs] with `NEpochs.ofAuto()`. */ - fun nEpochsAuto() = nEpochs(NEpochs.ofAuto()) - - /** Alias for calling [nEpochs] with `NEpochs.ofManual(manual)`. */ - fun nEpochs(manual: Long) = nEpochs(NEpochs.ofManual(manual)) - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [Hyperparameters]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Hyperparameters = - Hyperparameters( - batchSize, - learningRateMultiplier, - nEpochs, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): Hyperparameters = apply { - if (validated) { - return@apply - } - - batchSize().ifPresent { it.validate() } - learningRateMultiplier().ifPresent { it.validate() } - nEpochs().ifPresent { it.validate() } - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (batchSize.asKnown().getOrNull()?.validity() ?: 0) + - (learningRateMultiplier.asKnown().getOrNull()?.validity() ?: 0) + - (nEpochs.asKnown().getOrNull()?.validity() ?: 0) - - /** - * Number of examples in each batch. A larger batch size means that model parameters - * are updated less frequently, but with lower variance. - */ - @JsonDeserialize(using = BatchSize.Deserializer::class) - @JsonSerialize(using = BatchSize.Serializer::class) - class BatchSize - private constructor( - private val auto: JsonValue? = null, - private val manual: Long? = null, - private val _json: JsonValue? = null, - ) { - - fun auto(): Optional = Optional.ofNullable(auto) - - fun manual(): Optional = Optional.ofNullable(manual) - - fun isAuto(): Boolean = auto != null - - fun isManual(): Boolean = manual != null - - fun asAuto(): JsonValue = auto.getOrThrow("auto") - - fun asManual(): Long = manual.getOrThrow("manual") - - fun _json(): Optional = Optional.ofNullable(_json) - - fun accept(visitor: Visitor): T = - when { - auto != null -> visitor.visitAuto(auto) - manual != null -> visitor.visitManual(manual) - else -> visitor.unknown(_json) - } - - private var validated: Boolean = false - - fun validate(): BatchSize = apply { - if (validated) { - return@apply - } - - accept( - object : Visitor { - override fun visitAuto(auto: JsonValue) { - auto.let { - if (it != JsonValue.from("auto")) { - throw OpenAIInvalidDataException( - "'auto' is invalid, received $it" - ) - } - } - } - - override fun visitManual(manual: Long) {} - } - ) - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - accept( - object : Visitor { - override fun visitAuto(auto: JsonValue) = - auto.let { if (it == JsonValue.from("auto")) 1 else 0 } - - override fun visitManual(manual: Long) = 1 - - override fun unknown(json: JsonValue?) = 0 - } - ) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is BatchSize && auto == other.auto && manual == other.manual /* spotless:on */ - } - - override fun hashCode(): Int = /* spotless:off */ Objects.hash(auto, manual) /* spotless:on */ - - override fun toString(): String = - when { - auto != null -> "BatchSize{auto=$auto}" - manual != null -> "BatchSize{manual=$manual}" - _json != null -> "BatchSize{_unknown=$_json}" - else -> throw IllegalStateException("Invalid BatchSize") - } - - companion object { - - @JvmStatic fun ofAuto() = BatchSize(auto = JsonValue.from("auto")) - - @JvmStatic fun ofManual(manual: Long) = BatchSize(manual = manual) - } - - /** - * An interface that defines how to map each variant of [BatchSize] to a value - * of type [T]. - */ - interface Visitor { - - fun visitAuto(auto: JsonValue): T - - fun visitManual(manual: Long): T - - /** - * Maps an unknown variant of [BatchSize] to a value of type [T]. - * - * An instance of [BatchSize] can contain an unknown variant if it was - * deserialized from data that doesn't match any known variant. For example, - * if the SDK is on an older version than the API, then the API may respond - * with new variants that the SDK is unaware of. - * - * @throws OpenAIInvalidDataException in the default implementation. - */ - fun unknown(json: JsonValue?): T { - throw OpenAIInvalidDataException("Unknown BatchSize: $json") - } - } - - internal class Deserializer : BaseDeserializer(BatchSize::class) { - - override fun ObjectCodec.deserialize(node: JsonNode): BatchSize { - val json = JsonValue.fromJsonNode(node) - - val bestMatches = - sequenceOf( - tryDeserialize(node, jacksonTypeRef()) - ?.let { BatchSize(auto = it, _json = json) } - ?.takeIf { it.isValid() }, - tryDeserialize(node, jacksonTypeRef())?.let { - BatchSize(manual = it, _json = json) - }, - ) - .filterNotNull() - .allMaxBy { it.validity() } - .toList() - return when (bestMatches.size) { - // This can happen if what we're deserializing is completely - // incompatible with all the possible variants (e.g. deserializing - // from object). - 0 -> BatchSize(_json = json) - 1 -> bestMatches.single() - // If there's more than one match with the highest validity, then - // use the first completely valid match, or simply the first match - // if none are completely valid. - else -> - bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() - } - } - } - - internal class Serializer : BaseSerializer(BatchSize::class) { - - override fun serialize( - value: BatchSize, - generator: JsonGenerator, - provider: SerializerProvider, - ) { - when { - value.auto != null -> generator.writeObject(value.auto) - value.manual != null -> generator.writeObject(value.manual) - value._json != null -> generator.writeObject(value._json) - else -> throw IllegalStateException("Invalid BatchSize") - } - } - } - } - - /** - * Scaling factor for the learning rate. A smaller learning rate may be useful to - * avoid overfitting. - */ - @JsonDeserialize(using = LearningRateMultiplier.Deserializer::class) - @JsonSerialize(using = LearningRateMultiplier.Serializer::class) - class LearningRateMultiplier - private constructor( - private val auto: JsonValue? = null, - private val manual: Double? = null, - private val _json: JsonValue? = null, - ) { - - fun auto(): Optional = Optional.ofNullable(auto) - - fun manual(): Optional = Optional.ofNullable(manual) - - fun isAuto(): Boolean = auto != null - - fun isManual(): Boolean = manual != null - - fun asAuto(): JsonValue = auto.getOrThrow("auto") - - fun asManual(): Double = manual.getOrThrow("manual") - - fun _json(): Optional = Optional.ofNullable(_json) - - fun accept(visitor: Visitor): T = - when { - auto != null -> visitor.visitAuto(auto) - manual != null -> visitor.visitManual(manual) - else -> visitor.unknown(_json) - } - - private var validated: Boolean = false - - fun validate(): LearningRateMultiplier = apply { - if (validated) { - return@apply - } - - accept( - object : Visitor { - override fun visitAuto(auto: JsonValue) { - auto.let { - if (it != JsonValue.from("auto")) { - throw OpenAIInvalidDataException( - "'auto' is invalid, received $it" - ) - } - } - } - - override fun visitManual(manual: Double) {} - } - ) - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - accept( - object : Visitor { - override fun visitAuto(auto: JsonValue) = - auto.let { if (it == JsonValue.from("auto")) 1 else 0 } - - override fun visitManual(manual: Double) = 1 - - override fun unknown(json: JsonValue?) = 0 - } - ) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is LearningRateMultiplier && auto == other.auto && manual == other.manual /* spotless:on */ - } - - override fun hashCode(): Int = /* spotless:off */ Objects.hash(auto, manual) /* spotless:on */ - - override fun toString(): String = - when { - auto != null -> "LearningRateMultiplier{auto=$auto}" - manual != null -> "LearningRateMultiplier{manual=$manual}" - _json != null -> "LearningRateMultiplier{_unknown=$_json}" - else -> throw IllegalStateException("Invalid LearningRateMultiplier") - } - - companion object { - - @JvmStatic - fun ofAuto() = LearningRateMultiplier(auto = JsonValue.from("auto")) - - @JvmStatic - fun ofManual(manual: Double) = LearningRateMultiplier(manual = manual) - } - - /** - * An interface that defines how to map each variant of [LearningRateMultiplier] - * to a value of type [T]. - */ - interface Visitor { - - fun visitAuto(auto: JsonValue): T - - fun visitManual(manual: Double): T - - /** - * Maps an unknown variant of [LearningRateMultiplier] to a value of type - * [T]. - * - * An instance of [LearningRateMultiplier] can contain an unknown variant if - * it was deserialized from data that doesn't match any known variant. For - * example, if the SDK is on an older version than the API, then the API may - * respond with new variants that the SDK is unaware of. - * - * @throws OpenAIInvalidDataException in the default implementation. - */ - fun unknown(json: JsonValue?): T { - throw OpenAIInvalidDataException( - "Unknown LearningRateMultiplier: $json" - ) - } - } - - internal class Deserializer : - BaseDeserializer(LearningRateMultiplier::class) { - - override fun ObjectCodec.deserialize( - node: JsonNode - ): LearningRateMultiplier { - val json = JsonValue.fromJsonNode(node) - - val bestMatches = - sequenceOf( - tryDeserialize(node, jacksonTypeRef()) - ?.let { - LearningRateMultiplier(auto = it, _json = json) - } - ?.takeIf { it.isValid() }, - tryDeserialize(node, jacksonTypeRef())?.let { - LearningRateMultiplier(manual = it, _json = json) - }, - ) - .filterNotNull() - .allMaxBy { it.validity() } - .toList() - return when (bestMatches.size) { - // This can happen if what we're deserializing is completely - // incompatible with all the possible variants (e.g. deserializing - // from object). - 0 -> LearningRateMultiplier(_json = json) - 1 -> bestMatches.single() - // If there's more than one match with the highest validity, then - // use the first completely valid match, or simply the first match - // if none are completely valid. - else -> - bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() - } - } - } - - internal class Serializer : - BaseSerializer(LearningRateMultiplier::class) { - - override fun serialize( - value: LearningRateMultiplier, - generator: JsonGenerator, - provider: SerializerProvider, - ) { - when { - value.auto != null -> generator.writeObject(value.auto) - value.manual != null -> generator.writeObject(value.manual) - value._json != null -> generator.writeObject(value._json) - else -> - throw IllegalStateException("Invalid LearningRateMultiplier") - } - } - } - } - - /** - * The number of epochs to train the model for. An epoch refers to one full cycle - * through the training dataset. - */ - @JsonDeserialize(using = NEpochs.Deserializer::class) - @JsonSerialize(using = NEpochs.Serializer::class) - class NEpochs - private constructor( - private val auto: JsonValue? = null, - private val manual: Long? = null, - private val _json: JsonValue? = null, - ) { - - fun auto(): Optional = Optional.ofNullable(auto) - - fun manual(): Optional = Optional.ofNullable(manual) - - fun isAuto(): Boolean = auto != null - - fun isManual(): Boolean = manual != null - - fun asAuto(): JsonValue = auto.getOrThrow("auto") - - fun asManual(): Long = manual.getOrThrow("manual") - - fun _json(): Optional = Optional.ofNullable(_json) - - fun accept(visitor: Visitor): T = - when { - auto != null -> visitor.visitAuto(auto) - manual != null -> visitor.visitManual(manual) - else -> visitor.unknown(_json) - } - - private var validated: Boolean = false - - fun validate(): NEpochs = apply { - if (validated) { - return@apply - } - - accept( - object : Visitor { - override fun visitAuto(auto: JsonValue) { - auto.let { - if (it != JsonValue.from("auto")) { - throw OpenAIInvalidDataException( - "'auto' is invalid, received $it" - ) - } - } - } - - override fun visitManual(manual: Long) {} - } - ) - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - accept( - object : Visitor { - override fun visitAuto(auto: JsonValue) = - auto.let { if (it == JsonValue.from("auto")) 1 else 0 } - - override fun visitManual(manual: Long) = 1 - - override fun unknown(json: JsonValue?) = 0 - } - ) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is NEpochs && auto == other.auto && manual == other.manual /* spotless:on */ - } - - override fun hashCode(): Int = /* spotless:off */ Objects.hash(auto, manual) /* spotless:on */ - - override fun toString(): String = - when { - auto != null -> "NEpochs{auto=$auto}" - manual != null -> "NEpochs{manual=$manual}" - _json != null -> "NEpochs{_unknown=$_json}" - else -> throw IllegalStateException("Invalid NEpochs") - } - - companion object { - - @JvmStatic fun ofAuto() = NEpochs(auto = JsonValue.from("auto")) - - @JvmStatic fun ofManual(manual: Long) = NEpochs(manual = manual) - } - - /** - * An interface that defines how to map each variant of [NEpochs] to a value of - * type [T]. - */ - interface Visitor { - - fun visitAuto(auto: JsonValue): T - - fun visitManual(manual: Long): T - - /** - * Maps an unknown variant of [NEpochs] to a value of type [T]. - * - * An instance of [NEpochs] can contain an unknown variant if it was - * deserialized from data that doesn't match any known variant. For example, - * if the SDK is on an older version than the API, then the API may respond - * with new variants that the SDK is unaware of. - * - * @throws OpenAIInvalidDataException in the default implementation. - */ - fun unknown(json: JsonValue?): T { - throw OpenAIInvalidDataException("Unknown NEpochs: $json") - } - } - - internal class Deserializer : BaseDeserializer(NEpochs::class) { - - override fun ObjectCodec.deserialize(node: JsonNode): NEpochs { - val json = JsonValue.fromJsonNode(node) - - val bestMatches = - sequenceOf( - tryDeserialize(node, jacksonTypeRef()) - ?.let { NEpochs(auto = it, _json = json) } - ?.takeIf { it.isValid() }, - tryDeserialize(node, jacksonTypeRef())?.let { - NEpochs(manual = it, _json = json) - }, - ) - .filterNotNull() - .allMaxBy { it.validity() } - .toList() - return when (bestMatches.size) { - // This can happen if what we're deserializing is completely - // incompatible with all the possible variants (e.g. deserializing - // from object). - 0 -> NEpochs(_json = json) - 1 -> bestMatches.single() - // If there's more than one match with the highest validity, then - // use the first completely valid match, or simply the first match - // if none are completely valid. - else -> - bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() - } - } - } - - internal class Serializer : BaseSerializer(NEpochs::class) { - - override fun serialize( - value: NEpochs, - generator: JsonGenerator, - provider: SerializerProvider, - ) { - when { - value.auto != null -> generator.writeObject(value.auto) - value.manual != null -> generator.writeObject(value.manual) - value._json != null -> generator.writeObject(value._json) - else -> throw IllegalStateException("Invalid NEpochs") - } - } - } - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is Hyperparameters && batchSize == other.batchSize && learningRateMultiplier == other.learningRateMultiplier && nEpochs == other.nEpochs && additionalProperties == other.additionalProperties /* spotless:on */ - } - - /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(batchSize, learningRateMultiplier, nEpochs, additionalProperties) } - /* spotless:on */ - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Hyperparameters{batchSize=$batchSize, learningRateMultiplier=$learningRateMultiplier, nEpochs=$nEpochs, additionalProperties=$additionalProperties}" - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return /* spotless:off */ other is Supervised && hyperparameters == other.hyperparameters && additionalProperties == other.additionalProperties /* spotless:on */ - } - - /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(hyperparameters, additionalProperties) } - /* spotless:on */ - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Supervised{hyperparameters=$hyperparameters, additionalProperties=$additionalProperties}" - } - - /** The type of method. Is either `supervised` or `dpo`. */ - class Type @JsonCreator private constructor(private val value: JsonField) : Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that doesn't - * match any known member, and you want to know that value. For example, if the SDK is - * on an older version than the API, then the API may respond with new members that the - * SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val SUPERVISED = of("supervised") - - @JvmField val DPO = of("dpo") + @JvmField val REINFORCEMENT = of("reinforcement") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } @@ -5290,6 +3123,7 @@ private constructor( enum class Known { SUPERVISED, DPO, + REINFORCEMENT, } /** @@ -5304,6 +3138,7 @@ private constructor( enum class Value { SUPERVISED, DPO, + REINFORCEMENT, /** An enum member indicating that [Type] was instantiated with an unknown value. */ _UNKNOWN, } @@ -5319,6 +3154,7 @@ private constructor( when (this) { SUPERVISED -> Value.SUPERVISED DPO -> Value.DPO + REINFORCEMENT -> Value.REINFORCEMENT else -> Value._UNKNOWN } @@ -5335,6 +3171,7 @@ private constructor( when (this) { SUPERVISED -> Known.SUPERVISED DPO -> Known.DPO + REINFORCEMENT -> Known.REINFORCEMENT else -> throw OpenAIInvalidDataException("Unknown Type: $value") } @@ -5397,17 +3234,17 @@ private constructor( return true } - return /* spotless:off */ other is Method && dpo == other.dpo && supervised == other.supervised && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ + return /* spotless:off */ other is Method && type == other.type && dpo == other.dpo && reinforcement == other.reinforcement && supervised == other.supervised && additionalProperties == other.additionalProperties /* spotless:on */ } /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(dpo, supervised, type, additionalProperties) } + private val hashCode: Int by lazy { Objects.hash(type, dpo, reinforcement, supervised, additionalProperties) } /* spotless:on */ override fun hashCode(): Int = hashCode override fun toString() = - "Method{dpo=$dpo, supervised=$supervised, type=$type, additionalProperties=$additionalProperties}" + "Method{type=$type, dpo=$dpo, reinforcement=$reinforcement, supervised=$supervised, additionalProperties=$additionalProperties}" } override fun equals(other: Any?): Boolean { diff --git a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobListEventsPage.kt b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobListEventsPage.kt index 7acc932f..2a93a6c8 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobListEventsPage.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobListEventsPage.kt @@ -2,12 +2,12 @@ package com.openai.models.finetuning.jobs +import com.openai.core.AutoPager +import com.openai.core.Page import com.openai.core.checkRequired import com.openai.services.blocking.finetuning.JobService import java.util.Objects import java.util.Optional -import java.util.stream.Stream -import java.util.stream.StreamSupport import kotlin.jvm.optionals.getOrNull /** @see [JobService.listEvents] */ @@ -16,7 +16,7 @@ private constructor( private val service: JobService, private val params: JobListEventsParams, private val response: JobListEventsPageResponse, -) { +) : Page { /** * Delegates to [JobListEventsPageResponse], but gracefully handles missing data. @@ -33,20 +33,16 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): JobListEventsParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): Optional = - getNextPageParams().map { service.listEvents(it) } + override fun nextPage(): JobListEventsPage = service.listEvents(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPager = AutoPager.from(this) /** The parameters that were used to request this page. */ fun params(): JobListEventsParams = params @@ -115,25 +111,6 @@ private constructor( ) } - class AutoPager(private val firstPage: JobListEventsPage) : Iterable { - - override fun iterator(): Iterator = iterator { - var page = firstPage - var index = 0 - while (true) { - while (index < page.data().size) { - yield(page.data()[index++]) - } - page = page.getNextPage().getOrNull() ?: break - index = 0 - } - } - - fun stream(): Stream { - return StreamSupport.stream(spliterator(), false) - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobListEventsPageAsync.kt b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobListEventsPageAsync.kt index eceb1568..2dc4a3e2 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobListEventsPageAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobListEventsPageAsync.kt @@ -2,22 +2,24 @@ package com.openai.models.finetuning.jobs +import com.openai.core.AutoPagerAsync +import com.openai.core.PageAsync import com.openai.core.checkRequired import com.openai.services.async.finetuning.JobServiceAsync import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor -import java.util.function.Predicate import kotlin.jvm.optionals.getOrNull /** @see [JobServiceAsync.listEvents] */ class JobListEventsPageAsync private constructor( private val service: JobServiceAsync, + private val streamHandlerExecutor: Executor, private val params: JobListEventsParams, private val response: JobListEventsPageResponse, -) { +) : PageAsync { /** * Delegates to [JobListEventsPageResponse], but gracefully handles missing data. @@ -34,22 +36,18 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): JobListEventsParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): CompletableFuture> = - getNextPageParams() - .map { service.listEvents(it).thenApply { Optional.of(it) } } - .orElseGet { CompletableFuture.completedFuture(Optional.empty()) } + override fun nextPage(): CompletableFuture = + service.listEvents(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPagerAsync = + AutoPagerAsync.from(this, streamHandlerExecutor) /** The parameters that were used to request this page. */ fun params(): JobListEventsParams = params @@ -67,6 +65,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -78,18 +77,24 @@ private constructor( class Builder internal constructor() { private var service: JobServiceAsync? = null + private var streamHandlerExecutor: Executor? = null private var params: JobListEventsParams? = null private var response: JobListEventsPageResponse? = null @JvmSynthetic internal fun from(jobListEventsPageAsync: JobListEventsPageAsync) = apply { service = jobListEventsPageAsync.service + streamHandlerExecutor = jobListEventsPageAsync.streamHandlerExecutor params = jobListEventsPageAsync.params response = jobListEventsPageAsync.response } fun service(service: JobServiceAsync) = apply { this.service = service } + fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply { + this.streamHandlerExecutor = streamHandlerExecutor + } + /** The parameters that were used to request this page. */ fun params(params: JobListEventsParams) = apply { this.params = params } @@ -104,6 +109,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -113,50 +119,22 @@ private constructor( fun build(): JobListEventsPageAsync = JobListEventsPageAsync( checkRequired("service", service), + checkRequired("streamHandlerExecutor", streamHandlerExecutor), checkRequired("params", params), checkRequired("response", response), ) } - class AutoPager(private val firstPage: JobListEventsPageAsync) { - - fun forEach( - action: Predicate, - executor: Executor, - ): CompletableFuture { - fun CompletableFuture>.forEach( - action: (FineTuningJobEvent) -> Boolean, - executor: Executor, - ): CompletableFuture = - thenComposeAsync( - { page -> - page - .filter { it.data().all(action) } - .map { it.getNextPage().forEach(action, executor) } - .orElseGet { CompletableFuture.completedFuture(null) } - }, - executor, - ) - return CompletableFuture.completedFuture(Optional.of(firstPage)) - .forEach(action::test, executor) - } - - fun toList(executor: Executor): CompletableFuture> { - val values = mutableListOf() - return forEach(values::add, executor).thenApply { values } - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return /* spotless:off */ other is JobListEventsPageAsync && service == other.service && params == other.params && response == other.response /* spotless:on */ + return /* spotless:off */ other is JobListEventsPageAsync && service == other.service && streamHandlerExecutor == other.streamHandlerExecutor && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, params, response) /* spotless:on */ + override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, streamHandlerExecutor, params, response) /* spotless:on */ override fun toString() = - "JobListEventsPageAsync{service=$service, params=$params, response=$response}" + "JobListEventsPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, response=$response}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobListEventsParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobListEventsParams.kt index 26348572..1922578d 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobListEventsParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobListEventsParams.kt @@ -3,7 +3,6 @@ package com.openai.models.finetuning.jobs import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import java.util.Objects @@ -13,14 +12,14 @@ import kotlin.jvm.optionals.getOrNull /** Get status updates for a fine-tuning job. */ class JobListEventsParams private constructor( - private val fineTuningJobId: String, + private val fineTuningJobId: String?, private val after: String?, private val limit: Long?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun fineTuningJobId(): String = fineTuningJobId + fun fineTuningJobId(): Optional = Optional.ofNullable(fineTuningJobId) /** Identifier for the last event from the previous pagination request. */ fun after(): Optional = Optional.ofNullable(after) @@ -36,14 +35,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [JobListEventsParams]. - * - * The following fields are required: - * ```java - * .fineTuningJobId() - * ``` - */ + @JvmStatic fun none(): JobListEventsParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [JobListEventsParams]. */ @JvmStatic fun builder() = Builder() } @@ -65,10 +59,14 @@ private constructor( additionalQueryParams = jobListEventsParams.additionalQueryParams.toBuilder() } - fun fineTuningJobId(fineTuningJobId: String) = apply { + fun fineTuningJobId(fineTuningJobId: String?) = apply { this.fineTuningJobId = fineTuningJobId } + /** Alias for calling [Builder.fineTuningJobId] with `fineTuningJobId.orElse(null)`. */ + fun fineTuningJobId(fineTuningJobId: Optional) = + fineTuningJobId(fineTuningJobId.getOrNull()) + /** Identifier for the last event from the previous pagination request. */ fun after(after: String?) = apply { this.after = after } @@ -190,17 +188,10 @@ private constructor( * Returns an immutable instance of [JobListEventsParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .fineTuningJobId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): JobListEventsParams = JobListEventsParams( - checkRequired("fineTuningJobId", fineTuningJobId), + fineTuningJobId, after, limit, additionalHeaders.build(), @@ -210,7 +201,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> fineTuningJobId + 0 -> fineTuningJobId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobListPage.kt b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobListPage.kt index db6bcab0..7ed9ed47 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobListPage.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobListPage.kt @@ -2,12 +2,12 @@ package com.openai.models.finetuning.jobs +import com.openai.core.AutoPager +import com.openai.core.Page import com.openai.core.checkRequired import com.openai.services.blocking.finetuning.JobService import java.util.Objects import java.util.Optional -import java.util.stream.Stream -import java.util.stream.StreamSupport import kotlin.jvm.optionals.getOrNull /** @see [JobService.list] */ @@ -16,7 +16,7 @@ private constructor( private val service: JobService, private val params: JobListParams, private val response: JobListPageResponse, -) { +) : Page { /** * Delegates to [JobListPageResponse], but gracefully handles missing data. @@ -33,19 +33,16 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): JobListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): Optional = getNextPageParams().map { service.list(it) } + override fun nextPage(): JobListPage = service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPager = AutoPager.from(this) /** The parameters that were used to request this page. */ fun params(): JobListParams = params @@ -114,25 +111,6 @@ private constructor( ) } - class AutoPager(private val firstPage: JobListPage) : Iterable { - - override fun iterator(): Iterator = iterator { - var page = firstPage - var index = 0 - while (true) { - while (index < page.data().size) { - yield(page.data()[index++]) - } - page = page.getNextPage().getOrNull() ?: break - index = 0 - } - } - - fun stream(): Stream { - return StreamSupport.stream(spliterator(), false) - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobListPageAsync.kt b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobListPageAsync.kt index 7730d220..5860505d 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobListPageAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobListPageAsync.kt @@ -2,22 +2,24 @@ package com.openai.models.finetuning.jobs +import com.openai.core.AutoPagerAsync +import com.openai.core.PageAsync import com.openai.core.checkRequired import com.openai.services.async.finetuning.JobServiceAsync import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor -import java.util.function.Predicate import kotlin.jvm.optionals.getOrNull /** @see [JobServiceAsync.list] */ class JobListPageAsync private constructor( private val service: JobServiceAsync, + private val streamHandlerExecutor: Executor, private val params: JobListParams, private val response: JobListPageResponse, -) { +) : PageAsync { /** * Delegates to [JobListPageResponse], but gracefully handles missing data. @@ -34,22 +36,17 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): JobListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): CompletableFuture> = - getNextPageParams() - .map { service.list(it).thenApply { Optional.of(it) } } - .orElseGet { CompletableFuture.completedFuture(Optional.empty()) } + override fun nextPage(): CompletableFuture = service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPagerAsync = + AutoPagerAsync.from(this, streamHandlerExecutor) /** The parameters that were used to request this page. */ fun params(): JobListParams = params @@ -67,6 +64,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -78,18 +76,24 @@ private constructor( class Builder internal constructor() { private var service: JobServiceAsync? = null + private var streamHandlerExecutor: Executor? = null private var params: JobListParams? = null private var response: JobListPageResponse? = null @JvmSynthetic internal fun from(jobListPageAsync: JobListPageAsync) = apply { service = jobListPageAsync.service + streamHandlerExecutor = jobListPageAsync.streamHandlerExecutor params = jobListPageAsync.params response = jobListPageAsync.response } fun service(service: JobServiceAsync) = apply { this.service = service } + fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply { + this.streamHandlerExecutor = streamHandlerExecutor + } + /** The parameters that were used to request this page. */ fun params(params: JobListParams) = apply { this.params = params } @@ -104,6 +108,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -113,47 +118,22 @@ private constructor( fun build(): JobListPageAsync = JobListPageAsync( checkRequired("service", service), + checkRequired("streamHandlerExecutor", streamHandlerExecutor), checkRequired("params", params), checkRequired("response", response), ) } - class AutoPager(private val firstPage: JobListPageAsync) { - - fun forEach(action: Predicate, executor: Executor): CompletableFuture { - fun CompletableFuture>.forEach( - action: (FineTuningJob) -> Boolean, - executor: Executor, - ): CompletableFuture = - thenComposeAsync( - { page -> - page - .filter { it.data().all(action) } - .map { it.getNextPage().forEach(action, executor) } - .orElseGet { CompletableFuture.completedFuture(null) } - }, - executor, - ) - return CompletableFuture.completedFuture(Optional.of(firstPage)) - .forEach(action::test, executor) - } - - fun toList(executor: Executor): CompletableFuture> { - val values = mutableListOf() - return forEach(values::add, executor).thenApply { values } - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return /* spotless:off */ other is JobListPageAsync && service == other.service && params == other.params && response == other.response /* spotless:on */ + return /* spotless:off */ other is JobListPageAsync && service == other.service && streamHandlerExecutor == other.streamHandlerExecutor && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, params, response) /* spotless:on */ + override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, streamHandlerExecutor, params, response) /* spotless:on */ override fun toString() = - "JobListPageAsync{service=$service, params=$params, response=$response}" + "JobListPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, response=$response}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobPauseParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobPauseParams.kt new file mode 100644 index 00000000..d4cc700b --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobPauseParams.kt @@ -0,0 +1,224 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.finetuning.jobs + +import com.openai.core.JsonValue +import com.openai.core.Params +import com.openai.core.http.Headers +import com.openai.core.http.QueryParams +import com.openai.core.toImmutable +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Pause a fine-tune job. */ +class JobPauseParams +private constructor( + private val fineTuningJobId: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, + private val additionalBodyProperties: Map, +) : Params { + + fun fineTuningJobId(): Optional = Optional.ofNullable(fineTuningJobId) + + fun _additionalBodyProperties(): Map = additionalBodyProperties + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + @JvmStatic fun none(): JobPauseParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [JobPauseParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [JobPauseParams]. */ + class Builder internal constructor() { + + private var fineTuningJobId: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + private var additionalBodyProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(jobPauseParams: JobPauseParams) = apply { + fineTuningJobId = jobPauseParams.fineTuningJobId + additionalHeaders = jobPauseParams.additionalHeaders.toBuilder() + additionalQueryParams = jobPauseParams.additionalQueryParams.toBuilder() + additionalBodyProperties = jobPauseParams.additionalBodyProperties.toMutableMap() + } + + fun fineTuningJobId(fineTuningJobId: String?) = apply { + this.fineTuningJobId = fineTuningJobId + } + + /** Alias for calling [Builder.fineTuningJobId] with `fineTuningJobId.orElse(null)`. */ + fun fineTuningJobId(fineTuningJobId: Optional) = + fineTuningJobId(fineTuningJobId.getOrNull()) + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) + } + + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } + + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } + + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } + + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } + + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } + + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + this.additionalBodyProperties.clear() + putAllAdditionalBodyProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + additionalBodyProperties.put(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + this.additionalBodyProperties.putAll(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { + additionalBodyProperties.remove(key) + } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalBodyProperty) + } + + /** + * Returns an immutable instance of [JobPauseParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): JobPauseParams = + JobPauseParams( + fineTuningJobId, + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), + ) + } + + fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) + + fun _pathParam(index: Int): String = + when (index) { + 0 -> fineTuningJobId ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is JobPauseParams && fineTuningJobId == other.fineTuningJobId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams && additionalBodyProperties == other.additionalBodyProperties /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(fineTuningJobId, additionalHeaders, additionalQueryParams, additionalBodyProperties) /* spotless:on */ + + override fun toString() = + "JobPauseParams{fineTuningJobId=$fineTuningJobId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobResumeParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobResumeParams.kt new file mode 100644 index 00000000..97f214e3 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobResumeParams.kt @@ -0,0 +1,224 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.finetuning.jobs + +import com.openai.core.JsonValue +import com.openai.core.Params +import com.openai.core.http.Headers +import com.openai.core.http.QueryParams +import com.openai.core.toImmutable +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Resume a fine-tune job. */ +class JobResumeParams +private constructor( + private val fineTuningJobId: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, + private val additionalBodyProperties: Map, +) : Params { + + fun fineTuningJobId(): Optional = Optional.ofNullable(fineTuningJobId) + + fun _additionalBodyProperties(): Map = additionalBodyProperties + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + @JvmStatic fun none(): JobResumeParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [JobResumeParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [JobResumeParams]. */ + class Builder internal constructor() { + + private var fineTuningJobId: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + private var additionalBodyProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(jobResumeParams: JobResumeParams) = apply { + fineTuningJobId = jobResumeParams.fineTuningJobId + additionalHeaders = jobResumeParams.additionalHeaders.toBuilder() + additionalQueryParams = jobResumeParams.additionalQueryParams.toBuilder() + additionalBodyProperties = jobResumeParams.additionalBodyProperties.toMutableMap() + } + + fun fineTuningJobId(fineTuningJobId: String?) = apply { + this.fineTuningJobId = fineTuningJobId + } + + /** Alias for calling [Builder.fineTuningJobId] with `fineTuningJobId.orElse(null)`. */ + fun fineTuningJobId(fineTuningJobId: Optional) = + fineTuningJobId(fineTuningJobId.getOrNull()) + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) + } + + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } + + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } + + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } + + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } + + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } + + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + this.additionalBodyProperties.clear() + putAllAdditionalBodyProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + additionalBodyProperties.put(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + this.additionalBodyProperties.putAll(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { + additionalBodyProperties.remove(key) + } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalBodyProperty) + } + + /** + * Returns an immutable instance of [JobResumeParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): JobResumeParams = + JobResumeParams( + fineTuningJobId, + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), + ) + } + + fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) + + fun _pathParam(index: Int): String = + when (index) { + 0 -> fineTuningJobId ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is JobResumeParams && fineTuningJobId == other.fineTuningJobId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams && additionalBodyProperties == other.additionalBodyProperties /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(fineTuningJobId, additionalHeaders, additionalQueryParams, additionalBodyProperties) /* spotless:on */ + + override fun toString() = + "JobResumeParams{fineTuningJobId=$fineTuningJobId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobRetrieveParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobRetrieveParams.kt index 2e5e2874..3a5e0814 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobRetrieveParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/JobRetrieveParams.kt @@ -3,10 +3,11 @@ package com.openai.models.finetuning.jobs import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** * Get info about a fine-tuning job. @@ -15,12 +16,12 @@ import java.util.Objects */ class JobRetrieveParams private constructor( - private val fineTuningJobId: String, + private val fineTuningJobId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun fineTuningJobId(): String = fineTuningJobId + fun fineTuningJobId(): Optional = Optional.ofNullable(fineTuningJobId) fun _additionalHeaders(): Headers = additionalHeaders @@ -30,14 +31,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [JobRetrieveParams]. - * - * The following fields are required: - * ```java - * .fineTuningJobId() - * ``` - */ + @JvmStatic fun none(): JobRetrieveParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [JobRetrieveParams]. */ @JvmStatic fun builder() = Builder() } @@ -55,10 +51,14 @@ private constructor( additionalQueryParams = jobRetrieveParams.additionalQueryParams.toBuilder() } - fun fineTuningJobId(fineTuningJobId: String) = apply { + fun fineTuningJobId(fineTuningJobId: String?) = apply { this.fineTuningJobId = fineTuningJobId } + /** Alias for calling [Builder.fineTuningJobId] with `fineTuningJobId.orElse(null)`. */ + fun fineTuningJobId(fineTuningJobId: Optional) = + fineTuningJobId(fineTuningJobId.getOrNull()) + fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() putAllAdditionalHeaders(additionalHeaders) @@ -161,17 +161,10 @@ private constructor( * Returns an immutable instance of [JobRetrieveParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .fineTuningJobId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): JobRetrieveParams = JobRetrieveParams( - checkRequired("fineTuningJobId", fineTuningJobId), + fineTuningJobId, additionalHeaders.build(), additionalQueryParams.build(), ) @@ -179,7 +172,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> fineTuningJobId + 0 -> fineTuningJobId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/checkpoints/CheckpointListPage.kt b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/checkpoints/CheckpointListPage.kt index 64c6ce8b..e5df9890 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/checkpoints/CheckpointListPage.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/checkpoints/CheckpointListPage.kt @@ -2,12 +2,12 @@ package com.openai.models.finetuning.jobs.checkpoints +import com.openai.core.AutoPager +import com.openai.core.Page import com.openai.core.checkRequired import com.openai.services.blocking.finetuning.jobs.CheckpointService import java.util.Objects import java.util.Optional -import java.util.stream.Stream -import java.util.stream.StreamSupport import kotlin.jvm.optionals.getOrNull /** @see [CheckpointService.list] */ @@ -16,7 +16,7 @@ private constructor( private val service: CheckpointService, private val params: CheckpointListParams, private val response: CheckpointListPageResponse, -) { +) : Page { /** * Delegates to [CheckpointListPageResponse], but gracefully handles missing data. @@ -33,19 +33,16 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): CheckpointListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): Optional = getNextPageParams().map { service.list(it) } + override fun nextPage(): CheckpointListPage = service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPager = AutoPager.from(this) /** The parameters that were used to request this page. */ fun params(): CheckpointListParams = params @@ -114,25 +111,6 @@ private constructor( ) } - class AutoPager(private val firstPage: CheckpointListPage) : Iterable { - - override fun iterator(): Iterator = iterator { - var page = firstPage - var index = 0 - while (true) { - while (index < page.data().size) { - yield(page.data()[index++]) - } - page = page.getNextPage().getOrNull() ?: break - index = 0 - } - } - - fun stream(): Stream { - return StreamSupport.stream(spliterator(), false) - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/checkpoints/CheckpointListPageAsync.kt b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/checkpoints/CheckpointListPageAsync.kt index b5812ee7..4c377a56 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/checkpoints/CheckpointListPageAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/checkpoints/CheckpointListPageAsync.kt @@ -2,22 +2,24 @@ package com.openai.models.finetuning.jobs.checkpoints +import com.openai.core.AutoPagerAsync +import com.openai.core.PageAsync import com.openai.core.checkRequired import com.openai.services.async.finetuning.jobs.CheckpointServiceAsync import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor -import java.util.function.Predicate import kotlin.jvm.optionals.getOrNull /** @see [CheckpointServiceAsync.list] */ class CheckpointListPageAsync private constructor( private val service: CheckpointServiceAsync, + private val streamHandlerExecutor: Executor, private val params: CheckpointListParams, private val response: CheckpointListPageResponse, -) { +) : PageAsync { /** * Delegates to [CheckpointListPageResponse], but gracefully handles missing data. @@ -34,22 +36,18 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): CheckpointListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): CompletableFuture> = - getNextPageParams() - .map { service.list(it).thenApply { Optional.of(it) } } - .orElseGet { CompletableFuture.completedFuture(Optional.empty()) } + override fun nextPage(): CompletableFuture = + service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPagerAsync = + AutoPagerAsync.from(this, streamHandlerExecutor) /** The parameters that were used to request this page. */ fun params(): CheckpointListParams = params @@ -67,6 +65,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -78,18 +77,24 @@ private constructor( class Builder internal constructor() { private var service: CheckpointServiceAsync? = null + private var streamHandlerExecutor: Executor? = null private var params: CheckpointListParams? = null private var response: CheckpointListPageResponse? = null @JvmSynthetic internal fun from(checkpointListPageAsync: CheckpointListPageAsync) = apply { service = checkpointListPageAsync.service + streamHandlerExecutor = checkpointListPageAsync.streamHandlerExecutor params = checkpointListPageAsync.params response = checkpointListPageAsync.response } fun service(service: CheckpointServiceAsync) = apply { this.service = service } + fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply { + this.streamHandlerExecutor = streamHandlerExecutor + } + /** The parameters that were used to request this page. */ fun params(params: CheckpointListParams) = apply { this.params = params } @@ -104,6 +109,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -113,50 +119,22 @@ private constructor( fun build(): CheckpointListPageAsync = CheckpointListPageAsync( checkRequired("service", service), + checkRequired("streamHandlerExecutor", streamHandlerExecutor), checkRequired("params", params), checkRequired("response", response), ) } - class AutoPager(private val firstPage: CheckpointListPageAsync) { - - fun forEach( - action: Predicate, - executor: Executor, - ): CompletableFuture { - fun CompletableFuture>.forEach( - action: (FineTuningJobCheckpoint) -> Boolean, - executor: Executor, - ): CompletableFuture = - thenComposeAsync( - { page -> - page - .filter { it.data().all(action) } - .map { it.getNextPage().forEach(action, executor) } - .orElseGet { CompletableFuture.completedFuture(null) } - }, - executor, - ) - return CompletableFuture.completedFuture(Optional.of(firstPage)) - .forEach(action::test, executor) - } - - fun toList(executor: Executor): CompletableFuture> { - val values = mutableListOf() - return forEach(values::add, executor).thenApply { values } - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return /* spotless:off */ other is CheckpointListPageAsync && service == other.service && params == other.params && response == other.response /* spotless:on */ + return /* spotless:off */ other is CheckpointListPageAsync && service == other.service && streamHandlerExecutor == other.streamHandlerExecutor && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, params, response) /* spotless:on */ + override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, streamHandlerExecutor, params, response) /* spotless:on */ override fun toString() = - "CheckpointListPageAsync{service=$service, params=$params, response=$response}" + "CheckpointListPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, response=$response}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/checkpoints/CheckpointListParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/checkpoints/CheckpointListParams.kt index 917d0458..46483d0c 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/checkpoints/CheckpointListParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/jobs/checkpoints/CheckpointListParams.kt @@ -3,7 +3,6 @@ package com.openai.models.finetuning.jobs.checkpoints import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import java.util.Objects @@ -13,14 +12,14 @@ import kotlin.jvm.optionals.getOrNull /** List checkpoints for a fine-tuning job. */ class CheckpointListParams private constructor( - private val fineTuningJobId: String, + private val fineTuningJobId: String?, private val after: String?, private val limit: Long?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun fineTuningJobId(): String = fineTuningJobId + fun fineTuningJobId(): Optional = Optional.ofNullable(fineTuningJobId) /** Identifier for the last checkpoint ID from the previous pagination request. */ fun after(): Optional = Optional.ofNullable(after) @@ -36,14 +35,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [CheckpointListParams]. - * - * The following fields are required: - * ```java - * .fineTuningJobId() - * ``` - */ + @JvmStatic fun none(): CheckpointListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [CheckpointListParams]. */ @JvmStatic fun builder() = Builder() } @@ -65,10 +59,14 @@ private constructor( additionalQueryParams = checkpointListParams.additionalQueryParams.toBuilder() } - fun fineTuningJobId(fineTuningJobId: String) = apply { + fun fineTuningJobId(fineTuningJobId: String?) = apply { this.fineTuningJobId = fineTuningJobId } + /** Alias for calling [Builder.fineTuningJobId] with `fineTuningJobId.orElse(null)`. */ + fun fineTuningJobId(fineTuningJobId: Optional) = + fineTuningJobId(fineTuningJobId.getOrNull()) + /** Identifier for the last checkpoint ID from the previous pagination request. */ fun after(after: String?) = apply { this.after = after } @@ -190,17 +188,10 @@ private constructor( * Returns an immutable instance of [CheckpointListParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .fineTuningJobId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): CheckpointListParams = CheckpointListParams( - checkRequired("fineTuningJobId", fineTuningJobId), + fineTuningJobId, after, limit, additionalHeaders.build(), @@ -210,7 +201,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> fineTuningJobId + 0 -> fineTuningJobId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/methods/DpoHyperparameters.kt b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/methods/DpoHyperparameters.kt new file mode 100644 index 00000000..e3c8b5c3 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/methods/DpoHyperparameters.kt @@ -0,0 +1,1050 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.finetuning.methods + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.BaseDeserializer +import com.openai.core.BaseSerializer +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.allMaxBy +import com.openai.core.getOrThrow +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** The hyperparameters used for the DPO fine-tuning job. */ +class DpoHyperparameters +private constructor( + private val batchSize: JsonField, + private val beta: JsonField, + private val learningRateMultiplier: JsonField, + private val nEpochs: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("batch_size") + @ExcludeMissing + batchSize: JsonField = JsonMissing.of(), + @JsonProperty("beta") @ExcludeMissing beta: JsonField = JsonMissing.of(), + @JsonProperty("learning_rate_multiplier") + @ExcludeMissing + learningRateMultiplier: JsonField = JsonMissing.of(), + @JsonProperty("n_epochs") @ExcludeMissing nEpochs: JsonField = JsonMissing.of(), + ) : this(batchSize, beta, learningRateMultiplier, nEpochs, mutableMapOf()) + + /** + * Number of examples in each batch. A larger batch size means that model parameters are updated + * less frequently, but with lower variance. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun batchSize(): Optional = batchSize.getOptional("batch_size") + + /** + * The beta value for the DPO method. A higher beta value will increase the weight of the + * penalty between the policy and reference model. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun beta(): Optional = beta.getOptional("beta") + + /** + * Scaling factor for the learning rate. A smaller learning rate may be useful to avoid + * overfitting. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun learningRateMultiplier(): Optional = + learningRateMultiplier.getOptional("learning_rate_multiplier") + + /** + * The number of epochs to train the model for. An epoch refers to one full cycle through the + * training dataset. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun nEpochs(): Optional = nEpochs.getOptional("n_epochs") + + /** + * Returns the raw JSON value of [batchSize]. + * + * Unlike [batchSize], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("batch_size") @ExcludeMissing fun _batchSize(): JsonField = batchSize + + /** + * Returns the raw JSON value of [beta]. + * + * Unlike [beta], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("beta") @ExcludeMissing fun _beta(): JsonField = beta + + /** + * Returns the raw JSON value of [learningRateMultiplier]. + * + * Unlike [learningRateMultiplier], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("learning_rate_multiplier") + @ExcludeMissing + fun _learningRateMultiplier(): JsonField = learningRateMultiplier + + /** + * Returns the raw JSON value of [nEpochs]. + * + * Unlike [nEpochs], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("n_epochs") @ExcludeMissing fun _nEpochs(): JsonField = nEpochs + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [DpoHyperparameters]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [DpoHyperparameters]. */ + class Builder internal constructor() { + + private var batchSize: JsonField = JsonMissing.of() + private var beta: JsonField = JsonMissing.of() + private var learningRateMultiplier: JsonField = JsonMissing.of() + private var nEpochs: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(dpoHyperparameters: DpoHyperparameters) = apply { + batchSize = dpoHyperparameters.batchSize + beta = dpoHyperparameters.beta + learningRateMultiplier = dpoHyperparameters.learningRateMultiplier + nEpochs = dpoHyperparameters.nEpochs + additionalProperties = dpoHyperparameters.additionalProperties.toMutableMap() + } + + /** + * Number of examples in each batch. A larger batch size means that model parameters are + * updated less frequently, but with lower variance. + */ + fun batchSize(batchSize: BatchSize) = batchSize(JsonField.of(batchSize)) + + /** + * Sets [Builder.batchSize] to an arbitrary JSON value. + * + * You should usually call [Builder.batchSize] with a well-typed [BatchSize] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun batchSize(batchSize: JsonField) = apply { this.batchSize = batchSize } + + /** Alias for calling [batchSize] with `BatchSize.ofAuto()`. */ + fun batchSizeAuto() = batchSize(BatchSize.ofAuto()) + + /** Alias for calling [batchSize] with `BatchSize.ofInteger(integer)`. */ + fun batchSize(integer: Long) = batchSize(BatchSize.ofInteger(integer)) + + /** + * The beta value for the DPO method. A higher beta value will increase the weight of the + * penalty between the policy and reference model. + */ + fun beta(beta: Beta) = beta(JsonField.of(beta)) + + /** + * Sets [Builder.beta] to an arbitrary JSON value. + * + * You should usually call [Builder.beta] with a well-typed [Beta] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun beta(beta: JsonField) = apply { this.beta = beta } + + /** Alias for calling [beta] with `Beta.ofAuto()`. */ + fun betaAuto() = beta(Beta.ofAuto()) + + /** Alias for calling [beta] with `Beta.ofNumber(number)`. */ + fun beta(number: Double) = beta(Beta.ofNumber(number)) + + /** + * Scaling factor for the learning rate. A smaller learning rate may be useful to avoid + * overfitting. + */ + fun learningRateMultiplier(learningRateMultiplier: LearningRateMultiplier) = + learningRateMultiplier(JsonField.of(learningRateMultiplier)) + + /** + * Sets [Builder.learningRateMultiplier] to an arbitrary JSON value. + * + * You should usually call [Builder.learningRateMultiplier] with a well-typed + * [LearningRateMultiplier] value instead. This method is primarily for setting the field to + * an undocumented or not yet supported value. + */ + fun learningRateMultiplier(learningRateMultiplier: JsonField) = + apply { + this.learningRateMultiplier = learningRateMultiplier + } + + /** Alias for calling [learningRateMultiplier] with `LearningRateMultiplier.ofAuto()`. */ + fun learningRateMultiplierAuto() = learningRateMultiplier(LearningRateMultiplier.ofAuto()) + + /** + * Alias for calling [learningRateMultiplier] with + * `LearningRateMultiplier.ofNumber(number)`. + */ + fun learningRateMultiplier(number: Double) = + learningRateMultiplier(LearningRateMultiplier.ofNumber(number)) + + /** + * The number of epochs to train the model for. An epoch refers to one full cycle through + * the training dataset. + */ + fun nEpochs(nEpochs: NEpochs) = nEpochs(JsonField.of(nEpochs)) + + /** + * Sets [Builder.nEpochs] to an arbitrary JSON value. + * + * You should usually call [Builder.nEpochs] with a well-typed [NEpochs] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun nEpochs(nEpochs: JsonField) = apply { this.nEpochs = nEpochs } + + /** Alias for calling [nEpochs] with `NEpochs.ofAuto()`. */ + fun nEpochsAuto() = nEpochs(NEpochs.ofAuto()) + + /** Alias for calling [nEpochs] with `NEpochs.ofInteger(integer)`. */ + fun nEpochs(integer: Long) = nEpochs(NEpochs.ofInteger(integer)) + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [DpoHyperparameters]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): DpoHyperparameters = + DpoHyperparameters( + batchSize, + beta, + learningRateMultiplier, + nEpochs, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): DpoHyperparameters = apply { + if (validated) { + return@apply + } + + batchSize().ifPresent { it.validate() } + beta().ifPresent { it.validate() } + learningRateMultiplier().ifPresent { it.validate() } + nEpochs().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (batchSize.asKnown().getOrNull()?.validity() ?: 0) + + (beta.asKnown().getOrNull()?.validity() ?: 0) + + (learningRateMultiplier.asKnown().getOrNull()?.validity() ?: 0) + + (nEpochs.asKnown().getOrNull()?.validity() ?: 0) + + /** + * Number of examples in each batch. A larger batch size means that model parameters are updated + * less frequently, but with lower variance. + */ + @JsonDeserialize(using = BatchSize.Deserializer::class) + @JsonSerialize(using = BatchSize.Serializer::class) + class BatchSize + private constructor( + private val auto: JsonValue? = null, + private val integer: Long? = null, + private val _json: JsonValue? = null, + ) { + + fun auto(): Optional = Optional.ofNullable(auto) + + fun integer(): Optional = Optional.ofNullable(integer) + + fun isAuto(): Boolean = auto != null + + fun isInteger(): Boolean = integer != null + + fun asAuto(): JsonValue = auto.getOrThrow("auto") + + fun asInteger(): Long = integer.getOrThrow("integer") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + auto != null -> visitor.visitAuto(auto) + integer != null -> visitor.visitInteger(integer) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): BatchSize = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitAuto(auto: JsonValue) { + auto.let { + if (it != JsonValue.from("auto")) { + throw OpenAIInvalidDataException("'auto' is invalid, received $it") + } + } + } + + override fun visitInteger(integer: Long) {} + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitAuto(auto: JsonValue) = + auto.let { if (it == JsonValue.from("auto")) 1 else 0 } + + override fun visitInteger(integer: Long) = 1 + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is BatchSize && auto == other.auto && integer == other.integer /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(auto, integer) /* spotless:on */ + + override fun toString(): String = + when { + auto != null -> "BatchSize{auto=$auto}" + integer != null -> "BatchSize{integer=$integer}" + _json != null -> "BatchSize{_unknown=$_json}" + else -> throw IllegalStateException("Invalid BatchSize") + } + + companion object { + + @JvmStatic fun ofAuto() = BatchSize(auto = JsonValue.from("auto")) + + @JvmStatic fun ofInteger(integer: Long) = BatchSize(integer = integer) + } + + /** + * An interface that defines how to map each variant of [BatchSize] to a value of type [T]. + */ + interface Visitor { + + fun visitAuto(auto: JsonValue): T + + fun visitInteger(integer: Long): T + + /** + * Maps an unknown variant of [BatchSize] to a value of type [T]. + * + * An instance of [BatchSize] can contain an unknown variant if it was deserialized from + * data that doesn't match any known variant. For example, if the SDK is on an older + * version than the API, then the API may respond with new variants that the SDK is + * unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown BatchSize: $json") + } + } + + internal class Deserializer : BaseDeserializer(BatchSize::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): BatchSize { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef()) + ?.let { BatchSize(auto = it, _json = json) } + ?.takeIf { it.isValid() }, + tryDeserialize(node, jacksonTypeRef())?.let { + BatchSize(integer = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with + // all the possible variants (e.g. deserializing from object). + 0 -> BatchSize(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely + // valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(BatchSize::class) { + + override fun serialize( + value: BatchSize, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.auto != null -> generator.writeObject(value.auto) + value.integer != null -> generator.writeObject(value.integer) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid BatchSize") + } + } + } + } + + /** + * The beta value for the DPO method. A higher beta value will increase the weight of the + * penalty between the policy and reference model. + */ + @JsonDeserialize(using = Beta.Deserializer::class) + @JsonSerialize(using = Beta.Serializer::class) + class Beta + private constructor( + private val auto: JsonValue? = null, + private val number: Double? = null, + private val _json: JsonValue? = null, + ) { + + fun auto(): Optional = Optional.ofNullable(auto) + + fun number(): Optional = Optional.ofNullable(number) + + fun isAuto(): Boolean = auto != null + + fun isNumber(): Boolean = number != null + + fun asAuto(): JsonValue = auto.getOrThrow("auto") + + fun asNumber(): Double = number.getOrThrow("number") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + auto != null -> visitor.visitAuto(auto) + number != null -> visitor.visitNumber(number) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): Beta = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitAuto(auto: JsonValue) { + auto.let { + if (it != JsonValue.from("auto")) { + throw OpenAIInvalidDataException("'auto' is invalid, received $it") + } + } + } + + override fun visitNumber(number: Double) {} + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitAuto(auto: JsonValue) = + auto.let { if (it == JsonValue.from("auto")) 1 else 0 } + + override fun visitNumber(number: Double) = 1 + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Beta && auto == other.auto && number == other.number /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(auto, number) /* spotless:on */ + + override fun toString(): String = + when { + auto != null -> "Beta{auto=$auto}" + number != null -> "Beta{number=$number}" + _json != null -> "Beta{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Beta") + } + + companion object { + + @JvmStatic fun ofAuto() = Beta(auto = JsonValue.from("auto")) + + @JvmStatic fun ofNumber(number: Double) = Beta(number = number) + } + + /** An interface that defines how to map each variant of [Beta] to a value of type [T]. */ + interface Visitor { + + fun visitAuto(auto: JsonValue): T + + fun visitNumber(number: Double): T + + /** + * Maps an unknown variant of [Beta] to a value of type [T]. + * + * An instance of [Beta] can contain an unknown variant if it was deserialized from data + * that doesn't match any known variant. For example, if the SDK is on an older version + * than the API, then the API may respond with new variants that the SDK is unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown Beta: $json") + } + } + + internal class Deserializer : BaseDeserializer(Beta::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): Beta { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef()) + ?.let { Beta(auto = it, _json = json) } + ?.takeIf { it.isValid() }, + tryDeserialize(node, jacksonTypeRef())?.let { + Beta(number = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with + // all the possible variants (e.g. deserializing from object). + 0 -> Beta(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely + // valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(Beta::class) { + + override fun serialize( + value: Beta, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.auto != null -> generator.writeObject(value.auto) + value.number != null -> generator.writeObject(value.number) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Beta") + } + } + } + } + + /** + * Scaling factor for the learning rate. A smaller learning rate may be useful to avoid + * overfitting. + */ + @JsonDeserialize(using = LearningRateMultiplier.Deserializer::class) + @JsonSerialize(using = LearningRateMultiplier.Serializer::class) + class LearningRateMultiplier + private constructor( + private val auto: JsonValue? = null, + private val number: Double? = null, + private val _json: JsonValue? = null, + ) { + + fun auto(): Optional = Optional.ofNullable(auto) + + fun number(): Optional = Optional.ofNullable(number) + + fun isAuto(): Boolean = auto != null + + fun isNumber(): Boolean = number != null + + fun asAuto(): JsonValue = auto.getOrThrow("auto") + + fun asNumber(): Double = number.getOrThrow("number") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + auto != null -> visitor.visitAuto(auto) + number != null -> visitor.visitNumber(number) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): LearningRateMultiplier = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitAuto(auto: JsonValue) { + auto.let { + if (it != JsonValue.from("auto")) { + throw OpenAIInvalidDataException("'auto' is invalid, received $it") + } + } + } + + override fun visitNumber(number: Double) {} + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitAuto(auto: JsonValue) = + auto.let { if (it == JsonValue.from("auto")) 1 else 0 } + + override fun visitNumber(number: Double) = 1 + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is LearningRateMultiplier && auto == other.auto && number == other.number /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(auto, number) /* spotless:on */ + + override fun toString(): String = + when { + auto != null -> "LearningRateMultiplier{auto=$auto}" + number != null -> "LearningRateMultiplier{number=$number}" + _json != null -> "LearningRateMultiplier{_unknown=$_json}" + else -> throw IllegalStateException("Invalid LearningRateMultiplier") + } + + companion object { + + @JvmStatic fun ofAuto() = LearningRateMultiplier(auto = JsonValue.from("auto")) + + @JvmStatic fun ofNumber(number: Double) = LearningRateMultiplier(number = number) + } + + /** + * An interface that defines how to map each variant of [LearningRateMultiplier] to a value + * of type [T]. + */ + interface Visitor { + + fun visitAuto(auto: JsonValue): T + + fun visitNumber(number: Double): T + + /** + * Maps an unknown variant of [LearningRateMultiplier] to a value of type [T]. + * + * An instance of [LearningRateMultiplier] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For example, if the SDK + * is on an older version than the API, then the API may respond with new variants that + * the SDK is unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown LearningRateMultiplier: $json") + } + } + + internal class Deserializer : + BaseDeserializer(LearningRateMultiplier::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): LearningRateMultiplier { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef()) + ?.let { LearningRateMultiplier(auto = it, _json = json) } + ?.takeIf { it.isValid() }, + tryDeserialize(node, jacksonTypeRef())?.let { + LearningRateMultiplier(number = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with + // all the possible variants (e.g. deserializing from object). + 0 -> LearningRateMultiplier(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely + // valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : + BaseSerializer(LearningRateMultiplier::class) { + + override fun serialize( + value: LearningRateMultiplier, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.auto != null -> generator.writeObject(value.auto) + value.number != null -> generator.writeObject(value.number) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid LearningRateMultiplier") + } + } + } + } + + /** + * The number of epochs to train the model for. An epoch refers to one full cycle through the + * training dataset. + */ + @JsonDeserialize(using = NEpochs.Deserializer::class) + @JsonSerialize(using = NEpochs.Serializer::class) + class NEpochs + private constructor( + private val auto: JsonValue? = null, + private val integer: Long? = null, + private val _json: JsonValue? = null, + ) { + + fun auto(): Optional = Optional.ofNullable(auto) + + fun integer(): Optional = Optional.ofNullable(integer) + + fun isAuto(): Boolean = auto != null + + fun isInteger(): Boolean = integer != null + + fun asAuto(): JsonValue = auto.getOrThrow("auto") + + fun asInteger(): Long = integer.getOrThrow("integer") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + auto != null -> visitor.visitAuto(auto) + integer != null -> visitor.visitInteger(integer) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): NEpochs = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitAuto(auto: JsonValue) { + auto.let { + if (it != JsonValue.from("auto")) { + throw OpenAIInvalidDataException("'auto' is invalid, received $it") + } + } + } + + override fun visitInteger(integer: Long) {} + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitAuto(auto: JsonValue) = + auto.let { if (it == JsonValue.from("auto")) 1 else 0 } + + override fun visitInteger(integer: Long) = 1 + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is NEpochs && auto == other.auto && integer == other.integer /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(auto, integer) /* spotless:on */ + + override fun toString(): String = + when { + auto != null -> "NEpochs{auto=$auto}" + integer != null -> "NEpochs{integer=$integer}" + _json != null -> "NEpochs{_unknown=$_json}" + else -> throw IllegalStateException("Invalid NEpochs") + } + + companion object { + + @JvmStatic fun ofAuto() = NEpochs(auto = JsonValue.from("auto")) + + @JvmStatic fun ofInteger(integer: Long) = NEpochs(integer = integer) + } + + /** + * An interface that defines how to map each variant of [NEpochs] to a value of type [T]. + */ + interface Visitor { + + fun visitAuto(auto: JsonValue): T + + fun visitInteger(integer: Long): T + + /** + * Maps an unknown variant of [NEpochs] to a value of type [T]. + * + * An instance of [NEpochs] can contain an unknown variant if it was deserialized from + * data that doesn't match any known variant. For example, if the SDK is on an older + * version than the API, then the API may respond with new variants that the SDK is + * unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown NEpochs: $json") + } + } + + internal class Deserializer : BaseDeserializer(NEpochs::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): NEpochs { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef()) + ?.let { NEpochs(auto = it, _json = json) } + ?.takeIf { it.isValid() }, + tryDeserialize(node, jacksonTypeRef())?.let { + NEpochs(integer = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with + // all the possible variants (e.g. deserializing from object). + 0 -> NEpochs(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely + // valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(NEpochs::class) { + + override fun serialize( + value: NEpochs, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.auto != null -> generator.writeObject(value.auto) + value.integer != null -> generator.writeObject(value.integer) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid NEpochs") + } + } + } + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is DpoHyperparameters && batchSize == other.batchSize && beta == other.beta && learningRateMultiplier == other.learningRateMultiplier && nEpochs == other.nEpochs && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(batchSize, beta, learningRateMultiplier, nEpochs, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "DpoHyperparameters{batchSize=$batchSize, beta=$beta, learningRateMultiplier=$learningRateMultiplier, nEpochs=$nEpochs, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/methods/DpoMethod.kt b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/methods/DpoMethod.kt new file mode 100644 index 00000000..bc489634 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/methods/DpoMethod.kt @@ -0,0 +1,166 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.finetuning.methods + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Configuration for the DPO fine-tuning method. */ +class DpoMethod +private constructor( + private val hyperparameters: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("hyperparameters") + @ExcludeMissing + hyperparameters: JsonField = JsonMissing.of() + ) : this(hyperparameters, mutableMapOf()) + + /** + * The hyperparameters used for the DPO fine-tuning job. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun hyperparameters(): Optional = + hyperparameters.getOptional("hyperparameters") + + /** + * Returns the raw JSON value of [hyperparameters]. + * + * Unlike [hyperparameters], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("hyperparameters") + @ExcludeMissing + fun _hyperparameters(): JsonField = hyperparameters + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [DpoMethod]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [DpoMethod]. */ + class Builder internal constructor() { + + private var hyperparameters: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(dpoMethod: DpoMethod) = apply { + hyperparameters = dpoMethod.hyperparameters + additionalProperties = dpoMethod.additionalProperties.toMutableMap() + } + + /** The hyperparameters used for the DPO fine-tuning job. */ + fun hyperparameters(hyperparameters: DpoHyperparameters) = + hyperparameters(JsonField.of(hyperparameters)) + + /** + * Sets [Builder.hyperparameters] to an arbitrary JSON value. + * + * You should usually call [Builder.hyperparameters] with a well-typed [DpoHyperparameters] + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun hyperparameters(hyperparameters: JsonField) = apply { + this.hyperparameters = hyperparameters + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [DpoMethod]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): DpoMethod = DpoMethod(hyperparameters, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): DpoMethod = apply { + if (validated) { + return@apply + } + + hyperparameters().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = (hyperparameters.asKnown().getOrNull()?.validity() ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is DpoMethod && hyperparameters == other.hyperparameters && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(hyperparameters, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "DpoMethod{hyperparameters=$hyperparameters, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/methods/ReinforcementHyperparameters.kt b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/methods/ReinforcementHyperparameters.kt new file mode 100644 index 00000000..99840ec7 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/methods/ReinforcementHyperparameters.kt @@ -0,0 +1,1703 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.finetuning.methods + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.BaseDeserializer +import com.openai.core.BaseSerializer +import com.openai.core.Enum +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.allMaxBy +import com.openai.core.getOrThrow +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** The hyperparameters used for the reinforcement fine-tuning job. */ +class ReinforcementHyperparameters +private constructor( + private val batchSize: JsonField, + private val computeMultiplier: JsonField, + private val evalInterval: JsonField, + private val evalSamples: JsonField, + private val learningRateMultiplier: JsonField, + private val nEpochs: JsonField, + private val reasoningEffort: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("batch_size") + @ExcludeMissing + batchSize: JsonField = JsonMissing.of(), + @JsonProperty("compute_multiplier") + @ExcludeMissing + computeMultiplier: JsonField = JsonMissing.of(), + @JsonProperty("eval_interval") + @ExcludeMissing + evalInterval: JsonField = JsonMissing.of(), + @JsonProperty("eval_samples") + @ExcludeMissing + evalSamples: JsonField = JsonMissing.of(), + @JsonProperty("learning_rate_multiplier") + @ExcludeMissing + learningRateMultiplier: JsonField = JsonMissing.of(), + @JsonProperty("n_epochs") @ExcludeMissing nEpochs: JsonField = JsonMissing.of(), + @JsonProperty("reasoning_effort") + @ExcludeMissing + reasoningEffort: JsonField = JsonMissing.of(), + ) : this( + batchSize, + computeMultiplier, + evalInterval, + evalSamples, + learningRateMultiplier, + nEpochs, + reasoningEffort, + mutableMapOf(), + ) + + /** + * Number of examples in each batch. A larger batch size means that model parameters are updated + * less frequently, but with lower variance. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun batchSize(): Optional = batchSize.getOptional("batch_size") + + /** + * Multiplier on amount of compute used for exploring search space during training. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun computeMultiplier(): Optional = + computeMultiplier.getOptional("compute_multiplier") + + /** + * The number of training steps between evaluation runs. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun evalInterval(): Optional = evalInterval.getOptional("eval_interval") + + /** + * Number of evaluation samples to generate per training step. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun evalSamples(): Optional = evalSamples.getOptional("eval_samples") + + /** + * Scaling factor for the learning rate. A smaller learning rate may be useful to avoid + * overfitting. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun learningRateMultiplier(): Optional = + learningRateMultiplier.getOptional("learning_rate_multiplier") + + /** + * The number of epochs to train the model for. An epoch refers to one full cycle through the + * training dataset. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun nEpochs(): Optional = nEpochs.getOptional("n_epochs") + + /** + * Level of reasoning effort. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun reasoningEffort(): Optional = + reasoningEffort.getOptional("reasoning_effort") + + /** + * Returns the raw JSON value of [batchSize]. + * + * Unlike [batchSize], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("batch_size") @ExcludeMissing fun _batchSize(): JsonField = batchSize + + /** + * Returns the raw JSON value of [computeMultiplier]. + * + * Unlike [computeMultiplier], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("compute_multiplier") + @ExcludeMissing + fun _computeMultiplier(): JsonField = computeMultiplier + + /** + * Returns the raw JSON value of [evalInterval]. + * + * Unlike [evalInterval], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("eval_interval") + @ExcludeMissing + fun _evalInterval(): JsonField = evalInterval + + /** + * Returns the raw JSON value of [evalSamples]. + * + * Unlike [evalSamples], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("eval_samples") + @ExcludeMissing + fun _evalSamples(): JsonField = evalSamples + + /** + * Returns the raw JSON value of [learningRateMultiplier]. + * + * Unlike [learningRateMultiplier], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("learning_rate_multiplier") + @ExcludeMissing + fun _learningRateMultiplier(): JsonField = learningRateMultiplier + + /** + * Returns the raw JSON value of [nEpochs]. + * + * Unlike [nEpochs], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("n_epochs") @ExcludeMissing fun _nEpochs(): JsonField = nEpochs + + /** + * Returns the raw JSON value of [reasoningEffort]. + * + * Unlike [reasoningEffort], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("reasoning_effort") + @ExcludeMissing + fun _reasoningEffort(): JsonField = reasoningEffort + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [ReinforcementHyperparameters]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ReinforcementHyperparameters]. */ + class Builder internal constructor() { + + private var batchSize: JsonField = JsonMissing.of() + private var computeMultiplier: JsonField = JsonMissing.of() + private var evalInterval: JsonField = JsonMissing.of() + private var evalSamples: JsonField = JsonMissing.of() + private var learningRateMultiplier: JsonField = JsonMissing.of() + private var nEpochs: JsonField = JsonMissing.of() + private var reasoningEffort: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(reinforcementHyperparameters: ReinforcementHyperparameters) = apply { + batchSize = reinforcementHyperparameters.batchSize + computeMultiplier = reinforcementHyperparameters.computeMultiplier + evalInterval = reinforcementHyperparameters.evalInterval + evalSamples = reinforcementHyperparameters.evalSamples + learningRateMultiplier = reinforcementHyperparameters.learningRateMultiplier + nEpochs = reinforcementHyperparameters.nEpochs + reasoningEffort = reinforcementHyperparameters.reasoningEffort + additionalProperties = reinforcementHyperparameters.additionalProperties.toMutableMap() + } + + /** + * Number of examples in each batch. A larger batch size means that model parameters are + * updated less frequently, but with lower variance. + */ + fun batchSize(batchSize: BatchSize) = batchSize(JsonField.of(batchSize)) + + /** + * Sets [Builder.batchSize] to an arbitrary JSON value. + * + * You should usually call [Builder.batchSize] with a well-typed [BatchSize] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun batchSize(batchSize: JsonField) = apply { this.batchSize = batchSize } + + /** Alias for calling [batchSize] with `BatchSize.ofAuto()`. */ + fun batchSizeAuto() = batchSize(BatchSize.ofAuto()) + + /** Alias for calling [batchSize] with `BatchSize.ofInteger(integer)`. */ + fun batchSize(integer: Long) = batchSize(BatchSize.ofInteger(integer)) + + /** Multiplier on amount of compute used for exploring search space during training. */ + fun computeMultiplier(computeMultiplier: ComputeMultiplier) = + computeMultiplier(JsonField.of(computeMultiplier)) + + /** + * Sets [Builder.computeMultiplier] to an arbitrary JSON value. + * + * You should usually call [Builder.computeMultiplier] with a well-typed [ComputeMultiplier] + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun computeMultiplier(computeMultiplier: JsonField) = apply { + this.computeMultiplier = computeMultiplier + } + + /** Alias for calling [computeMultiplier] with `ComputeMultiplier.ofAuto()`. */ + fun computeMultiplierAuto() = computeMultiplier(ComputeMultiplier.ofAuto()) + + /** Alias for calling [computeMultiplier] with `ComputeMultiplier.ofNumber(number)`. */ + fun computeMultiplier(number: Double) = + computeMultiplier(ComputeMultiplier.ofNumber(number)) + + /** The number of training steps between evaluation runs. */ + fun evalInterval(evalInterval: EvalInterval) = evalInterval(JsonField.of(evalInterval)) + + /** + * Sets [Builder.evalInterval] to an arbitrary JSON value. + * + * You should usually call [Builder.evalInterval] with a well-typed [EvalInterval] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun evalInterval(evalInterval: JsonField) = apply { + this.evalInterval = evalInterval + } + + /** Alias for calling [evalInterval] with `EvalInterval.ofAuto()`. */ + fun evalIntervalAuto() = evalInterval(EvalInterval.ofAuto()) + + /** Alias for calling [evalInterval] with `EvalInterval.ofInteger(integer)`. */ + fun evalInterval(integer: Long) = evalInterval(EvalInterval.ofInteger(integer)) + + /** Number of evaluation samples to generate per training step. */ + fun evalSamples(evalSamples: EvalSamples) = evalSamples(JsonField.of(evalSamples)) + + /** + * Sets [Builder.evalSamples] to an arbitrary JSON value. + * + * You should usually call [Builder.evalSamples] with a well-typed [EvalSamples] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun evalSamples(evalSamples: JsonField) = apply { + this.evalSamples = evalSamples + } + + /** Alias for calling [evalSamples] with `EvalSamples.ofAuto()`. */ + fun evalSamplesAuto() = evalSamples(EvalSamples.ofAuto()) + + /** Alias for calling [evalSamples] with `EvalSamples.ofInteger(integer)`. */ + fun evalSamples(integer: Long) = evalSamples(EvalSamples.ofInteger(integer)) + + /** + * Scaling factor for the learning rate. A smaller learning rate may be useful to avoid + * overfitting. + */ + fun learningRateMultiplier(learningRateMultiplier: LearningRateMultiplier) = + learningRateMultiplier(JsonField.of(learningRateMultiplier)) + + /** + * Sets [Builder.learningRateMultiplier] to an arbitrary JSON value. + * + * You should usually call [Builder.learningRateMultiplier] with a well-typed + * [LearningRateMultiplier] value instead. This method is primarily for setting the field to + * an undocumented or not yet supported value. + */ + fun learningRateMultiplier(learningRateMultiplier: JsonField) = + apply { + this.learningRateMultiplier = learningRateMultiplier + } + + /** Alias for calling [learningRateMultiplier] with `LearningRateMultiplier.ofAuto()`. */ + fun learningRateMultiplierAuto() = learningRateMultiplier(LearningRateMultiplier.ofAuto()) + + /** + * Alias for calling [learningRateMultiplier] with + * `LearningRateMultiplier.ofNumber(number)`. + */ + fun learningRateMultiplier(number: Double) = + learningRateMultiplier(LearningRateMultiplier.ofNumber(number)) + + /** + * The number of epochs to train the model for. An epoch refers to one full cycle through + * the training dataset. + */ + fun nEpochs(nEpochs: NEpochs) = nEpochs(JsonField.of(nEpochs)) + + /** + * Sets [Builder.nEpochs] to an arbitrary JSON value. + * + * You should usually call [Builder.nEpochs] with a well-typed [NEpochs] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun nEpochs(nEpochs: JsonField) = apply { this.nEpochs = nEpochs } + + /** Alias for calling [nEpochs] with `NEpochs.ofAuto()`. */ + fun nEpochsAuto() = nEpochs(NEpochs.ofAuto()) + + /** Alias for calling [nEpochs] with `NEpochs.ofInteger(integer)`. */ + fun nEpochs(integer: Long) = nEpochs(NEpochs.ofInteger(integer)) + + /** Level of reasoning effort. */ + fun reasoningEffort(reasoningEffort: ReasoningEffort) = + reasoningEffort(JsonField.of(reasoningEffort)) + + /** + * Sets [Builder.reasoningEffort] to an arbitrary JSON value. + * + * You should usually call [Builder.reasoningEffort] with a well-typed [ReasoningEffort] + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun reasoningEffort(reasoningEffort: JsonField) = apply { + this.reasoningEffort = reasoningEffort + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [ReinforcementHyperparameters]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): ReinforcementHyperparameters = + ReinforcementHyperparameters( + batchSize, + computeMultiplier, + evalInterval, + evalSamples, + learningRateMultiplier, + nEpochs, + reasoningEffort, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): ReinforcementHyperparameters = apply { + if (validated) { + return@apply + } + + batchSize().ifPresent { it.validate() } + computeMultiplier().ifPresent { it.validate() } + evalInterval().ifPresent { it.validate() } + evalSamples().ifPresent { it.validate() } + learningRateMultiplier().ifPresent { it.validate() } + nEpochs().ifPresent { it.validate() } + reasoningEffort().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (batchSize.asKnown().getOrNull()?.validity() ?: 0) + + (computeMultiplier.asKnown().getOrNull()?.validity() ?: 0) + + (evalInterval.asKnown().getOrNull()?.validity() ?: 0) + + (evalSamples.asKnown().getOrNull()?.validity() ?: 0) + + (learningRateMultiplier.asKnown().getOrNull()?.validity() ?: 0) + + (nEpochs.asKnown().getOrNull()?.validity() ?: 0) + + (reasoningEffort.asKnown().getOrNull()?.validity() ?: 0) + + /** + * Number of examples in each batch. A larger batch size means that model parameters are updated + * less frequently, but with lower variance. + */ + @JsonDeserialize(using = BatchSize.Deserializer::class) + @JsonSerialize(using = BatchSize.Serializer::class) + class BatchSize + private constructor( + private val auto: JsonValue? = null, + private val integer: Long? = null, + private val _json: JsonValue? = null, + ) { + + fun auto(): Optional = Optional.ofNullable(auto) + + fun integer(): Optional = Optional.ofNullable(integer) + + fun isAuto(): Boolean = auto != null + + fun isInteger(): Boolean = integer != null + + fun asAuto(): JsonValue = auto.getOrThrow("auto") + + fun asInteger(): Long = integer.getOrThrow("integer") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + auto != null -> visitor.visitAuto(auto) + integer != null -> visitor.visitInteger(integer) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): BatchSize = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitAuto(auto: JsonValue) { + auto.let { + if (it != JsonValue.from("auto")) { + throw OpenAIInvalidDataException("'auto' is invalid, received $it") + } + } + } + + override fun visitInteger(integer: Long) {} + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitAuto(auto: JsonValue) = + auto.let { if (it == JsonValue.from("auto")) 1 else 0 } + + override fun visitInteger(integer: Long) = 1 + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is BatchSize && auto == other.auto && integer == other.integer /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(auto, integer) /* spotless:on */ + + override fun toString(): String = + when { + auto != null -> "BatchSize{auto=$auto}" + integer != null -> "BatchSize{integer=$integer}" + _json != null -> "BatchSize{_unknown=$_json}" + else -> throw IllegalStateException("Invalid BatchSize") + } + + companion object { + + @JvmStatic fun ofAuto() = BatchSize(auto = JsonValue.from("auto")) + + @JvmStatic fun ofInteger(integer: Long) = BatchSize(integer = integer) + } + + /** + * An interface that defines how to map each variant of [BatchSize] to a value of type [T]. + */ + interface Visitor { + + fun visitAuto(auto: JsonValue): T + + fun visitInteger(integer: Long): T + + /** + * Maps an unknown variant of [BatchSize] to a value of type [T]. + * + * An instance of [BatchSize] can contain an unknown variant if it was deserialized from + * data that doesn't match any known variant. For example, if the SDK is on an older + * version than the API, then the API may respond with new variants that the SDK is + * unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown BatchSize: $json") + } + } + + internal class Deserializer : BaseDeserializer(BatchSize::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): BatchSize { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef()) + ?.let { BatchSize(auto = it, _json = json) } + ?.takeIf { it.isValid() }, + tryDeserialize(node, jacksonTypeRef())?.let { + BatchSize(integer = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with + // all the possible variants (e.g. deserializing from object). + 0 -> BatchSize(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely + // valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(BatchSize::class) { + + override fun serialize( + value: BatchSize, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.auto != null -> generator.writeObject(value.auto) + value.integer != null -> generator.writeObject(value.integer) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid BatchSize") + } + } + } + } + + /** Multiplier on amount of compute used for exploring search space during training. */ + @JsonDeserialize(using = ComputeMultiplier.Deserializer::class) + @JsonSerialize(using = ComputeMultiplier.Serializer::class) + class ComputeMultiplier + private constructor( + private val auto: JsonValue? = null, + private val number: Double? = null, + private val _json: JsonValue? = null, + ) { + + fun auto(): Optional = Optional.ofNullable(auto) + + fun number(): Optional = Optional.ofNullable(number) + + fun isAuto(): Boolean = auto != null + + fun isNumber(): Boolean = number != null + + fun asAuto(): JsonValue = auto.getOrThrow("auto") + + fun asNumber(): Double = number.getOrThrow("number") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + auto != null -> visitor.visitAuto(auto) + number != null -> visitor.visitNumber(number) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): ComputeMultiplier = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitAuto(auto: JsonValue) { + auto.let { + if (it != JsonValue.from("auto")) { + throw OpenAIInvalidDataException("'auto' is invalid, received $it") + } + } + } + + override fun visitNumber(number: Double) {} + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitAuto(auto: JsonValue) = + auto.let { if (it == JsonValue.from("auto")) 1 else 0 } + + override fun visitNumber(number: Double) = 1 + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ComputeMultiplier && auto == other.auto && number == other.number /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(auto, number) /* spotless:on */ + + override fun toString(): String = + when { + auto != null -> "ComputeMultiplier{auto=$auto}" + number != null -> "ComputeMultiplier{number=$number}" + _json != null -> "ComputeMultiplier{_unknown=$_json}" + else -> throw IllegalStateException("Invalid ComputeMultiplier") + } + + companion object { + + @JvmStatic fun ofAuto() = ComputeMultiplier(auto = JsonValue.from("auto")) + + @JvmStatic fun ofNumber(number: Double) = ComputeMultiplier(number = number) + } + + /** + * An interface that defines how to map each variant of [ComputeMultiplier] to a value of + * type [T]. + */ + interface Visitor { + + fun visitAuto(auto: JsonValue): T + + fun visitNumber(number: Double): T + + /** + * Maps an unknown variant of [ComputeMultiplier] to a value of type [T]. + * + * An instance of [ComputeMultiplier] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For example, if the SDK + * is on an older version than the API, then the API may respond with new variants that + * the SDK is unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown ComputeMultiplier: $json") + } + } + + internal class Deserializer : + BaseDeserializer(ComputeMultiplier::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): ComputeMultiplier { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef()) + ?.let { ComputeMultiplier(auto = it, _json = json) } + ?.takeIf { it.isValid() }, + tryDeserialize(node, jacksonTypeRef())?.let { + ComputeMultiplier(number = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with + // all the possible variants (e.g. deserializing from object). + 0 -> ComputeMultiplier(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely + // valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(ComputeMultiplier::class) { + + override fun serialize( + value: ComputeMultiplier, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.auto != null -> generator.writeObject(value.auto) + value.number != null -> generator.writeObject(value.number) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid ComputeMultiplier") + } + } + } + } + + /** The number of training steps between evaluation runs. */ + @JsonDeserialize(using = EvalInterval.Deserializer::class) + @JsonSerialize(using = EvalInterval.Serializer::class) + class EvalInterval + private constructor( + private val auto: JsonValue? = null, + private val integer: Long? = null, + private val _json: JsonValue? = null, + ) { + + fun auto(): Optional = Optional.ofNullable(auto) + + fun integer(): Optional = Optional.ofNullable(integer) + + fun isAuto(): Boolean = auto != null + + fun isInteger(): Boolean = integer != null + + fun asAuto(): JsonValue = auto.getOrThrow("auto") + + fun asInteger(): Long = integer.getOrThrow("integer") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + auto != null -> visitor.visitAuto(auto) + integer != null -> visitor.visitInteger(integer) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): EvalInterval = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitAuto(auto: JsonValue) { + auto.let { + if (it != JsonValue.from("auto")) { + throw OpenAIInvalidDataException("'auto' is invalid, received $it") + } + } + } + + override fun visitInteger(integer: Long) {} + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitAuto(auto: JsonValue) = + auto.let { if (it == JsonValue.from("auto")) 1 else 0 } + + override fun visitInteger(integer: Long) = 1 + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is EvalInterval && auto == other.auto && integer == other.integer /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(auto, integer) /* spotless:on */ + + override fun toString(): String = + when { + auto != null -> "EvalInterval{auto=$auto}" + integer != null -> "EvalInterval{integer=$integer}" + _json != null -> "EvalInterval{_unknown=$_json}" + else -> throw IllegalStateException("Invalid EvalInterval") + } + + companion object { + + @JvmStatic fun ofAuto() = EvalInterval(auto = JsonValue.from("auto")) + + @JvmStatic fun ofInteger(integer: Long) = EvalInterval(integer = integer) + } + + /** + * An interface that defines how to map each variant of [EvalInterval] to a value of type + * [T]. + */ + interface Visitor { + + fun visitAuto(auto: JsonValue): T + + fun visitInteger(integer: Long): T + + /** + * Maps an unknown variant of [EvalInterval] to a value of type [T]. + * + * An instance of [EvalInterval] can contain an unknown variant if it was deserialized + * from data that doesn't match any known variant. For example, if the SDK is on an + * older version than the API, then the API may respond with new variants that the SDK + * is unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown EvalInterval: $json") + } + } + + internal class Deserializer : BaseDeserializer(EvalInterval::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): EvalInterval { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef()) + ?.let { EvalInterval(auto = it, _json = json) } + ?.takeIf { it.isValid() }, + tryDeserialize(node, jacksonTypeRef())?.let { + EvalInterval(integer = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with + // all the possible variants (e.g. deserializing from object). + 0 -> EvalInterval(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely + // valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(EvalInterval::class) { + + override fun serialize( + value: EvalInterval, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.auto != null -> generator.writeObject(value.auto) + value.integer != null -> generator.writeObject(value.integer) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid EvalInterval") + } + } + } + } + + /** Number of evaluation samples to generate per training step. */ + @JsonDeserialize(using = EvalSamples.Deserializer::class) + @JsonSerialize(using = EvalSamples.Serializer::class) + class EvalSamples + private constructor( + private val auto: JsonValue? = null, + private val integer: Long? = null, + private val _json: JsonValue? = null, + ) { + + fun auto(): Optional = Optional.ofNullable(auto) + + fun integer(): Optional = Optional.ofNullable(integer) + + fun isAuto(): Boolean = auto != null + + fun isInteger(): Boolean = integer != null + + fun asAuto(): JsonValue = auto.getOrThrow("auto") + + fun asInteger(): Long = integer.getOrThrow("integer") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + auto != null -> visitor.visitAuto(auto) + integer != null -> visitor.visitInteger(integer) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): EvalSamples = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitAuto(auto: JsonValue) { + auto.let { + if (it != JsonValue.from("auto")) { + throw OpenAIInvalidDataException("'auto' is invalid, received $it") + } + } + } + + override fun visitInteger(integer: Long) {} + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitAuto(auto: JsonValue) = + auto.let { if (it == JsonValue.from("auto")) 1 else 0 } + + override fun visitInteger(integer: Long) = 1 + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is EvalSamples && auto == other.auto && integer == other.integer /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(auto, integer) /* spotless:on */ + + override fun toString(): String = + when { + auto != null -> "EvalSamples{auto=$auto}" + integer != null -> "EvalSamples{integer=$integer}" + _json != null -> "EvalSamples{_unknown=$_json}" + else -> throw IllegalStateException("Invalid EvalSamples") + } + + companion object { + + @JvmStatic fun ofAuto() = EvalSamples(auto = JsonValue.from("auto")) + + @JvmStatic fun ofInteger(integer: Long) = EvalSamples(integer = integer) + } + + /** + * An interface that defines how to map each variant of [EvalSamples] to a value of type + * [T]. + */ + interface Visitor { + + fun visitAuto(auto: JsonValue): T + + fun visitInteger(integer: Long): T + + /** + * Maps an unknown variant of [EvalSamples] to a value of type [T]. + * + * An instance of [EvalSamples] can contain an unknown variant if it was deserialized + * from data that doesn't match any known variant. For example, if the SDK is on an + * older version than the API, then the API may respond with new variants that the SDK + * is unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown EvalSamples: $json") + } + } + + internal class Deserializer : BaseDeserializer(EvalSamples::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): EvalSamples { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef()) + ?.let { EvalSamples(auto = it, _json = json) } + ?.takeIf { it.isValid() }, + tryDeserialize(node, jacksonTypeRef())?.let { + EvalSamples(integer = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with + // all the possible variants (e.g. deserializing from object). + 0 -> EvalSamples(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely + // valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(EvalSamples::class) { + + override fun serialize( + value: EvalSamples, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.auto != null -> generator.writeObject(value.auto) + value.integer != null -> generator.writeObject(value.integer) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid EvalSamples") + } + } + } + } + + /** + * Scaling factor for the learning rate. A smaller learning rate may be useful to avoid + * overfitting. + */ + @JsonDeserialize(using = LearningRateMultiplier.Deserializer::class) + @JsonSerialize(using = LearningRateMultiplier.Serializer::class) + class LearningRateMultiplier + private constructor( + private val auto: JsonValue? = null, + private val number: Double? = null, + private val _json: JsonValue? = null, + ) { + + fun auto(): Optional = Optional.ofNullable(auto) + + fun number(): Optional = Optional.ofNullable(number) + + fun isAuto(): Boolean = auto != null + + fun isNumber(): Boolean = number != null + + fun asAuto(): JsonValue = auto.getOrThrow("auto") + + fun asNumber(): Double = number.getOrThrow("number") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + auto != null -> visitor.visitAuto(auto) + number != null -> visitor.visitNumber(number) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): LearningRateMultiplier = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitAuto(auto: JsonValue) { + auto.let { + if (it != JsonValue.from("auto")) { + throw OpenAIInvalidDataException("'auto' is invalid, received $it") + } + } + } + + override fun visitNumber(number: Double) {} + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitAuto(auto: JsonValue) = + auto.let { if (it == JsonValue.from("auto")) 1 else 0 } + + override fun visitNumber(number: Double) = 1 + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is LearningRateMultiplier && auto == other.auto && number == other.number /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(auto, number) /* spotless:on */ + + override fun toString(): String = + when { + auto != null -> "LearningRateMultiplier{auto=$auto}" + number != null -> "LearningRateMultiplier{number=$number}" + _json != null -> "LearningRateMultiplier{_unknown=$_json}" + else -> throw IllegalStateException("Invalid LearningRateMultiplier") + } + + companion object { + + @JvmStatic fun ofAuto() = LearningRateMultiplier(auto = JsonValue.from("auto")) + + @JvmStatic fun ofNumber(number: Double) = LearningRateMultiplier(number = number) + } + + /** + * An interface that defines how to map each variant of [LearningRateMultiplier] to a value + * of type [T]. + */ + interface Visitor { + + fun visitAuto(auto: JsonValue): T + + fun visitNumber(number: Double): T + + /** + * Maps an unknown variant of [LearningRateMultiplier] to a value of type [T]. + * + * An instance of [LearningRateMultiplier] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For example, if the SDK + * is on an older version than the API, then the API may respond with new variants that + * the SDK is unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown LearningRateMultiplier: $json") + } + } + + internal class Deserializer : + BaseDeserializer(LearningRateMultiplier::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): LearningRateMultiplier { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef()) + ?.let { LearningRateMultiplier(auto = it, _json = json) } + ?.takeIf { it.isValid() }, + tryDeserialize(node, jacksonTypeRef())?.let { + LearningRateMultiplier(number = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with + // all the possible variants (e.g. deserializing from object). + 0 -> LearningRateMultiplier(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely + // valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : + BaseSerializer(LearningRateMultiplier::class) { + + override fun serialize( + value: LearningRateMultiplier, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.auto != null -> generator.writeObject(value.auto) + value.number != null -> generator.writeObject(value.number) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid LearningRateMultiplier") + } + } + } + } + + /** + * The number of epochs to train the model for. An epoch refers to one full cycle through the + * training dataset. + */ + @JsonDeserialize(using = NEpochs.Deserializer::class) + @JsonSerialize(using = NEpochs.Serializer::class) + class NEpochs + private constructor( + private val auto: JsonValue? = null, + private val integer: Long? = null, + private val _json: JsonValue? = null, + ) { + + fun auto(): Optional = Optional.ofNullable(auto) + + fun integer(): Optional = Optional.ofNullable(integer) + + fun isAuto(): Boolean = auto != null + + fun isInteger(): Boolean = integer != null + + fun asAuto(): JsonValue = auto.getOrThrow("auto") + + fun asInteger(): Long = integer.getOrThrow("integer") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + auto != null -> visitor.visitAuto(auto) + integer != null -> visitor.visitInteger(integer) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): NEpochs = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitAuto(auto: JsonValue) { + auto.let { + if (it != JsonValue.from("auto")) { + throw OpenAIInvalidDataException("'auto' is invalid, received $it") + } + } + } + + override fun visitInteger(integer: Long) {} + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitAuto(auto: JsonValue) = + auto.let { if (it == JsonValue.from("auto")) 1 else 0 } + + override fun visitInteger(integer: Long) = 1 + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is NEpochs && auto == other.auto && integer == other.integer /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(auto, integer) /* spotless:on */ + + override fun toString(): String = + when { + auto != null -> "NEpochs{auto=$auto}" + integer != null -> "NEpochs{integer=$integer}" + _json != null -> "NEpochs{_unknown=$_json}" + else -> throw IllegalStateException("Invalid NEpochs") + } + + companion object { + + @JvmStatic fun ofAuto() = NEpochs(auto = JsonValue.from("auto")) + + @JvmStatic fun ofInteger(integer: Long) = NEpochs(integer = integer) + } + + /** + * An interface that defines how to map each variant of [NEpochs] to a value of type [T]. + */ + interface Visitor { + + fun visitAuto(auto: JsonValue): T + + fun visitInteger(integer: Long): T + + /** + * Maps an unknown variant of [NEpochs] to a value of type [T]. + * + * An instance of [NEpochs] can contain an unknown variant if it was deserialized from + * data that doesn't match any known variant. For example, if the SDK is on an older + * version than the API, then the API may respond with new variants that the SDK is + * unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown NEpochs: $json") + } + } + + internal class Deserializer : BaseDeserializer(NEpochs::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): NEpochs { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef()) + ?.let { NEpochs(auto = it, _json = json) } + ?.takeIf { it.isValid() }, + tryDeserialize(node, jacksonTypeRef())?.let { + NEpochs(integer = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with + // all the possible variants (e.g. deserializing from object). + 0 -> NEpochs(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely + // valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(NEpochs::class) { + + override fun serialize( + value: NEpochs, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.auto != null -> generator.writeObject(value.auto) + value.integer != null -> generator.writeObject(value.integer) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid NEpochs") + } + } + } + } + + /** Level of reasoning effort. */ + class ReasoningEffort @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val DEFAULT = of("default") + + @JvmField val LOW = of("low") + + @JvmField val MEDIUM = of("medium") + + @JvmField val HIGH = of("high") + + @JvmStatic fun of(value: String) = ReasoningEffort(JsonField.of(value)) + } + + /** An enum containing [ReasoningEffort]'s known values. */ + enum class Known { + DEFAULT, + LOW, + MEDIUM, + HIGH, + } + + /** + * An enum containing [ReasoningEffort]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [ReasoningEffort] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + DEFAULT, + LOW, + MEDIUM, + HIGH, + /** + * An enum member indicating that [ReasoningEffort] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + DEFAULT -> Value.DEFAULT + LOW -> Value.LOW + MEDIUM -> Value.MEDIUM + HIGH -> Value.HIGH + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + DEFAULT -> Known.DEFAULT + LOW -> Known.LOW + MEDIUM -> Known.MEDIUM + HIGH -> Known.HIGH + else -> throw OpenAIInvalidDataException("Unknown ReasoningEffort: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): ReasoningEffort = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ReasoningEffort && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ReinforcementHyperparameters && batchSize == other.batchSize && computeMultiplier == other.computeMultiplier && evalInterval == other.evalInterval && evalSamples == other.evalSamples && learningRateMultiplier == other.learningRateMultiplier && nEpochs == other.nEpochs && reasoningEffort == other.reasoningEffort && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(batchSize, computeMultiplier, evalInterval, evalSamples, learningRateMultiplier, nEpochs, reasoningEffort, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ReinforcementHyperparameters{batchSize=$batchSize, computeMultiplier=$computeMultiplier, evalInterval=$evalInterval, evalSamples=$evalSamples, learningRateMultiplier=$learningRateMultiplier, nEpochs=$nEpochs, reasoningEffort=$reasoningEffort, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/methods/ReinforcementMethod.kt b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/methods/ReinforcementMethod.kt new file mode 100644 index 00000000..423082ee --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/methods/ReinforcementMethod.kt @@ -0,0 +1,541 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.finetuning.methods + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.BaseDeserializer +import com.openai.core.BaseSerializer +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.allMaxBy +import com.openai.core.checkRequired +import com.openai.core.getOrThrow +import com.openai.errors.OpenAIInvalidDataException +import com.openai.models.graders.gradermodels.MultiGrader +import com.openai.models.graders.gradermodels.PythonGrader +import com.openai.models.graders.gradermodels.ScoreModelGrader +import com.openai.models.graders.gradermodels.StringCheckGrader +import com.openai.models.graders.gradermodels.TextSimilarityGrader +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Configuration for the reinforcement fine-tuning method. */ +class ReinforcementMethod +private constructor( + private val grader: JsonField, + private val hyperparameters: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("grader") @ExcludeMissing grader: JsonField = JsonMissing.of(), + @JsonProperty("hyperparameters") + @ExcludeMissing + hyperparameters: JsonField = JsonMissing.of(), + ) : this(grader, hyperparameters, mutableMapOf()) + + /** + * The grader used for the fine-tuning job. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun grader(): Grader = grader.getRequired("grader") + + /** + * The hyperparameters used for the reinforcement fine-tuning job. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun hyperparameters(): Optional = + hyperparameters.getOptional("hyperparameters") + + /** + * Returns the raw JSON value of [grader]. + * + * Unlike [grader], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("grader") @ExcludeMissing fun _grader(): JsonField = grader + + /** + * Returns the raw JSON value of [hyperparameters]. + * + * Unlike [hyperparameters], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("hyperparameters") + @ExcludeMissing + fun _hyperparameters(): JsonField = hyperparameters + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [ReinforcementMethod]. + * + * The following fields are required: + * ```java + * .grader() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ReinforcementMethod]. */ + class Builder internal constructor() { + + private var grader: JsonField? = null + private var hyperparameters: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(reinforcementMethod: ReinforcementMethod) = apply { + grader = reinforcementMethod.grader + hyperparameters = reinforcementMethod.hyperparameters + additionalProperties = reinforcementMethod.additionalProperties.toMutableMap() + } + + /** The grader used for the fine-tuning job. */ + fun grader(grader: Grader) = grader(JsonField.of(grader)) + + /** + * Sets [Builder.grader] to an arbitrary JSON value. + * + * You should usually call [Builder.grader] with a well-typed [Grader] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun grader(grader: JsonField) = apply { this.grader = grader } + + /** Alias for calling [grader] with `Grader.ofStringCheck(stringCheck)`. */ + fun grader(stringCheck: StringCheckGrader) = grader(Grader.ofStringCheck(stringCheck)) + + /** Alias for calling [grader] with `Grader.ofTextSimilarity(textSimilarity)`. */ + fun grader(textSimilarity: TextSimilarityGrader) = + grader(Grader.ofTextSimilarity(textSimilarity)) + + /** Alias for calling [grader] with `Grader.ofPython(python)`. */ + fun grader(python: PythonGrader) = grader(Grader.ofPython(python)) + + /** Alias for calling [grader] with `Grader.ofScoreModel(scoreModel)`. */ + fun grader(scoreModel: ScoreModelGrader) = grader(Grader.ofScoreModel(scoreModel)) + + /** Alias for calling [grader] with `Grader.ofMulti(multi)`. */ + fun grader(multi: MultiGrader) = grader(Grader.ofMulti(multi)) + + /** The hyperparameters used for the reinforcement fine-tuning job. */ + fun hyperparameters(hyperparameters: ReinforcementHyperparameters) = + hyperparameters(JsonField.of(hyperparameters)) + + /** + * Sets [Builder.hyperparameters] to an arbitrary JSON value. + * + * You should usually call [Builder.hyperparameters] with a well-typed + * [ReinforcementHyperparameters] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun hyperparameters(hyperparameters: JsonField) = apply { + this.hyperparameters = hyperparameters + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [ReinforcementMethod]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .grader() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ReinforcementMethod = + ReinforcementMethod( + checkRequired("grader", grader), + hyperparameters, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): ReinforcementMethod = apply { + if (validated) { + return@apply + } + + grader().validate() + hyperparameters().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (grader.asKnown().getOrNull()?.validity() ?: 0) + + (hyperparameters.asKnown().getOrNull()?.validity() ?: 0) + + /** The grader used for the fine-tuning job. */ + @JsonDeserialize(using = Grader.Deserializer::class) + @JsonSerialize(using = Grader.Serializer::class) + class Grader + private constructor( + private val stringCheck: StringCheckGrader? = null, + private val textSimilarity: TextSimilarityGrader? = null, + private val python: PythonGrader? = null, + private val scoreModel: ScoreModelGrader? = null, + private val multi: MultiGrader? = null, + private val _json: JsonValue? = null, + ) { + + /** + * A StringCheckGrader object that performs a string comparison between input and reference + * using a specified operation. + */ + fun stringCheck(): Optional = Optional.ofNullable(stringCheck) + + /** A TextSimilarityGrader object which grades text based on similarity metrics. */ + fun textSimilarity(): Optional = Optional.ofNullable(textSimilarity) + + /** A PythonGrader object that runs a python script on the input. */ + fun python(): Optional = Optional.ofNullable(python) + + /** A ScoreModelGrader object that uses a model to assign a score to the input. */ + fun scoreModel(): Optional = Optional.ofNullable(scoreModel) + + /** + * A MultiGrader object combines the output of multiple graders to produce a single score. + */ + fun multi(): Optional = Optional.ofNullable(multi) + + fun isStringCheck(): Boolean = stringCheck != null + + fun isTextSimilarity(): Boolean = textSimilarity != null + + fun isPython(): Boolean = python != null + + fun isScoreModel(): Boolean = scoreModel != null + + fun isMulti(): Boolean = multi != null + + /** + * A StringCheckGrader object that performs a string comparison between input and reference + * using a specified operation. + */ + fun asStringCheck(): StringCheckGrader = stringCheck.getOrThrow("stringCheck") + + /** A TextSimilarityGrader object which grades text based on similarity metrics. */ + fun asTextSimilarity(): TextSimilarityGrader = textSimilarity.getOrThrow("textSimilarity") + + /** A PythonGrader object that runs a python script on the input. */ + fun asPython(): PythonGrader = python.getOrThrow("python") + + /** A ScoreModelGrader object that uses a model to assign a score to the input. */ + fun asScoreModel(): ScoreModelGrader = scoreModel.getOrThrow("scoreModel") + + /** + * A MultiGrader object combines the output of multiple graders to produce a single score. + */ + fun asMulti(): MultiGrader = multi.getOrThrow("multi") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + stringCheck != null -> visitor.visitStringCheck(stringCheck) + textSimilarity != null -> visitor.visitTextSimilarity(textSimilarity) + python != null -> visitor.visitPython(python) + scoreModel != null -> visitor.visitScoreModel(scoreModel) + multi != null -> visitor.visitMulti(multi) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): Grader = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitStringCheck(stringCheck: StringCheckGrader) { + stringCheck.validate() + } + + override fun visitTextSimilarity(textSimilarity: TextSimilarityGrader) { + textSimilarity.validate() + } + + override fun visitPython(python: PythonGrader) { + python.validate() + } + + override fun visitScoreModel(scoreModel: ScoreModelGrader) { + scoreModel.validate() + } + + override fun visitMulti(multi: MultiGrader) { + multi.validate() + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitStringCheck(stringCheck: StringCheckGrader) = + stringCheck.validity() + + override fun visitTextSimilarity(textSimilarity: TextSimilarityGrader) = + textSimilarity.validity() + + override fun visitPython(python: PythonGrader) = python.validity() + + override fun visitScoreModel(scoreModel: ScoreModelGrader) = + scoreModel.validity() + + override fun visitMulti(multi: MultiGrader) = multi.validity() + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Grader && stringCheck == other.stringCheck && textSimilarity == other.textSimilarity && python == other.python && scoreModel == other.scoreModel && multi == other.multi /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(stringCheck, textSimilarity, python, scoreModel, multi) /* spotless:on */ + + override fun toString(): String = + when { + stringCheck != null -> "Grader{stringCheck=$stringCheck}" + textSimilarity != null -> "Grader{textSimilarity=$textSimilarity}" + python != null -> "Grader{python=$python}" + scoreModel != null -> "Grader{scoreModel=$scoreModel}" + multi != null -> "Grader{multi=$multi}" + _json != null -> "Grader{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Grader") + } + + companion object { + + /** + * A StringCheckGrader object that performs a string comparison between input and + * reference using a specified operation. + */ + @JvmStatic + fun ofStringCheck(stringCheck: StringCheckGrader) = Grader(stringCheck = stringCheck) + + /** A TextSimilarityGrader object which grades text based on similarity metrics. */ + @JvmStatic + fun ofTextSimilarity(textSimilarity: TextSimilarityGrader) = + Grader(textSimilarity = textSimilarity) + + /** A PythonGrader object that runs a python script on the input. */ + @JvmStatic fun ofPython(python: PythonGrader) = Grader(python = python) + + /** A ScoreModelGrader object that uses a model to assign a score to the input. */ + @JvmStatic + fun ofScoreModel(scoreModel: ScoreModelGrader) = Grader(scoreModel = scoreModel) + + /** + * A MultiGrader object combines the output of multiple graders to produce a single + * score. + */ + @JvmStatic fun ofMulti(multi: MultiGrader) = Grader(multi = multi) + } + + /** An interface that defines how to map each variant of [Grader] to a value of type [T]. */ + interface Visitor { + + /** + * A StringCheckGrader object that performs a string comparison between input and + * reference using a specified operation. + */ + fun visitStringCheck(stringCheck: StringCheckGrader): T + + /** A TextSimilarityGrader object which grades text based on similarity metrics. */ + fun visitTextSimilarity(textSimilarity: TextSimilarityGrader): T + + /** A PythonGrader object that runs a python script on the input. */ + fun visitPython(python: PythonGrader): T + + /** A ScoreModelGrader object that uses a model to assign a score to the input. */ + fun visitScoreModel(scoreModel: ScoreModelGrader): T + + /** + * A MultiGrader object combines the output of multiple graders to produce a single + * score. + */ + fun visitMulti(multi: MultiGrader): T + + /** + * Maps an unknown variant of [Grader] to a value of type [T]. + * + * An instance of [Grader] can contain an unknown variant if it was deserialized from + * data that doesn't match any known variant. For example, if the SDK is on an older + * version than the API, then the API may respond with new variants that the SDK is + * unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown Grader: $json") + } + } + + internal class Deserializer : BaseDeserializer(Grader::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): Grader { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + Grader(stringCheck = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + Grader(textSimilarity = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + Grader(python = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + Grader(scoreModel = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + Grader(multi = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with + // all the possible variants (e.g. deserializing from boolean). + 0 -> Grader(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely + // valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(Grader::class) { + + override fun serialize( + value: Grader, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.stringCheck != null -> generator.writeObject(value.stringCheck) + value.textSimilarity != null -> generator.writeObject(value.textSimilarity) + value.python != null -> generator.writeObject(value.python) + value.scoreModel != null -> generator.writeObject(value.scoreModel) + value.multi != null -> generator.writeObject(value.multi) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Grader") + } + } + } + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ReinforcementMethod && grader == other.grader && hyperparameters == other.hyperparameters && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(grader, hyperparameters, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ReinforcementMethod{grader=$grader, hyperparameters=$hyperparameters, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/methods/SupervisedHyperparameters.kt b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/methods/SupervisedHyperparameters.kt new file mode 100644 index 00000000..92aa0e79 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/methods/SupervisedHyperparameters.kt @@ -0,0 +1,832 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.finetuning.methods + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.BaseDeserializer +import com.openai.core.BaseSerializer +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.allMaxBy +import com.openai.core.getOrThrow +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** The hyperparameters used for the fine-tuning job. */ +class SupervisedHyperparameters +private constructor( + private val batchSize: JsonField, + private val learningRateMultiplier: JsonField, + private val nEpochs: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("batch_size") + @ExcludeMissing + batchSize: JsonField = JsonMissing.of(), + @JsonProperty("learning_rate_multiplier") + @ExcludeMissing + learningRateMultiplier: JsonField = JsonMissing.of(), + @JsonProperty("n_epochs") @ExcludeMissing nEpochs: JsonField = JsonMissing.of(), + ) : this(batchSize, learningRateMultiplier, nEpochs, mutableMapOf()) + + /** + * Number of examples in each batch. A larger batch size means that model parameters are updated + * less frequently, but with lower variance. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun batchSize(): Optional = batchSize.getOptional("batch_size") + + /** + * Scaling factor for the learning rate. A smaller learning rate may be useful to avoid + * overfitting. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun learningRateMultiplier(): Optional = + learningRateMultiplier.getOptional("learning_rate_multiplier") + + /** + * The number of epochs to train the model for. An epoch refers to one full cycle through the + * training dataset. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun nEpochs(): Optional = nEpochs.getOptional("n_epochs") + + /** + * Returns the raw JSON value of [batchSize]. + * + * Unlike [batchSize], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("batch_size") @ExcludeMissing fun _batchSize(): JsonField = batchSize + + /** + * Returns the raw JSON value of [learningRateMultiplier]. + * + * Unlike [learningRateMultiplier], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("learning_rate_multiplier") + @ExcludeMissing + fun _learningRateMultiplier(): JsonField = learningRateMultiplier + + /** + * Returns the raw JSON value of [nEpochs]. + * + * Unlike [nEpochs], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("n_epochs") @ExcludeMissing fun _nEpochs(): JsonField = nEpochs + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [SupervisedHyperparameters]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SupervisedHyperparameters]. */ + class Builder internal constructor() { + + private var batchSize: JsonField = JsonMissing.of() + private var learningRateMultiplier: JsonField = JsonMissing.of() + private var nEpochs: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(supervisedHyperparameters: SupervisedHyperparameters) = apply { + batchSize = supervisedHyperparameters.batchSize + learningRateMultiplier = supervisedHyperparameters.learningRateMultiplier + nEpochs = supervisedHyperparameters.nEpochs + additionalProperties = supervisedHyperparameters.additionalProperties.toMutableMap() + } + + /** + * Number of examples in each batch. A larger batch size means that model parameters are + * updated less frequently, but with lower variance. + */ + fun batchSize(batchSize: BatchSize) = batchSize(JsonField.of(batchSize)) + + /** + * Sets [Builder.batchSize] to an arbitrary JSON value. + * + * You should usually call [Builder.batchSize] with a well-typed [BatchSize] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun batchSize(batchSize: JsonField) = apply { this.batchSize = batchSize } + + /** Alias for calling [batchSize] with `BatchSize.ofAuto()`. */ + fun batchSizeAuto() = batchSize(BatchSize.ofAuto()) + + /** Alias for calling [batchSize] with `BatchSize.ofInteger(integer)`. */ + fun batchSize(integer: Long) = batchSize(BatchSize.ofInteger(integer)) + + /** + * Scaling factor for the learning rate. A smaller learning rate may be useful to avoid + * overfitting. + */ + fun learningRateMultiplier(learningRateMultiplier: LearningRateMultiplier) = + learningRateMultiplier(JsonField.of(learningRateMultiplier)) + + /** + * Sets [Builder.learningRateMultiplier] to an arbitrary JSON value. + * + * You should usually call [Builder.learningRateMultiplier] with a well-typed + * [LearningRateMultiplier] value instead. This method is primarily for setting the field to + * an undocumented or not yet supported value. + */ + fun learningRateMultiplier(learningRateMultiplier: JsonField) = + apply { + this.learningRateMultiplier = learningRateMultiplier + } + + /** Alias for calling [learningRateMultiplier] with `LearningRateMultiplier.ofAuto()`. */ + fun learningRateMultiplierAuto() = learningRateMultiplier(LearningRateMultiplier.ofAuto()) + + /** + * Alias for calling [learningRateMultiplier] with + * `LearningRateMultiplier.ofNumber(number)`. + */ + fun learningRateMultiplier(number: Double) = + learningRateMultiplier(LearningRateMultiplier.ofNumber(number)) + + /** + * The number of epochs to train the model for. An epoch refers to one full cycle through + * the training dataset. + */ + fun nEpochs(nEpochs: NEpochs) = nEpochs(JsonField.of(nEpochs)) + + /** + * Sets [Builder.nEpochs] to an arbitrary JSON value. + * + * You should usually call [Builder.nEpochs] with a well-typed [NEpochs] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun nEpochs(nEpochs: JsonField) = apply { this.nEpochs = nEpochs } + + /** Alias for calling [nEpochs] with `NEpochs.ofAuto()`. */ + fun nEpochsAuto() = nEpochs(NEpochs.ofAuto()) + + /** Alias for calling [nEpochs] with `NEpochs.ofInteger(integer)`. */ + fun nEpochs(integer: Long) = nEpochs(NEpochs.ofInteger(integer)) + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [SupervisedHyperparameters]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): SupervisedHyperparameters = + SupervisedHyperparameters( + batchSize, + learningRateMultiplier, + nEpochs, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): SupervisedHyperparameters = apply { + if (validated) { + return@apply + } + + batchSize().ifPresent { it.validate() } + learningRateMultiplier().ifPresent { it.validate() } + nEpochs().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (batchSize.asKnown().getOrNull()?.validity() ?: 0) + + (learningRateMultiplier.asKnown().getOrNull()?.validity() ?: 0) + + (nEpochs.asKnown().getOrNull()?.validity() ?: 0) + + /** + * Number of examples in each batch. A larger batch size means that model parameters are updated + * less frequently, but with lower variance. + */ + @JsonDeserialize(using = BatchSize.Deserializer::class) + @JsonSerialize(using = BatchSize.Serializer::class) + class BatchSize + private constructor( + private val auto: JsonValue? = null, + private val integer: Long? = null, + private val _json: JsonValue? = null, + ) { + + fun auto(): Optional = Optional.ofNullable(auto) + + fun integer(): Optional = Optional.ofNullable(integer) + + fun isAuto(): Boolean = auto != null + + fun isInteger(): Boolean = integer != null + + fun asAuto(): JsonValue = auto.getOrThrow("auto") + + fun asInteger(): Long = integer.getOrThrow("integer") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + auto != null -> visitor.visitAuto(auto) + integer != null -> visitor.visitInteger(integer) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): BatchSize = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitAuto(auto: JsonValue) { + auto.let { + if (it != JsonValue.from("auto")) { + throw OpenAIInvalidDataException("'auto' is invalid, received $it") + } + } + } + + override fun visitInteger(integer: Long) {} + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitAuto(auto: JsonValue) = + auto.let { if (it == JsonValue.from("auto")) 1 else 0 } + + override fun visitInteger(integer: Long) = 1 + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is BatchSize && auto == other.auto && integer == other.integer /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(auto, integer) /* spotless:on */ + + override fun toString(): String = + when { + auto != null -> "BatchSize{auto=$auto}" + integer != null -> "BatchSize{integer=$integer}" + _json != null -> "BatchSize{_unknown=$_json}" + else -> throw IllegalStateException("Invalid BatchSize") + } + + companion object { + + @JvmStatic fun ofAuto() = BatchSize(auto = JsonValue.from("auto")) + + @JvmStatic fun ofInteger(integer: Long) = BatchSize(integer = integer) + } + + /** + * An interface that defines how to map each variant of [BatchSize] to a value of type [T]. + */ + interface Visitor { + + fun visitAuto(auto: JsonValue): T + + fun visitInteger(integer: Long): T + + /** + * Maps an unknown variant of [BatchSize] to a value of type [T]. + * + * An instance of [BatchSize] can contain an unknown variant if it was deserialized from + * data that doesn't match any known variant. For example, if the SDK is on an older + * version than the API, then the API may respond with new variants that the SDK is + * unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown BatchSize: $json") + } + } + + internal class Deserializer : BaseDeserializer(BatchSize::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): BatchSize { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef()) + ?.let { BatchSize(auto = it, _json = json) } + ?.takeIf { it.isValid() }, + tryDeserialize(node, jacksonTypeRef())?.let { + BatchSize(integer = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with + // all the possible variants (e.g. deserializing from object). + 0 -> BatchSize(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely + // valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(BatchSize::class) { + + override fun serialize( + value: BatchSize, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.auto != null -> generator.writeObject(value.auto) + value.integer != null -> generator.writeObject(value.integer) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid BatchSize") + } + } + } + } + + /** + * Scaling factor for the learning rate. A smaller learning rate may be useful to avoid + * overfitting. + */ + @JsonDeserialize(using = LearningRateMultiplier.Deserializer::class) + @JsonSerialize(using = LearningRateMultiplier.Serializer::class) + class LearningRateMultiplier + private constructor( + private val auto: JsonValue? = null, + private val number: Double? = null, + private val _json: JsonValue? = null, + ) { + + fun auto(): Optional = Optional.ofNullable(auto) + + fun number(): Optional = Optional.ofNullable(number) + + fun isAuto(): Boolean = auto != null + + fun isNumber(): Boolean = number != null + + fun asAuto(): JsonValue = auto.getOrThrow("auto") + + fun asNumber(): Double = number.getOrThrow("number") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + auto != null -> visitor.visitAuto(auto) + number != null -> visitor.visitNumber(number) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): LearningRateMultiplier = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitAuto(auto: JsonValue) { + auto.let { + if (it != JsonValue.from("auto")) { + throw OpenAIInvalidDataException("'auto' is invalid, received $it") + } + } + } + + override fun visitNumber(number: Double) {} + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitAuto(auto: JsonValue) = + auto.let { if (it == JsonValue.from("auto")) 1 else 0 } + + override fun visitNumber(number: Double) = 1 + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is LearningRateMultiplier && auto == other.auto && number == other.number /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(auto, number) /* spotless:on */ + + override fun toString(): String = + when { + auto != null -> "LearningRateMultiplier{auto=$auto}" + number != null -> "LearningRateMultiplier{number=$number}" + _json != null -> "LearningRateMultiplier{_unknown=$_json}" + else -> throw IllegalStateException("Invalid LearningRateMultiplier") + } + + companion object { + + @JvmStatic fun ofAuto() = LearningRateMultiplier(auto = JsonValue.from("auto")) + + @JvmStatic fun ofNumber(number: Double) = LearningRateMultiplier(number = number) + } + + /** + * An interface that defines how to map each variant of [LearningRateMultiplier] to a value + * of type [T]. + */ + interface Visitor { + + fun visitAuto(auto: JsonValue): T + + fun visitNumber(number: Double): T + + /** + * Maps an unknown variant of [LearningRateMultiplier] to a value of type [T]. + * + * An instance of [LearningRateMultiplier] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For example, if the SDK + * is on an older version than the API, then the API may respond with new variants that + * the SDK is unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown LearningRateMultiplier: $json") + } + } + + internal class Deserializer : + BaseDeserializer(LearningRateMultiplier::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): LearningRateMultiplier { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef()) + ?.let { LearningRateMultiplier(auto = it, _json = json) } + ?.takeIf { it.isValid() }, + tryDeserialize(node, jacksonTypeRef())?.let { + LearningRateMultiplier(number = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with + // all the possible variants (e.g. deserializing from object). + 0 -> LearningRateMultiplier(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely + // valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : + BaseSerializer(LearningRateMultiplier::class) { + + override fun serialize( + value: LearningRateMultiplier, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.auto != null -> generator.writeObject(value.auto) + value.number != null -> generator.writeObject(value.number) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid LearningRateMultiplier") + } + } + } + } + + /** + * The number of epochs to train the model for. An epoch refers to one full cycle through the + * training dataset. + */ + @JsonDeserialize(using = NEpochs.Deserializer::class) + @JsonSerialize(using = NEpochs.Serializer::class) + class NEpochs + private constructor( + private val auto: JsonValue? = null, + private val integer: Long? = null, + private val _json: JsonValue? = null, + ) { + + fun auto(): Optional = Optional.ofNullable(auto) + + fun integer(): Optional = Optional.ofNullable(integer) + + fun isAuto(): Boolean = auto != null + + fun isInteger(): Boolean = integer != null + + fun asAuto(): JsonValue = auto.getOrThrow("auto") + + fun asInteger(): Long = integer.getOrThrow("integer") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + auto != null -> visitor.visitAuto(auto) + integer != null -> visitor.visitInteger(integer) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): NEpochs = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitAuto(auto: JsonValue) { + auto.let { + if (it != JsonValue.from("auto")) { + throw OpenAIInvalidDataException("'auto' is invalid, received $it") + } + } + } + + override fun visitInteger(integer: Long) {} + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitAuto(auto: JsonValue) = + auto.let { if (it == JsonValue.from("auto")) 1 else 0 } + + override fun visitInteger(integer: Long) = 1 + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is NEpochs && auto == other.auto && integer == other.integer /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(auto, integer) /* spotless:on */ + + override fun toString(): String = + when { + auto != null -> "NEpochs{auto=$auto}" + integer != null -> "NEpochs{integer=$integer}" + _json != null -> "NEpochs{_unknown=$_json}" + else -> throw IllegalStateException("Invalid NEpochs") + } + + companion object { + + @JvmStatic fun ofAuto() = NEpochs(auto = JsonValue.from("auto")) + + @JvmStatic fun ofInteger(integer: Long) = NEpochs(integer = integer) + } + + /** + * An interface that defines how to map each variant of [NEpochs] to a value of type [T]. + */ + interface Visitor { + + fun visitAuto(auto: JsonValue): T + + fun visitInteger(integer: Long): T + + /** + * Maps an unknown variant of [NEpochs] to a value of type [T]. + * + * An instance of [NEpochs] can contain an unknown variant if it was deserialized from + * data that doesn't match any known variant. For example, if the SDK is on an older + * version than the API, then the API may respond with new variants that the SDK is + * unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown NEpochs: $json") + } + } + + internal class Deserializer : BaseDeserializer(NEpochs::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): NEpochs { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef()) + ?.let { NEpochs(auto = it, _json = json) } + ?.takeIf { it.isValid() }, + tryDeserialize(node, jacksonTypeRef())?.let { + NEpochs(integer = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with + // all the possible variants (e.g. deserializing from object). + 0 -> NEpochs(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely + // valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(NEpochs::class) { + + override fun serialize( + value: NEpochs, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.auto != null -> generator.writeObject(value.auto) + value.integer != null -> generator.writeObject(value.integer) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid NEpochs") + } + } + } + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is SupervisedHyperparameters && batchSize == other.batchSize && learningRateMultiplier == other.learningRateMultiplier && nEpochs == other.nEpochs && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(batchSize, learningRateMultiplier, nEpochs, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "SupervisedHyperparameters{batchSize=$batchSize, learningRateMultiplier=$learningRateMultiplier, nEpochs=$nEpochs, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/finetuning/methods/SupervisedMethod.kt b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/methods/SupervisedMethod.kt new file mode 100644 index 00000000..e6aa5f12 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/finetuning/methods/SupervisedMethod.kt @@ -0,0 +1,167 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.finetuning.methods + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Configuration for the supervised fine-tuning method. */ +class SupervisedMethod +private constructor( + private val hyperparameters: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("hyperparameters") + @ExcludeMissing + hyperparameters: JsonField = JsonMissing.of() + ) : this(hyperparameters, mutableMapOf()) + + /** + * The hyperparameters used for the fine-tuning job. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun hyperparameters(): Optional = + hyperparameters.getOptional("hyperparameters") + + /** + * Returns the raw JSON value of [hyperparameters]. + * + * Unlike [hyperparameters], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("hyperparameters") + @ExcludeMissing + fun _hyperparameters(): JsonField = hyperparameters + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [SupervisedMethod]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SupervisedMethod]. */ + class Builder internal constructor() { + + private var hyperparameters: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(supervisedMethod: SupervisedMethod) = apply { + hyperparameters = supervisedMethod.hyperparameters + additionalProperties = supervisedMethod.additionalProperties.toMutableMap() + } + + /** The hyperparameters used for the fine-tuning job. */ + fun hyperparameters(hyperparameters: SupervisedHyperparameters) = + hyperparameters(JsonField.of(hyperparameters)) + + /** + * Sets [Builder.hyperparameters] to an arbitrary JSON value. + * + * You should usually call [Builder.hyperparameters] with a well-typed + * [SupervisedHyperparameters] value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ + fun hyperparameters(hyperparameters: JsonField) = apply { + this.hyperparameters = hyperparameters + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [SupervisedMethod]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): SupervisedMethod = + SupervisedMethod(hyperparameters, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): SupervisedMethod = apply { + if (validated) { + return@apply + } + + hyperparameters().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = (hyperparameters.asKnown().getOrNull()?.validity() ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is SupervisedMethod && hyperparameters == other.hyperparameters && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(hyperparameters, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "SupervisedMethod{hyperparameters=$hyperparameters, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalLabelModelGrader.kt b/openai-java-core/src/main/kotlin/com/openai/models/graders/gradermodels/LabelModelGrader.kt similarity index 97% rename from openai-java-core/src/main/kotlin/com/openai/models/evals/EvalLabelModelGrader.kt rename to openai-java-core/src/main/kotlin/com/openai/models/graders/gradermodels/LabelModelGrader.kt index 7576d0c9..e29ecd15 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalLabelModelGrader.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/graders/gradermodels/LabelModelGrader.kt @@ -1,6 +1,6 @@ // File generated from our OpenAPI spec by Stainless. -package com.openai.models.evals +package com.openai.models.graders.gradermodels import com.fasterxml.jackson.annotation.JsonAnyGetter import com.fasterxml.jackson.annotation.JsonAnySetter @@ -33,7 +33,7 @@ import java.util.Optional import kotlin.jvm.optionals.getOrNull /** A LabelModelGrader object which uses a model to assign labels to each item in the evaluation. */ -class EvalLabelModelGrader +class LabelModelGrader private constructor( private val input: JsonField>, private val labels: JsonField>, @@ -159,7 +159,7 @@ private constructor( companion object { /** - * Returns a mutable builder for constructing an instance of [EvalLabelModelGrader]. + * Returns a mutable builder for constructing an instance of [LabelModelGrader]. * * The following fields are required: * ```java @@ -173,7 +173,7 @@ private constructor( @JvmStatic fun builder() = Builder() } - /** A builder for [EvalLabelModelGrader]. */ + /** A builder for [LabelModelGrader]. */ class Builder internal constructor() { private var input: JsonField>? = null @@ -185,14 +185,14 @@ private constructor( private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(evalLabelModelGrader: EvalLabelModelGrader) = apply { - input = evalLabelModelGrader.input.map { it.toMutableList() } - labels = evalLabelModelGrader.labels.map { it.toMutableList() } - model = evalLabelModelGrader.model - name = evalLabelModelGrader.name - passingLabels = evalLabelModelGrader.passingLabels.map { it.toMutableList() } - type = evalLabelModelGrader.type - additionalProperties = evalLabelModelGrader.additionalProperties.toMutableMap() + internal fun from(labelModelGrader: LabelModelGrader) = apply { + input = labelModelGrader.input.map { it.toMutableList() } + labels = labelModelGrader.labels.map { it.toMutableList() } + model = labelModelGrader.model + name = labelModelGrader.name + passingLabels = labelModelGrader.passingLabels.map { it.toMutableList() } + type = labelModelGrader.type + additionalProperties = labelModelGrader.additionalProperties.toMutableMap() } fun input(input: List) = input(JsonField.of(input)) @@ -328,7 +328,7 @@ private constructor( } /** - * Returns an immutable instance of [EvalLabelModelGrader]. + * Returns an immutable instance of [LabelModelGrader]. * * Further updates to this [Builder] will not mutate the returned instance. * @@ -343,8 +343,8 @@ private constructor( * * @throws IllegalStateException if any required field is unset. */ - fun build(): EvalLabelModelGrader = - EvalLabelModelGrader( + fun build(): LabelModelGrader = + LabelModelGrader( checkRequired("input", input).map { it.toImmutable() }, checkRequired("labels", labels).map { it.toImmutable() }, checkRequired("model", model), @@ -357,7 +357,7 @@ private constructor( private var validated: Boolean = false - fun validate(): EvalLabelModelGrader = apply { + fun validate(): LabelModelGrader = apply { if (validated) { return@apply } @@ -1335,7 +1335,7 @@ private constructor( return true } - return /* spotless:off */ other is EvalLabelModelGrader && input == other.input && labels == other.labels && model == other.model && name == other.name && passingLabels == other.passingLabels && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ + return /* spotless:off */ other is LabelModelGrader && input == other.input && labels == other.labels && model == other.model && name == other.name && passingLabels == other.passingLabels && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ } /* spotless:off */ @@ -1345,5 +1345,5 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "EvalLabelModelGrader{input=$input, labels=$labels, model=$model, name=$name, passingLabels=$passingLabels, type=$type, additionalProperties=$additionalProperties}" + "LabelModelGrader{input=$input, labels=$labels, model=$model, name=$name, passingLabels=$passingLabels, type=$type, additionalProperties=$additionalProperties}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/graders/gradermodels/MultiGrader.kt b/openai-java-core/src/main/kotlin/com/openai/models/graders/gradermodels/MultiGrader.kt new file mode 100644 index 00000000..8b950189 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/graders/gradermodels/MultiGrader.kt @@ -0,0 +1,391 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.graders.gradermodels + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.checkRequired +import com.openai.core.toImmutable +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import kotlin.jvm.optionals.getOrNull + +/** A MultiGrader object combines the output of multiple graders to produce a single score. */ +class MultiGrader +private constructor( + private val calculateOutput: JsonField, + private val graders: JsonField, + private val name: JsonField, + private val type: JsonValue, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("calculate_output") + @ExcludeMissing + calculateOutput: JsonField = JsonMissing.of(), + @JsonProperty("graders") @ExcludeMissing graders: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + ) : this(calculateOutput, graders, name, type, mutableMapOf()) + + /** + * A formula to calculate the output based on grader results. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun calculateOutput(): String = calculateOutput.getRequired("calculate_output") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun graders(): Graders = graders.getRequired("graders") + + /** + * The name of the grader. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun name(): String = name.getRequired("name") + + /** + * The type of grader. + * + * Expected to always return the following: + * ```java + * JsonValue.from("multi") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server responded + * with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * Returns the raw JSON value of [calculateOutput]. + * + * Unlike [calculateOutput], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("calculate_output") + @ExcludeMissing + fun _calculateOutput(): JsonField = calculateOutput + + /** + * Returns the raw JSON value of [graders]. + * + * Unlike [graders], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("graders") @ExcludeMissing fun _graders(): JsonField = graders + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [MultiGrader]. + * + * The following fields are required: + * ```java + * .calculateOutput() + * .graders() + * .name() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [MultiGrader]. */ + class Builder internal constructor() { + + private var calculateOutput: JsonField? = null + private var graders: JsonField? = null + private var name: JsonField? = null + private var type: JsonValue = JsonValue.from("multi") + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(multiGrader: MultiGrader) = apply { + calculateOutput = multiGrader.calculateOutput + graders = multiGrader.graders + name = multiGrader.name + type = multiGrader.type + additionalProperties = multiGrader.additionalProperties.toMutableMap() + } + + /** A formula to calculate the output based on grader results. */ + fun calculateOutput(calculateOutput: String) = + calculateOutput(JsonField.of(calculateOutput)) + + /** + * Sets [Builder.calculateOutput] to an arbitrary JSON value. + * + * You should usually call [Builder.calculateOutput] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun calculateOutput(calculateOutput: JsonField) = apply { + this.calculateOutput = calculateOutput + } + + fun graders(graders: Graders) = graders(JsonField.of(graders)) + + /** + * Sets [Builder.graders] to an arbitrary JSON value. + * + * You should usually call [Builder.graders] with a well-typed [Graders] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun graders(graders: JsonField) = apply { this.graders = graders } + + /** The name of the grader. */ + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("multi") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [MultiGrader]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .calculateOutput() + * .graders() + * .name() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): MultiGrader = + MultiGrader( + checkRequired("calculateOutput", calculateOutput), + checkRequired("graders", graders), + checkRequired("name", name), + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): MultiGrader = apply { + if (validated) { + return@apply + } + + calculateOutput() + graders().validate() + name() + _type().let { + if (it != JsonValue.from("multi")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (calculateOutput.asKnown().isPresent) 1 else 0) + + (graders.asKnown().getOrNull()?.validity() ?: 0) + + (if (name.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("multi")) 1 else 0 } + + class Graders + @JsonCreator + private constructor( + @com.fasterxml.jackson.annotation.JsonValue + private val additionalProperties: Map + ) { + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Graders]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Graders]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(graders: Graders) = apply { + additionalProperties = graders.additionalProperties.toMutableMap() + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Graders]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Graders = Graders(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Graders = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + additionalProperties.count { (_, value) -> !value.isNull() && !value.isMissing() } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Graders && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = "Graders{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is MultiGrader && calculateOutput == other.calculateOutput && graders == other.graders && name == other.name && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(calculateOutput, graders, name, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "MultiGrader{calculateOutput=$calculateOutput, graders=$graders, name=$name, type=$type, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/graders/gradermodels/PythonGrader.kt b/openai-java-core/src/main/kotlin/com/openai/models/graders/gradermodels/PythonGrader.kt new file mode 100644 index 00000000..6aef3d56 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/graders/gradermodels/PythonGrader.kt @@ -0,0 +1,282 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.graders.gradermodels + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.checkRequired +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional + +/** A PythonGrader object that runs a python script on the input. */ +class PythonGrader +private constructor( + private val name: JsonField, + private val source: JsonField, + private val type: JsonValue, + private val imageTag: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("source") @ExcludeMissing source: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + @JsonProperty("image_tag") @ExcludeMissing imageTag: JsonField = JsonMissing.of(), + ) : this(name, source, type, imageTag, mutableMapOf()) + + /** + * The name of the grader. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun name(): String = name.getRequired("name") + + /** + * The source code of the python script. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun source(): String = source.getRequired("source") + + /** + * The object type, which is always `python`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("python") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server responded + * with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * The image tag to use for the python script. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun imageTag(): Optional = imageTag.getOptional("image_tag") + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [source]. + * + * Unlike [source], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("source") @ExcludeMissing fun _source(): JsonField = source + + /** + * Returns the raw JSON value of [imageTag]. + * + * Unlike [imageTag], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("image_tag") @ExcludeMissing fun _imageTag(): JsonField = imageTag + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [PythonGrader]. + * + * The following fields are required: + * ```java + * .name() + * .source() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [PythonGrader]. */ + class Builder internal constructor() { + + private var name: JsonField? = null + private var source: JsonField? = null + private var type: JsonValue = JsonValue.from("python") + private var imageTag: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(pythonGrader: PythonGrader) = apply { + name = pythonGrader.name + source = pythonGrader.source + type = pythonGrader.type + imageTag = pythonGrader.imageTag + additionalProperties = pythonGrader.additionalProperties.toMutableMap() + } + + /** The name of the grader. */ + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** The source code of the python script. */ + fun source(source: String) = source(JsonField.of(source)) + + /** + * Sets [Builder.source] to an arbitrary JSON value. + * + * You should usually call [Builder.source] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun source(source: JsonField) = apply { this.source = source } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("python") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + /** The image tag to use for the python script. */ + fun imageTag(imageTag: String) = imageTag(JsonField.of(imageTag)) + + /** + * Sets [Builder.imageTag] to an arbitrary JSON value. + * + * You should usually call [Builder.imageTag] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun imageTag(imageTag: JsonField) = apply { this.imageTag = imageTag } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [PythonGrader]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * .source() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): PythonGrader = + PythonGrader( + checkRequired("name", name), + checkRequired("source", source), + type, + imageTag, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): PythonGrader = apply { + if (validated) { + return@apply + } + + name() + source() + _type().let { + if (it != JsonValue.from("python")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + imageTag() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (name.asKnown().isPresent) 1 else 0) + + (if (source.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("python")) 1 else 0 } + + (if (imageTag.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is PythonGrader && name == other.name && source == other.source && type == other.type && imageTag == other.imageTag && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, source, type, imageTag, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "PythonGrader{name=$name, source=$source, type=$type, imageTag=$imageTag, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/graders/gradermodels/ScoreModelGrader.kt b/openai-java-core/src/main/kotlin/com/openai/models/graders/gradermodels/ScoreModelGrader.kt new file mode 100644 index 00000000..b6dc3c82 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/graders/gradermodels/ScoreModelGrader.kt @@ -0,0 +1,1313 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.graders.gradermodels + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.BaseDeserializer +import com.openai.core.BaseSerializer +import com.openai.core.Enum +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.allMaxBy +import com.openai.core.checkKnown +import com.openai.core.checkRequired +import com.openai.core.getOrThrow +import com.openai.core.toImmutable +import com.openai.errors.OpenAIInvalidDataException +import com.openai.models.responses.ResponseInputText +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** A ScoreModelGrader object that uses a model to assign a score to the input. */ +class ScoreModelGrader +private constructor( + private val input: JsonField>, + private val model: JsonField, + private val name: JsonField, + private val type: JsonValue, + private val range: JsonField>, + private val samplingParams: JsonValue, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("input") @ExcludeMissing input: JsonField> = JsonMissing.of(), + @JsonProperty("model") @ExcludeMissing model: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + @JsonProperty("range") @ExcludeMissing range: JsonField> = JsonMissing.of(), + @JsonProperty("sampling_params") + @ExcludeMissing + samplingParams: JsonValue = JsonMissing.of(), + ) : this(input, model, name, type, range, samplingParams, mutableMapOf()) + + /** + * The input text. This may include template strings. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun input(): List = input.getRequired("input") + + /** + * The model to use for the evaluation. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun model(): String = model.getRequired("model") + + /** + * The name of the grader. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun name(): String = name.getRequired("name") + + /** + * The object type, which is always `score_model`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("score_model") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server responded + * with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * The range of the score. Defaults to `[0, 1]`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun range(): Optional> = range.getOptional("range") + + /** The sampling parameters for the model. */ + @JsonProperty("sampling_params") + @ExcludeMissing + fun _samplingParams(): JsonValue = samplingParams + + /** + * Returns the raw JSON value of [input]. + * + * Unlike [input], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("input") @ExcludeMissing fun _input(): JsonField> = input + + /** + * 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 = model + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [range]. + * + * Unlike [range], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("range") @ExcludeMissing fun _range(): JsonField> = range + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [ScoreModelGrader]. + * + * The following fields are required: + * ```java + * .input() + * .model() + * .name() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ScoreModelGrader]. */ + class Builder internal constructor() { + + private var input: JsonField>? = null + private var model: JsonField? = null + private var name: JsonField? = null + private var type: JsonValue = JsonValue.from("score_model") + private var range: JsonField>? = null + private var samplingParams: JsonValue = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(scoreModelGrader: ScoreModelGrader) = apply { + input = scoreModelGrader.input.map { it.toMutableList() } + model = scoreModelGrader.model + name = scoreModelGrader.name + type = scoreModelGrader.type + range = scoreModelGrader.range.map { it.toMutableList() } + samplingParams = scoreModelGrader.samplingParams + additionalProperties = scoreModelGrader.additionalProperties.toMutableMap() + } + + /** The input text. This may include template strings. */ + fun input(input: List) = input(JsonField.of(input)) + + /** + * Sets [Builder.input] to an arbitrary JSON value. + * + * You should usually call [Builder.input] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun input(input: JsonField>) = apply { + this.input = input.map { it.toMutableList() } + } + + /** + * Adds a single [Input] to [Builder.input]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addInput(input: Input) = apply { + this.input = + (this.input ?: JsonField.of(mutableListOf())).also { + checkKnown("input", it).add(input) + } + } + + /** The model to use for the evaluation. */ + 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) = apply { this.model = model } + + /** The name of the grader. */ + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("score_model") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + /** The range of the score. Defaults to `[0, 1]`. */ + fun range(range: List) = range(JsonField.of(range)) + + /** + * Sets [Builder.range] to an arbitrary JSON value. + * + * You should usually call [Builder.range] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun range(range: JsonField>) = apply { + this.range = range.map { it.toMutableList() } + } + + /** + * Adds a single [Double] to [Builder.range]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addRange(range: Double) = apply { + this.range = + (this.range ?: JsonField.of(mutableListOf())).also { + checkKnown("range", it).add(range) + } + } + + /** The sampling parameters for the model. */ + fun samplingParams(samplingParams: JsonValue) = apply { + this.samplingParams = samplingParams + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [ScoreModelGrader]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .input() + * .model() + * .name() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ScoreModelGrader = + ScoreModelGrader( + checkRequired("input", input).map { it.toImmutable() }, + checkRequired("model", model), + checkRequired("name", name), + type, + (range ?: JsonMissing.of()).map { it.toImmutable() }, + samplingParams, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): ScoreModelGrader = apply { + if (validated) { + return@apply + } + + input().forEach { it.validate() } + model() + name() + _type().let { + if (it != JsonValue.from("score_model")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + range() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (input.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (model.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("score_model")) 1 else 0 } + + (range.asKnown().getOrNull()?.size ?: 0) + + /** + * A message input to the model with a role indicating instruction following hierarchy. + * Instructions given with the `developer` or `system` role take precedence over instructions + * given with the `user` role. Messages with the `assistant` role are presumed to have been + * generated by the model in previous interactions. + */ + class Input + private constructor( + private val content: JsonField, + private val role: JsonField, + private val type: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("content") @ExcludeMissing content: JsonField = JsonMissing.of(), + @JsonProperty("role") @ExcludeMissing role: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + ) : this(content, role, type, mutableMapOf()) + + /** + * Text inputs to the model - can contain template strings. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun content(): Content = content.getRequired("content") + + /** + * The role of the message input. One of `user`, `assistant`, `system`, or `developer`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun role(): Role = role.getRequired("role") + + /** + * The type of the message input. Always `message`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun type(): Optional = type.getOptional("type") + + /** + * Returns the raw JSON value of [content]. + * + * Unlike [content], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("content") @ExcludeMissing fun _content(): JsonField = content + + /** + * Returns the raw JSON value of [role]. + * + * Unlike [role], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("role") @ExcludeMissing fun _role(): JsonField = role + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Input]. + * + * The following fields are required: + * ```java + * .content() + * .role() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Input]. */ + class Builder internal constructor() { + + private var content: JsonField? = null + private var role: JsonField? = null + private var type: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(input: Input) = apply { + content = input.content + role = input.role + type = input.type + additionalProperties = input.additionalProperties.toMutableMap() + } + + /** Text inputs to the model - can contain template strings. */ + fun content(content: Content) = content(JsonField.of(content)) + + /** + * Sets [Builder.content] to an arbitrary JSON value. + * + * You should usually call [Builder.content] with a well-typed [Content] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun content(content: JsonField) = apply { this.content = content } + + /** Alias for calling [content] with `Content.ofTextInput(textInput)`. */ + fun content(textInput: String) = content(Content.ofTextInput(textInput)) + + /** + * Alias for calling [content] with `Content.ofResponseInputText(responseInputText)`. + */ + fun content(responseInputText: ResponseInputText) = + content(Content.ofResponseInputText(responseInputText)) + + /** Alias for calling [content] with `Content.ofOutputText(outputText)`. */ + fun content(outputText: Content.OutputText) = content(Content.ofOutputText(outputText)) + + /** + * The role of the message input. One of `user`, `assistant`, `system`, or `developer`. + */ + fun role(role: Role) = role(JsonField.of(role)) + + /** + * Sets [Builder.role] to an arbitrary JSON value. + * + * You should usually call [Builder.role] with a well-typed [Role] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun role(role: JsonField) = apply { this.role = role } + + /** The type of the message input. Always `message`. */ + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonField) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Input]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .content() + * .role() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Input = + Input( + checkRequired("content", content), + checkRequired("role", role), + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Input = apply { + if (validated) { + return@apply + } + + content().validate() + role().validate() + type().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (content.asKnown().getOrNull()?.validity() ?: 0) + + (role.asKnown().getOrNull()?.validity() ?: 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + /** Text inputs to the model - can contain template strings. */ + @JsonDeserialize(using = Content.Deserializer::class) + @JsonSerialize(using = Content.Serializer::class) + class Content + private constructor( + private val textInput: String? = null, + private val responseInputText: ResponseInputText? = null, + private val outputText: OutputText? = null, + private val _json: JsonValue? = null, + ) { + + /** A text input to the model. */ + fun textInput(): Optional = Optional.ofNullable(textInput) + + /** A text input to the model. */ + fun responseInputText(): Optional = + Optional.ofNullable(responseInputText) + + /** A text output from the model. */ + fun outputText(): Optional = Optional.ofNullable(outputText) + + fun isTextInput(): Boolean = textInput != null + + fun isResponseInputText(): Boolean = responseInputText != null + + fun isOutputText(): Boolean = outputText != null + + /** A text input to the model. */ + fun asTextInput(): String = textInput.getOrThrow("textInput") + + /** A text input to the model. */ + fun asResponseInputText(): ResponseInputText = + responseInputText.getOrThrow("responseInputText") + + /** A text output from the model. */ + fun asOutputText(): OutputText = outputText.getOrThrow("outputText") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + textInput != null -> visitor.visitTextInput(textInput) + responseInputText != null -> visitor.visitResponseInputText(responseInputText) + outputText != null -> visitor.visitOutputText(outputText) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): Content = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitTextInput(textInput: String) {} + + override fun visitResponseInputText(responseInputText: ResponseInputText) { + responseInputText.validate() + } + + override fun visitOutputText(outputText: OutputText) { + outputText.validate() + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitTextInput(textInput: String) = 1 + + override fun visitResponseInputText(responseInputText: ResponseInputText) = + responseInputText.validity() + + override fun visitOutputText(outputText: OutputText) = outputText.validity() + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Content && textInput == other.textInput && responseInputText == other.responseInputText && outputText == other.outputText /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(textInput, responseInputText, outputText) /* spotless:on */ + + override fun toString(): String = + when { + textInput != null -> "Content{textInput=$textInput}" + responseInputText != null -> "Content{responseInputText=$responseInputText}" + outputText != null -> "Content{outputText=$outputText}" + _json != null -> "Content{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Content") + } + + companion object { + + /** A text input to the model. */ + @JvmStatic fun ofTextInput(textInput: String) = Content(textInput = textInput) + + /** A text input to the model. */ + @JvmStatic + fun ofResponseInputText(responseInputText: ResponseInputText) = + Content(responseInputText = responseInputText) + + /** A text output from the model. */ + @JvmStatic + fun ofOutputText(outputText: OutputText) = Content(outputText = outputText) + } + + /** + * An interface that defines how to map each variant of [Content] to a value of type + * [T]. + */ + interface Visitor { + + /** A text input to the model. */ + fun visitTextInput(textInput: String): T + + /** A text input to the model. */ + fun visitResponseInputText(responseInputText: ResponseInputText): T + + /** A text output from the model. */ + fun visitOutputText(outputText: OutputText): T + + /** + * Maps an unknown variant of [Content] to a value of type [T]. + * + * An instance of [Content] can contain an unknown variant if it was deserialized + * from data that doesn't match any known variant. For example, if the SDK is on an + * older version than the API, then the API may respond with new variants that the + * SDK is unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown Content: $json") + } + } + + internal class Deserializer : BaseDeserializer(Content::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): Content { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + Content(responseInputText = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + Content(outputText = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + Content(textInput = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible + // with all the possible variants (e.g. deserializing from array). + 0 -> Content(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the + // first completely valid match, or simply the first match if none are + // completely valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(Content::class) { + + override fun serialize( + value: Content, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.textInput != null -> generator.writeObject(value.textInput) + value.responseInputText != null -> + generator.writeObject(value.responseInputText) + value.outputText != null -> generator.writeObject(value.outputText) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Content") + } + } + } + + /** A text output from the model. */ + class OutputText + private constructor( + private val text: JsonField, + private val type: JsonValue, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("text") + @ExcludeMissing + text: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + ) : this(text, type, mutableMapOf()) + + /** + * The text output from the model. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun text(): String = text.getRequired("text") + + /** + * The type of the output text. Always `output_text`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("output_text") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * Returns the raw JSON value of [text]. + * + * Unlike [text], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("text") @ExcludeMissing fun _text(): JsonField = text + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [OutputText]. + * + * The following fields are required: + * ```java + * .text() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [OutputText]. */ + class Builder internal constructor() { + + private var text: JsonField? = null + private var type: JsonValue = JsonValue.from("output_text") + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(outputText: OutputText) = apply { + text = outputText.text + type = outputText.type + additionalProperties = outputText.additionalProperties.toMutableMap() + } + + /** The text output from the model. */ + fun text(text: String) = text(JsonField.of(text)) + + /** + * Sets [Builder.text] to an arbitrary JSON value. + * + * You should usually call [Builder.text] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun text(text: JsonField) = apply { this.text = text } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to + * the following: + * ```java + * JsonValue.from("output_text") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [OutputText]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .text() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): OutputText = + OutputText( + checkRequired("text", text), + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): OutputText = apply { + if (validated) { + return@apply + } + + text() + _type().let { + if (it != JsonValue.from("output_text")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (text.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("output_text")) 1 else 0 } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is OutputText && text == other.text && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(text, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "OutputText{text=$text, type=$type, additionalProperties=$additionalProperties}" + } + } + + /** The role of the message input. One of `user`, `assistant`, `system`, or `developer`. */ + class Role @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val USER = of("user") + + @JvmField val ASSISTANT = of("assistant") + + @JvmField val SYSTEM = of("system") + + @JvmField val DEVELOPER = of("developer") + + @JvmStatic fun of(value: String) = Role(JsonField.of(value)) + } + + /** An enum containing [Role]'s known values. */ + enum class Known { + USER, + ASSISTANT, + SYSTEM, + DEVELOPER, + } + + /** + * An enum containing [Role]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Role] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + USER, + ASSISTANT, + SYSTEM, + DEVELOPER, + /** An enum member indicating that [Role] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you + * want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + USER -> Value.USER + ASSISTANT -> Value.ASSISTANT + SYSTEM -> Value.SYSTEM + DEVELOPER -> Value.DEVELOPER + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + USER -> Known.USER + ASSISTANT -> Known.ASSISTANT + SYSTEM -> Known.SYSTEM + DEVELOPER -> Known.DEVELOPER + else -> throw OpenAIInvalidDataException("Unknown Role: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + OpenAIInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Role = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Role && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** The type of the message input. Always `message`. */ + class Type @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val MESSAGE = of("message") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + MESSAGE + } + + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + MESSAGE, + /** An enum member indicating that [Type] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you + * want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + MESSAGE -> Value.MESSAGE + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + MESSAGE -> Known.MESSAGE + else -> throw OpenAIInvalidDataException("Unknown Type: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + OpenAIInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Type = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Input && content == other.content && role == other.role && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(content, role, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Input{content=$content, role=$role, type=$type, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ScoreModelGrader && input == other.input && model == other.model && name == other.name && type == other.type && range == other.range && samplingParams == other.samplingParams && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(input, model, name, type, range, samplingParams, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ScoreModelGrader{input=$input, model=$model, name=$name, type=$type, range=$range, samplingParams=$samplingParams, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalStringCheckGrader.kt b/openai-java-core/src/main/kotlin/com/openai/models/graders/gradermodels/StringCheckGrader.kt similarity index 92% rename from openai-java-core/src/main/kotlin/com/openai/models/evals/EvalStringCheckGrader.kt rename to openai-java-core/src/main/kotlin/com/openai/models/graders/gradermodels/StringCheckGrader.kt index e1279a14..34bf9216 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalStringCheckGrader.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/graders/gradermodels/StringCheckGrader.kt @@ -1,6 +1,6 @@ // File generated from our OpenAPI spec by Stainless. -package com.openai.models.evals +package com.openai.models.graders.gradermodels import com.fasterxml.jackson.annotation.JsonAnyGetter import com.fasterxml.jackson.annotation.JsonAnySetter @@ -21,7 +21,7 @@ import kotlin.jvm.optionals.getOrNull * A StringCheckGrader object that performs a string comparison between input and reference using a * specified operation. */ -class EvalStringCheckGrader +class StringCheckGrader private constructor( private val input: JsonField, private val name: JsonField, @@ -130,7 +130,7 @@ private constructor( companion object { /** - * Returns a mutable builder for constructing an instance of [EvalStringCheckGrader]. + * Returns a mutable builder for constructing an instance of [StringCheckGrader]. * * The following fields are required: * ```java @@ -143,7 +143,7 @@ private constructor( @JvmStatic fun builder() = Builder() } - /** A builder for [EvalStringCheckGrader]. */ + /** A builder for [StringCheckGrader]. */ class Builder internal constructor() { private var input: JsonField? = null @@ -154,13 +154,13 @@ private constructor( private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(evalStringCheckGrader: EvalStringCheckGrader) = apply { - input = evalStringCheckGrader.input - name = evalStringCheckGrader.name - operation = evalStringCheckGrader.operation - reference = evalStringCheckGrader.reference - type = evalStringCheckGrader.type - additionalProperties = evalStringCheckGrader.additionalProperties.toMutableMap() + internal fun from(stringCheckGrader: StringCheckGrader) = apply { + input = stringCheckGrader.input + name = stringCheckGrader.name + operation = stringCheckGrader.operation + reference = stringCheckGrader.reference + type = stringCheckGrader.type + additionalProperties = stringCheckGrader.additionalProperties.toMutableMap() } /** The input text. This may include template strings. */ @@ -243,7 +243,7 @@ private constructor( } /** - * Returns an immutable instance of [EvalStringCheckGrader]. + * Returns an immutable instance of [StringCheckGrader]. * * Further updates to this [Builder] will not mutate the returned instance. * @@ -257,8 +257,8 @@ private constructor( * * @throws IllegalStateException if any required field is unset. */ - fun build(): EvalStringCheckGrader = - EvalStringCheckGrader( + fun build(): StringCheckGrader = + StringCheckGrader( checkRequired("input", input), checkRequired("name", name), checkRequired("operation", operation), @@ -270,7 +270,7 @@ private constructor( private var validated: Boolean = false - fun validate(): EvalStringCheckGrader = apply { + fun validate(): StringCheckGrader = apply { if (validated) { return@apply } @@ -453,7 +453,7 @@ private constructor( return true } - return /* spotless:off */ other is EvalStringCheckGrader && input == other.input && name == other.name && operation == other.operation && reference == other.reference && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ + return /* spotless:off */ other is StringCheckGrader && input == other.input && name == other.name && operation == other.operation && reference == other.reference && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ } /* spotless:off */ @@ -463,5 +463,5 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "EvalStringCheckGrader{input=$input, name=$name, operation=$operation, reference=$reference, type=$type, additionalProperties=$additionalProperties}" + "StringCheckGrader{input=$input, name=$name, operation=$operation, reference=$reference, type=$type, additionalProperties=$additionalProperties}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalTextSimilarityGrader.kt b/openai-java-core/src/main/kotlin/com/openai/models/graders/gradermodels/TextSimilarityGrader.kt similarity index 82% rename from openai-java-core/src/main/kotlin/com/openai/models/evals/EvalTextSimilarityGrader.kt rename to openai-java-core/src/main/kotlin/com/openai/models/graders/gradermodels/TextSimilarityGrader.kt index 271cc2c2..a72392d4 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalTextSimilarityGrader.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/graders/gradermodels/TextSimilarityGrader.kt @@ -1,6 +1,6 @@ // File generated from our OpenAPI spec by Stainless. -package com.openai.models.evals +package com.openai.models.graders.gradermodels import com.fasterxml.jackson.annotation.JsonAnyGetter import com.fasterxml.jackson.annotation.JsonAnySetter @@ -15,18 +15,16 @@ import com.openai.core.checkRequired import com.openai.errors.OpenAIInvalidDataException import java.util.Collections import java.util.Objects -import java.util.Optional import kotlin.jvm.optionals.getOrNull /** A TextSimilarityGrader object which grades text based on similarity metrics. */ -class EvalTextSimilarityGrader +class TextSimilarityGrader private constructor( private val evaluationMetric: JsonField, private val input: JsonField, - private val passThreshold: JsonField, + private val name: JsonField, private val reference: JsonField, private val type: JsonValue, - private val name: JsonField, private val additionalProperties: MutableMap, ) { @@ -36,13 +34,10 @@ private constructor( @ExcludeMissing evaluationMetric: JsonField = JsonMissing.of(), @JsonProperty("input") @ExcludeMissing input: JsonField = JsonMissing.of(), - @JsonProperty("pass_threshold") - @ExcludeMissing - passThreshold: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), @JsonProperty("reference") @ExcludeMissing reference: JsonField = JsonMissing.of(), @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), - @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), - ) : this(evaluationMetric, input, passThreshold, reference, type, name, mutableMapOf()) + ) : this(evaluationMetric, input, name, reference, type, mutableMapOf()) /** * The evaluation metric to use. One of `fuzzy_match`, `bleu`, `gleu`, `meteor`, `rouge_1`, @@ -62,12 +57,12 @@ private constructor( fun input(): String = input.getRequired("input") /** - * A float score where a value greater than or equal indicates a passing grade. + * The name of the grader. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected value). */ - fun passThreshold(): Double = passThreshold.getRequired("pass_threshold") + fun name(): String = name.getRequired("name") /** * The text being graded against. @@ -90,14 +85,6 @@ private constructor( */ @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type - /** - * The name of the grader. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun name(): Optional = name.getOptional("name") - /** * Returns the raw JSON value of [evaluationMetric]. * @@ -116,13 +103,11 @@ private constructor( @JsonProperty("input") @ExcludeMissing fun _input(): JsonField = input /** - * Returns the raw JSON value of [passThreshold]. + * Returns the raw JSON value of [name]. * - * Unlike [passThreshold], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("pass_threshold") - @ExcludeMissing - fun _passThreshold(): JsonField = passThreshold + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name /** * Returns the raw JSON value of [reference]. @@ -131,13 +116,6 @@ private constructor( */ @JsonProperty("reference") @ExcludeMissing fun _reference(): JsonField = reference - /** - * Returns the raw JSON value of [name]. - * - * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name - @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { additionalProperties.put(key, value) @@ -153,39 +131,37 @@ private constructor( companion object { /** - * Returns a mutable builder for constructing an instance of [EvalTextSimilarityGrader]. + * Returns a mutable builder for constructing an instance of [TextSimilarityGrader]. * * The following fields are required: * ```java * .evaluationMetric() * .input() - * .passThreshold() + * .name() * .reference() * ``` */ @JvmStatic fun builder() = Builder() } - /** A builder for [EvalTextSimilarityGrader]. */ + /** A builder for [TextSimilarityGrader]. */ class Builder internal constructor() { private var evaluationMetric: JsonField? = null private var input: JsonField? = null - private var passThreshold: JsonField? = null + private var name: JsonField? = null private var reference: JsonField? = null private var type: JsonValue = JsonValue.from("text_similarity") - private var name: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(evalTextSimilarityGrader: EvalTextSimilarityGrader) = apply { - evaluationMetric = evalTextSimilarityGrader.evaluationMetric - input = evalTextSimilarityGrader.input - passThreshold = evalTextSimilarityGrader.passThreshold - reference = evalTextSimilarityGrader.reference - type = evalTextSimilarityGrader.type - name = evalTextSimilarityGrader.name - additionalProperties = evalTextSimilarityGrader.additionalProperties.toMutableMap() + internal fun from(textSimilarityGrader: TextSimilarityGrader) = apply { + evaluationMetric = textSimilarityGrader.evaluationMetric + input = textSimilarityGrader.input + name = textSimilarityGrader.name + reference = textSimilarityGrader.reference + type = textSimilarityGrader.type + additionalProperties = textSimilarityGrader.additionalProperties.toMutableMap() } /** @@ -217,19 +193,16 @@ private constructor( */ fun input(input: JsonField) = apply { this.input = input } - /** A float score where a value greater than or equal indicates a passing grade. */ - fun passThreshold(passThreshold: Double) = passThreshold(JsonField.of(passThreshold)) + /** The name of the grader. */ + fun name(name: String) = name(JsonField.of(name)) /** - * Sets [Builder.passThreshold] to an arbitrary JSON value. + * Sets [Builder.name] to an arbitrary JSON value. * - * You should usually call [Builder.passThreshold] with a well-typed [Double] value instead. - * This method is primarily for setting the field to an undocumented or not yet supported - * value. + * You should usually call [Builder.name] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. */ - fun passThreshold(passThreshold: JsonField) = apply { - this.passThreshold = passThreshold - } + fun name(name: JsonField) = apply { this.name = name } /** The text being graded against. */ fun reference(reference: String) = reference(JsonField.of(reference)) @@ -257,17 +230,6 @@ private constructor( */ fun type(type: JsonValue) = apply { this.type = type } - /** The name of the grader. */ - fun name(name: String) = name(JsonField.of(name)) - - /** - * Sets [Builder.name] to an arbitrary JSON value. - * - * You should usually call [Builder.name] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun name(name: JsonField) = apply { this.name = name } - fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() putAllAdditionalProperties(additionalProperties) @@ -288,7 +250,7 @@ private constructor( } /** - * Returns an immutable instance of [EvalTextSimilarityGrader]. + * Returns an immutable instance of [TextSimilarityGrader]. * * Further updates to this [Builder] will not mutate the returned instance. * @@ -296,41 +258,39 @@ private constructor( * ```java * .evaluationMetric() * .input() - * .passThreshold() + * .name() * .reference() * ``` * * @throws IllegalStateException if any required field is unset. */ - fun build(): EvalTextSimilarityGrader = - EvalTextSimilarityGrader( + fun build(): TextSimilarityGrader = + TextSimilarityGrader( checkRequired("evaluationMetric", evaluationMetric), checkRequired("input", input), - checkRequired("passThreshold", passThreshold), + checkRequired("name", name), checkRequired("reference", reference), type, - name, additionalProperties.toMutableMap(), ) } private var validated: Boolean = false - fun validate(): EvalTextSimilarityGrader = apply { + fun validate(): TextSimilarityGrader = apply { if (validated) { return@apply } evaluationMetric().validate() input() - passThreshold() + name() reference() _type().let { if (it != JsonValue.from("text_similarity")) { throw OpenAIInvalidDataException("'type' is invalid, received $it") } } - name() validated = true } @@ -351,10 +311,9 @@ private constructor( internal fun validity(): Int = (evaluationMetric.asKnown().getOrNull()?.validity() ?: 0) + (if (input.asKnown().isPresent) 1 else 0) + - (if (passThreshold.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + (if (reference.asKnown().isPresent) 1 else 0) + - type.let { if (it == JsonValue.from("text_similarity")) 1 else 0 } + - (if (name.asKnown().isPresent) 1 else 0) + type.let { if (it == JsonValue.from("text_similarity")) 1 else 0 } /** * The evaluation metric to use. One of `fuzzy_match`, `bleu`, `gleu`, `meteor`, `rouge_1`, @@ -542,15 +501,15 @@ private constructor( return true } - return /* spotless:off */ other is EvalTextSimilarityGrader && evaluationMetric == other.evaluationMetric && input == other.input && passThreshold == other.passThreshold && reference == other.reference && type == other.type && name == other.name && additionalProperties == other.additionalProperties /* spotless:on */ + return /* spotless:off */ other is TextSimilarityGrader && evaluationMetric == other.evaluationMetric && input == other.input && name == other.name && reference == other.reference && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ } /* spotless:off */ - private val hashCode: Int by lazy { Objects.hash(evaluationMetric, input, passThreshold, reference, type, name, additionalProperties) } + private val hashCode: Int by lazy { Objects.hash(evaluationMetric, input, name, reference, type, additionalProperties) } /* spotless:on */ override fun hashCode(): Int = hashCode override fun toString() = - "EvalTextSimilarityGrader{evaluationMetric=$evaluationMetric, input=$input, passThreshold=$passThreshold, reference=$reference, type=$type, name=$name, additionalProperties=$additionalProperties}" + "TextSimilarityGrader{evaluationMetric=$evaluationMetric, input=$input, name=$name, reference=$reference, type=$type, additionalProperties=$additionalProperties}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/models/ModelDeleteParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/models/ModelDeleteParams.kt index f87f9a5a..c3b48aed 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/models/ModelDeleteParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/models/ModelDeleteParams.kt @@ -4,25 +4,25 @@ package com.openai.models.models import com.openai.core.JsonValue import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import com.openai.core.toImmutable import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** * Delete a fine-tuned model. You must have the Owner role in your organization to delete a model. */ class ModelDeleteParams private constructor( - private val model: String, + private val model: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, ) : Params { - fun model(): String = model + fun model(): Optional = Optional.ofNullable(model) fun _additionalBodyProperties(): Map = additionalBodyProperties @@ -34,14 +34,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [ModelDeleteParams]. - * - * The following fields are required: - * ```java - * .model() - * ``` - */ + @JvmStatic fun none(): ModelDeleteParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [ModelDeleteParams]. */ @JvmStatic fun builder() = Builder() } @@ -61,7 +56,10 @@ private constructor( additionalBodyProperties = modelDeleteParams.additionalBodyProperties.toMutableMap() } - fun model(model: String) = apply { this.model = model } + fun model(model: String?) = apply { this.model = model } + + /** Alias for calling [Builder.model] with `model.orElse(null)`. */ + fun model(model: Optional) = model(model.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -187,17 +185,10 @@ private constructor( * Returns an immutable instance of [ModelDeleteParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .model() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): ModelDeleteParams = ModelDeleteParams( - checkRequired("model", model), + model, additionalHeaders.build(), additionalQueryParams.build(), additionalBodyProperties.toImmutable(), @@ -209,7 +200,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> model + 0 -> model ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/models/ModelListPage.kt b/openai-java-core/src/main/kotlin/com/openai/models/models/ModelListPage.kt index 2da80544..9ce4bde9 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/models/ModelListPage.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/models/ModelListPage.kt @@ -2,13 +2,12 @@ package com.openai.models.models +import com.openai.core.AutoPager import com.openai.core.JsonValue +import com.openai.core.Page import com.openai.core.checkRequired import com.openai.services.blocking.ModelService import java.util.Objects -import java.util.Optional -import java.util.stream.Stream -import java.util.stream.StreamSupport import kotlin.jvm.optionals.getOrNull /** @see [ModelService.list] */ @@ -17,7 +16,7 @@ private constructor( private val service: ModelService, private val params: ModelListParams, private val response: ModelListPageResponse, -) { +) : Page { /** * Delegates to [ModelListPageResponse], but gracefully handles missing data. @@ -29,13 +28,16 @@ private constructor( /** @see [ModelListPageResponse.object_] */ fun object_(): JsonValue = response._object_() - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional = Optional.empty() + override fun hasNextPage(): Boolean = items().isNotEmpty() - fun getNextPage(): Optional = getNextPageParams().map { service.list(it) } + fun nextPageParams(): ModelListParams = + throw IllegalStateException("Cannot construct next page params") - fun autoPager(): AutoPager = AutoPager(this) + override fun nextPage(): ModelListPage = service.list(nextPageParams()) + + fun autoPager(): AutoPager = AutoPager.from(this) /** The parameters that were used to request this page. */ fun params(): ModelListParams = params @@ -104,25 +106,6 @@ private constructor( ) } - class AutoPager(private val firstPage: ModelListPage) : Iterable { - - override fun iterator(): Iterator = iterator { - var page = firstPage - var index = 0 - while (true) { - while (index < page.data().size) { - yield(page.data()[index++]) - } - page = page.getNextPage().getOrNull() ?: break - index = 0 - } - } - - fun stream(): Stream { - return StreamSupport.stream(spliterator(), false) - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/openai-java-core/src/main/kotlin/com/openai/models/models/ModelListPageAsync.kt b/openai-java-core/src/main/kotlin/com/openai/models/models/ModelListPageAsync.kt index 653a08f5..335ac20c 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/models/ModelListPageAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/models/ModelListPageAsync.kt @@ -2,23 +2,24 @@ package com.openai.models.models +import com.openai.core.AutoPagerAsync import com.openai.core.JsonValue +import com.openai.core.PageAsync import com.openai.core.checkRequired import com.openai.services.async.ModelServiceAsync import java.util.Objects -import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor -import java.util.function.Predicate import kotlin.jvm.optionals.getOrNull /** @see [ModelServiceAsync.list] */ class ModelListPageAsync private constructor( private val service: ModelServiceAsync, + private val streamHandlerExecutor: Executor, private val params: ModelListParams, private val response: ModelListPageResponse, -) { +) : PageAsync { /** * Delegates to [ModelListPageResponse], but gracefully handles missing data. @@ -30,16 +31,16 @@ private constructor( /** @see [ModelListPageResponse.object_] */ fun object_(): JsonValue = response._object_() - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional = Optional.empty() + override fun hasNextPage(): Boolean = items().isNotEmpty() - fun getNextPage(): CompletableFuture> = - getNextPageParams() - .map { service.list(it).thenApply { Optional.of(it) } } - .orElseGet { CompletableFuture.completedFuture(Optional.empty()) } + fun nextPageParams(): ModelListParams = + throw IllegalStateException("Cannot construct next page params") - fun autoPager(): AutoPager = AutoPager(this) + override fun nextPage(): CompletableFuture = service.list(nextPageParams()) + + fun autoPager(): AutoPagerAsync = AutoPagerAsync.from(this, streamHandlerExecutor) /** The parameters that were used to request this page. */ fun params(): ModelListParams = params @@ -57,6 +58,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -68,18 +70,24 @@ private constructor( class Builder internal constructor() { private var service: ModelServiceAsync? = null + private var streamHandlerExecutor: Executor? = null private var params: ModelListParams? = null private var response: ModelListPageResponse? = null @JvmSynthetic internal fun from(modelListPageAsync: ModelListPageAsync) = apply { service = modelListPageAsync.service + streamHandlerExecutor = modelListPageAsync.streamHandlerExecutor params = modelListPageAsync.params response = modelListPageAsync.response } fun service(service: ModelServiceAsync) = apply { this.service = service } + fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply { + this.streamHandlerExecutor = streamHandlerExecutor + } + /** The parameters that were used to request this page. */ fun params(params: ModelListParams) = apply { this.params = params } @@ -94,6 +102,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -103,47 +112,22 @@ private constructor( fun build(): ModelListPageAsync = ModelListPageAsync( checkRequired("service", service), + checkRequired("streamHandlerExecutor", streamHandlerExecutor), checkRequired("params", params), checkRequired("response", response), ) } - class AutoPager(private val firstPage: ModelListPageAsync) { - - fun forEach(action: Predicate, executor: Executor): CompletableFuture { - fun CompletableFuture>.forEach( - action: (Model) -> Boolean, - executor: Executor, - ): CompletableFuture = - thenComposeAsync( - { page -> - page - .filter { it.data().all(action) } - .map { it.getNextPage().forEach(action, executor) } - .orElseGet { CompletableFuture.completedFuture(null) } - }, - executor, - ) - return CompletableFuture.completedFuture(Optional.of(firstPage)) - .forEach(action::test, executor) - } - - fun toList(executor: Executor): CompletableFuture> { - val values = mutableListOf() - return forEach(values::add, executor).thenApply { values } - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return /* spotless:off */ other is ModelListPageAsync && service == other.service && params == other.params && response == other.response /* spotless:on */ + return /* spotless:off */ other is ModelListPageAsync && service == other.service && streamHandlerExecutor == other.streamHandlerExecutor && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, params, response) /* spotless:on */ + override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, streamHandlerExecutor, params, response) /* spotless:on */ override fun toString() = - "ModelListPageAsync{service=$service, params=$params, response=$response}" + "ModelListPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, response=$response}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/models/ModelRetrieveParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/models/ModelRetrieveParams.kt index d76cdabc..1be64185 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/models/ModelRetrieveParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/models/ModelRetrieveParams.kt @@ -3,10 +3,11 @@ package com.openai.models.models import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** * Retrieves a model instance, providing basic information about the model such as the owner and @@ -14,12 +15,12 @@ import java.util.Objects */ class ModelRetrieveParams private constructor( - private val model: String, + private val model: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun model(): String = model + fun model(): Optional = Optional.ofNullable(model) fun _additionalHeaders(): Headers = additionalHeaders @@ -29,14 +30,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [ModelRetrieveParams]. - * - * The following fields are required: - * ```java - * .model() - * ``` - */ + @JvmStatic fun none(): ModelRetrieveParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [ModelRetrieveParams]. */ @JvmStatic fun builder() = Builder() } @@ -54,7 +50,10 @@ private constructor( additionalQueryParams = modelRetrieveParams.additionalQueryParams.toBuilder() } - fun model(model: String) = apply { this.model = model } + fun model(model: String?) = apply { this.model = model } + + /** Alias for calling [Builder.model] with `model.orElse(null)`. */ + fun model(model: Optional) = model(model.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -158,25 +157,14 @@ private constructor( * Returns an immutable instance of [ModelRetrieveParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .model() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): ModelRetrieveParams = - ModelRetrieveParams( - checkRequired("model", model), - additionalHeaders.build(), - additionalQueryParams.build(), - ) + ModelRetrieveParams(model, additionalHeaders.build(), additionalQueryParams.build()) } fun _pathParam(index: Int): String = when (index) { - 0 -> model + 0 -> model ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseDeleteParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseDeleteParams.kt index b3fae35d..38398d98 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseDeleteParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseDeleteParams.kt @@ -4,23 +4,23 @@ package com.openai.models.responses import com.openai.core.JsonValue import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import com.openai.core.toImmutable import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** Deletes a model response with the given ID. */ class ResponseDeleteParams private constructor( - private val responseId: String, + private val responseId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, ) : Params { - fun responseId(): String = responseId + fun responseId(): Optional = Optional.ofNullable(responseId) fun _additionalBodyProperties(): Map = additionalBodyProperties @@ -32,14 +32,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [ResponseDeleteParams]. - * - * The following fields are required: - * ```java - * .responseId() - * ``` - */ + @JvmStatic fun none(): ResponseDeleteParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [ResponseDeleteParams]. */ @JvmStatic fun builder() = Builder() } @@ -59,7 +54,10 @@ private constructor( additionalBodyProperties = responseDeleteParams.additionalBodyProperties.toMutableMap() } - fun responseId(responseId: String) = apply { this.responseId = responseId } + fun responseId(responseId: String?) = apply { this.responseId = responseId } + + /** Alias for calling [Builder.responseId] with `responseId.orElse(null)`. */ + fun responseId(responseId: Optional) = responseId(responseId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -185,17 +183,10 @@ private constructor( * Returns an immutable instance of [ResponseDeleteParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .responseId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): ResponseDeleteParams = ResponseDeleteParams( - checkRequired("responseId", responseId), + responseId, additionalHeaders.build(), additionalQueryParams.build(), additionalBodyProperties.toImmutable(), @@ -207,7 +198,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> responseId + 0 -> responseId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseFileSearchToolCall.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseFileSearchToolCall.kt index 35019c26..1e0389b6 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseFileSearchToolCall.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseFileSearchToolCall.kt @@ -497,7 +497,7 @@ private constructor( private val attributes: JsonField, private val fileId: JsonField, private val filename: JsonField, - private val score: JsonField, + private val score: JsonField, private val text: JsonField, private val additionalProperties: MutableMap, ) { @@ -511,7 +511,7 @@ private constructor( @JsonProperty("filename") @ExcludeMissing filename: JsonField = JsonMissing.of(), - @JsonProperty("score") @ExcludeMissing score: JsonField = JsonMissing.of(), + @JsonProperty("score") @ExcludeMissing score: JsonField = JsonMissing.of(), @JsonProperty("text") @ExcludeMissing text: JsonField = JsonMissing.of(), ) : this(attributes, fileId, filename, score, text, mutableMapOf()) @@ -549,7 +549,7 @@ private constructor( * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). */ - fun score(): Optional = score.getOptional("score") + fun score(): Optional = score.getOptional("score") /** * The text that was retrieved from the file. @@ -587,7 +587,7 @@ private constructor( * * Unlike [score], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("score") @ExcludeMissing fun _score(): JsonField = score + @JsonProperty("score") @ExcludeMissing fun _score(): JsonField = score /** * Returns the raw JSON value of [text]. @@ -620,7 +620,7 @@ private constructor( private var attributes: JsonField = JsonMissing.of() private var fileId: JsonField = JsonMissing.of() private var filename: JsonField = JsonMissing.of() - private var score: JsonField = JsonMissing.of() + private var score: JsonField = JsonMissing.of() private var text: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @@ -682,16 +682,16 @@ private constructor( fun filename(filename: JsonField) = apply { this.filename = filename } /** The relevance score of the file - a value between 0 and 1. */ - fun score(score: Double) = score(JsonField.of(score)) + fun score(score: Float) = score(JsonField.of(score)) /** * Sets [Builder.score] to an arbitrary JSON value. * - * You should usually call [Builder.score] with a well-typed [Double] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. + * You should usually call [Builder.score] with a well-typed [Float] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. */ - fun score(score: JsonField) = apply { this.score = score } + fun score(score: JsonField) = apply { this.score = score } /** The text that was retrieved from the file. */ fun text(text: String) = text(JsonField.of(text)) diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseRetrieveParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseRetrieveParams.kt index 3c73de87..bc158949 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseRetrieveParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseRetrieveParams.kt @@ -3,7 +3,6 @@ package com.openai.models.responses import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import com.openai.core.toImmutable @@ -14,13 +13,13 @@ import kotlin.jvm.optionals.getOrNull /** Retrieves a model response with the given ID. */ class ResponseRetrieveParams private constructor( - private val responseId: String, + private val responseId: String?, private val include: List?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun responseId(): String = responseId + fun responseId(): Optional = Optional.ofNullable(responseId) /** * Additional fields to include in the response. See the `include` parameter for Response @@ -36,14 +35,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [ResponseRetrieveParams]. - * - * The following fields are required: - * ```java - * .responseId() - * ``` - */ + @JvmStatic fun none(): ResponseRetrieveParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [ResponseRetrieveParams]. */ @JvmStatic fun builder() = Builder() } @@ -63,7 +57,10 @@ private constructor( additionalQueryParams = responseRetrieveParams.additionalQueryParams.toBuilder() } - fun responseId(responseId: String) = apply { this.responseId = responseId } + fun responseId(responseId: String?) = apply { this.responseId = responseId } + + /** Alias for calling [Builder.responseId] with `responseId.orElse(null)`. */ + fun responseId(responseId: Optional) = responseId(responseId.getOrNull()) /** * Additional fields to include in the response. See the `include` parameter for Response @@ -187,17 +184,10 @@ private constructor( * Returns an immutable instance of [ResponseRetrieveParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .responseId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): ResponseRetrieveParams = ResponseRetrieveParams( - checkRequired("responseId", responseId), + responseId, include?.toImmutable(), additionalHeaders.build(), additionalQueryParams.build(), @@ -206,7 +196,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> responseId + 0 -> responseId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/inputitems/InputItemListPage.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/inputitems/InputItemListPage.kt index 1fbb02ef..6218c55b 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/inputitems/InputItemListPage.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/inputitems/InputItemListPage.kt @@ -2,6 +2,8 @@ package com.openai.models.responses.inputitems +import com.openai.core.AutoPager +import com.openai.core.Page import com.openai.core.checkRequired import com.openai.models.responses.ResponseComputerToolCall import com.openai.models.responses.ResponseComputerToolCallOutputItem @@ -15,8 +17,6 @@ import com.openai.models.responses.ResponseOutputMessage import com.openai.services.blocking.responses.InputItemService import java.util.Objects import java.util.Optional -import java.util.stream.Stream -import java.util.stream.StreamSupport import kotlin.jvm.optionals.getOrNull /** @see [InputItemService.list] */ @@ -25,7 +25,7 @@ private constructor( private val service: InputItemService, private val params: InputItemListParams, private val response: ResponseItemList, -) { +) : Page { /** * Delegates to [ResponseItemList], but gracefully handles missing data. @@ -41,63 +41,57 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() - - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } - - return Optional.of( - params - .toBuilder() - .after( - data() - .last() - .accept( - object : ResponseItem.Visitor> { - override fun visitResponseInputMessageItem( - responseInputMessageItem: ResponseInputMessageItem - ): Optional = - responseInputMessageItem._id().getOptional("id") - - override fun visitResponseOutputMessage( - responseOutputMessage: ResponseOutputMessage - ): Optional = responseOutputMessage._id().getOptional("id") - - override fun visitFileSearchCall( - fileSearchCall: ResponseFileSearchToolCall - ): Optional = fileSearchCall._id().getOptional("id") - - override fun visitComputerCall( - computerCall: ResponseComputerToolCall - ): Optional = computerCall._id().getOptional("id") - - override fun visitComputerCallOutput( - computerCallOutput: ResponseComputerToolCallOutputItem - ): Optional = computerCallOutput._id().getOptional("id") - - override fun visitWebSearchCall( - webSearchCall: ResponseFunctionWebSearch - ): Optional = webSearchCall._id().getOptional("id") - - override fun visitFunctionCall( - functionCall: ResponseFunctionToolCallItem - ): Optional = functionCall._id().getOptional("id") - - override fun visitFunctionCallOutput( - functionCallOutput: ResponseFunctionToolCallOutputItem - ): Optional = functionCallOutput._id().getOptional("id") - } - ) - ) - .build() - ) - } + override fun items(): List = data() + + override fun hasNextPage(): Boolean = items().isNotEmpty() + + fun nextPageParams(): InputItemListParams = + params + .toBuilder() + .after( + items() + .last() + .accept( + object : ResponseItem.Visitor> { + override fun visitResponseInputMessageItem( + responseInputMessageItem: ResponseInputMessageItem + ): Optional = responseInputMessageItem._id().getOptional("id") + + override fun visitResponseOutputMessage( + responseOutputMessage: ResponseOutputMessage + ): Optional = responseOutputMessage._id().getOptional("id") + + override fun visitFileSearchCall( + fileSearchCall: ResponseFileSearchToolCall + ): Optional = fileSearchCall._id().getOptional("id") + + override fun visitComputerCall( + computerCall: ResponseComputerToolCall + ): Optional = computerCall._id().getOptional("id") + + override fun visitComputerCallOutput( + computerCallOutput: ResponseComputerToolCallOutputItem + ): Optional = computerCallOutput._id().getOptional("id") + + override fun visitWebSearchCall( + webSearchCall: ResponseFunctionWebSearch + ): Optional = webSearchCall._id().getOptional("id") + + override fun visitFunctionCall( + functionCall: ResponseFunctionToolCallItem + ): Optional = functionCall._id().getOptional("id") + + override fun visitFunctionCallOutput( + functionCallOutput: ResponseFunctionToolCallOutputItem + ): Optional = functionCallOutput._id().getOptional("id") + } + ) + ) + .build() - fun getNextPage(): Optional = getNextPageParams().map { service.list(it) } + override fun nextPage(): InputItemListPage = service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPager = AutoPager.from(this) /** The parameters that were used to request this page. */ fun params(): InputItemListParams = params @@ -166,25 +160,6 @@ private constructor( ) } - class AutoPager(private val firstPage: InputItemListPage) : Iterable { - - override fun iterator(): Iterator = iterator { - var page = firstPage - var index = 0 - while (true) { - while (index < page.data().size) { - yield(page.data()[index++]) - } - page = page.getNextPage().getOrNull() ?: break - index = 0 - } - } - - fun stream(): Stream { - return StreamSupport.stream(spliterator(), false) - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/inputitems/InputItemListPageAsync.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/inputitems/InputItemListPageAsync.kt index ddde7ff4..a840b310 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/inputitems/InputItemListPageAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/inputitems/InputItemListPageAsync.kt @@ -2,6 +2,8 @@ package com.openai.models.responses.inputitems +import com.openai.core.AutoPagerAsync +import com.openai.core.PageAsync import com.openai.core.checkRequired import com.openai.models.responses.ResponseComputerToolCall import com.openai.models.responses.ResponseComputerToolCallOutputItem @@ -17,16 +19,16 @@ import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor -import java.util.function.Predicate import kotlin.jvm.optionals.getOrNull /** @see [InputItemServiceAsync.list] */ class InputItemListPageAsync private constructor( private val service: InputItemServiceAsync, + private val streamHandlerExecutor: Executor, private val params: InputItemListParams, private val response: ResponseItemList, -) { +) : PageAsync { /** * Delegates to [ResponseItemList], but gracefully handles missing data. @@ -42,66 +44,58 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() - - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } - - return Optional.of( - params - .toBuilder() - .after( - data() - .last() - .accept( - object : ResponseItem.Visitor> { - override fun visitResponseInputMessageItem( - responseInputMessageItem: ResponseInputMessageItem - ): Optional = - responseInputMessageItem._id().getOptional("id") - - override fun visitResponseOutputMessage( - responseOutputMessage: ResponseOutputMessage - ): Optional = responseOutputMessage._id().getOptional("id") - - override fun visitFileSearchCall( - fileSearchCall: ResponseFileSearchToolCall - ): Optional = fileSearchCall._id().getOptional("id") - - override fun visitComputerCall( - computerCall: ResponseComputerToolCall - ): Optional = computerCall._id().getOptional("id") - - override fun visitComputerCallOutput( - computerCallOutput: ResponseComputerToolCallOutputItem - ): Optional = computerCallOutput._id().getOptional("id") - - override fun visitWebSearchCall( - webSearchCall: ResponseFunctionWebSearch - ): Optional = webSearchCall._id().getOptional("id") - - override fun visitFunctionCall( - functionCall: ResponseFunctionToolCallItem - ): Optional = functionCall._id().getOptional("id") - - override fun visitFunctionCallOutput( - functionCallOutput: ResponseFunctionToolCallOutputItem - ): Optional = functionCallOutput._id().getOptional("id") - } - ) - ) - .build() - ) - } + override fun items(): List = data() + + override fun hasNextPage(): Boolean = items().isNotEmpty() + + fun nextPageParams(): InputItemListParams = + params + .toBuilder() + .after( + items() + .last() + .accept( + object : ResponseItem.Visitor> { + override fun visitResponseInputMessageItem( + responseInputMessageItem: ResponseInputMessageItem + ): Optional = responseInputMessageItem._id().getOptional("id") + + override fun visitResponseOutputMessage( + responseOutputMessage: ResponseOutputMessage + ): Optional = responseOutputMessage._id().getOptional("id") + + override fun visitFileSearchCall( + fileSearchCall: ResponseFileSearchToolCall + ): Optional = fileSearchCall._id().getOptional("id") + + override fun visitComputerCall( + computerCall: ResponseComputerToolCall + ): Optional = computerCall._id().getOptional("id") + + override fun visitComputerCallOutput( + computerCallOutput: ResponseComputerToolCallOutputItem + ): Optional = computerCallOutput._id().getOptional("id") + + override fun visitWebSearchCall( + webSearchCall: ResponseFunctionWebSearch + ): Optional = webSearchCall._id().getOptional("id") + + override fun visitFunctionCall( + functionCall: ResponseFunctionToolCallItem + ): Optional = functionCall._id().getOptional("id") + + override fun visitFunctionCallOutput( + functionCallOutput: ResponseFunctionToolCallOutputItem + ): Optional = functionCallOutput._id().getOptional("id") + } + ) + ) + .build() - fun getNextPage(): CompletableFuture> = - getNextPageParams() - .map { service.list(it).thenApply { Optional.of(it) } } - .orElseGet { CompletableFuture.completedFuture(Optional.empty()) } + override fun nextPage(): CompletableFuture = + service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPagerAsync = AutoPagerAsync.from(this, streamHandlerExecutor) /** The parameters that were used to request this page. */ fun params(): InputItemListParams = params @@ -119,6 +113,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -130,18 +125,24 @@ private constructor( class Builder internal constructor() { private var service: InputItemServiceAsync? = null + private var streamHandlerExecutor: Executor? = null private var params: InputItemListParams? = null private var response: ResponseItemList? = null @JvmSynthetic internal fun from(inputItemListPageAsync: InputItemListPageAsync) = apply { service = inputItemListPageAsync.service + streamHandlerExecutor = inputItemListPageAsync.streamHandlerExecutor params = inputItemListPageAsync.params response = inputItemListPageAsync.response } fun service(service: InputItemServiceAsync) = apply { this.service = service } + fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply { + this.streamHandlerExecutor = streamHandlerExecutor + } + /** The parameters that were used to request this page. */ fun params(params: InputItemListParams) = apply { this.params = params } @@ -156,6 +157,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -165,47 +167,22 @@ private constructor( fun build(): InputItemListPageAsync = InputItemListPageAsync( checkRequired("service", service), + checkRequired("streamHandlerExecutor", streamHandlerExecutor), checkRequired("params", params), checkRequired("response", response), ) } - class AutoPager(private val firstPage: InputItemListPageAsync) { - - fun forEach(action: Predicate, executor: Executor): CompletableFuture { - fun CompletableFuture>.forEach( - action: (ResponseItem) -> Boolean, - executor: Executor, - ): CompletableFuture = - thenComposeAsync( - { page -> - page - .filter { it.data().all(action) } - .map { it.getNextPage().forEach(action, executor) } - .orElseGet { CompletableFuture.completedFuture(null) } - }, - executor, - ) - return CompletableFuture.completedFuture(Optional.of(firstPage)) - .forEach(action::test, executor) - } - - fun toList(executor: Executor): CompletableFuture> { - val values = mutableListOf() - return forEach(values::add, executor).thenApply { values } - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return /* spotless:off */ other is InputItemListPageAsync && service == other.service && params == other.params && response == other.response /* spotless:on */ + return /* spotless:off */ other is InputItemListPageAsync && service == other.service && streamHandlerExecutor == other.streamHandlerExecutor && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, params, response) /* spotless:on */ + override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, streamHandlerExecutor, params, response) /* spotless:on */ override fun toString() = - "InputItemListPageAsync{service=$service, params=$params, response=$response}" + "InputItemListPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, response=$response}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/inputitems/InputItemListParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/inputitems/InputItemListParams.kt index 11ddf361..e3f3cbd9 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/inputitems/InputItemListParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/inputitems/InputItemListParams.kt @@ -6,7 +6,6 @@ import com.fasterxml.jackson.annotation.JsonCreator import com.openai.core.Enum import com.openai.core.JsonField import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import com.openai.core.toImmutable @@ -19,7 +18,7 @@ import kotlin.jvm.optionals.getOrNull /** Returns a list of input items for a given response. */ class InputItemListParams private constructor( - private val responseId: String, + private val responseId: String?, private val after: String?, private val before: String?, private val include: List?, @@ -29,7 +28,7 @@ private constructor( private val additionalQueryParams: QueryParams, ) : Params { - fun responseId(): String = responseId + fun responseId(): Optional = Optional.ofNullable(responseId) /** An item ID to list items after, used in pagination. */ fun after(): Optional = Optional.ofNullable(after) @@ -64,14 +63,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [InputItemListParams]. - * - * The following fields are required: - * ```java - * .responseId() - * ``` - */ + @JvmStatic fun none(): InputItemListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [InputItemListParams]. */ @JvmStatic fun builder() = Builder() } @@ -99,7 +93,10 @@ private constructor( additionalQueryParams = inputItemListParams.additionalQueryParams.toBuilder() } - fun responseId(responseId: String) = apply { this.responseId = responseId } + fun responseId(responseId: String?) = apply { this.responseId = responseId } + + /** Alias for calling [Builder.responseId] with `responseId.orElse(null)`. */ + fun responseId(responseId: Optional) = responseId(responseId.getOrNull()) /** An item ID to list items after, used in pagination. */ fun after(after: String?) = apply { this.after = after } @@ -261,17 +258,10 @@ private constructor( * Returns an immutable instance of [InputItemListParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .responseId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): InputItemListParams = InputItemListParams( - checkRequired("responseId", responseId), + responseId, after, before, include?.toImmutable(), @@ -284,7 +274,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> responseId + 0 -> responseId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/uploads/UploadCancelParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/uploads/UploadCancelParams.kt index 5b2fe821..013b5ddc 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/uploads/UploadCancelParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/uploads/UploadCancelParams.kt @@ -4,23 +4,23 @@ package com.openai.models.uploads import com.openai.core.JsonValue import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import com.openai.core.toImmutable import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** Cancels the Upload. No Parts may be added after an Upload is cancelled. */ class UploadCancelParams private constructor( - private val uploadId: String, + private val uploadId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, ) : Params { - fun uploadId(): String = uploadId + fun uploadId(): Optional = Optional.ofNullable(uploadId) fun _additionalBodyProperties(): Map = additionalBodyProperties @@ -32,14 +32,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [UploadCancelParams]. - * - * The following fields are required: - * ```java - * .uploadId() - * ``` - */ + @JvmStatic fun none(): UploadCancelParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [UploadCancelParams]. */ @JvmStatic fun builder() = Builder() } @@ -59,7 +54,10 @@ private constructor( additionalBodyProperties = uploadCancelParams.additionalBodyProperties.toMutableMap() } - fun uploadId(uploadId: String) = apply { this.uploadId = uploadId } + fun uploadId(uploadId: String?) = apply { this.uploadId = uploadId } + + /** Alias for calling [Builder.uploadId] with `uploadId.orElse(null)`. */ + fun uploadId(uploadId: Optional) = uploadId(uploadId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -185,17 +183,10 @@ private constructor( * Returns an immutable instance of [UploadCancelParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .uploadId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): UploadCancelParams = UploadCancelParams( - checkRequired("uploadId", uploadId), + uploadId, additionalHeaders.build(), additionalQueryParams.build(), additionalBodyProperties.toImmutable(), @@ -207,7 +198,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> uploadId + 0 -> uploadId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/uploads/UploadCompleteParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/uploads/UploadCompleteParams.kt index 990ef1d4..fb5603c1 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/uploads/UploadCompleteParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/uploads/UploadCompleteParams.kt @@ -36,13 +36,13 @@ import kotlin.jvm.optionals.getOrNull */ class UploadCompleteParams private constructor( - private val uploadId: String, + private val uploadId: String?, private val body: Body, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun uploadId(): String = uploadId + fun uploadId(): Optional = Optional.ofNullable(uploadId) /** * The ordered list of Part IDs. @@ -90,7 +90,6 @@ private constructor( * * The following fields are required: * ```java - * .uploadId() * .partIds() * ``` */ @@ -113,7 +112,10 @@ private constructor( additionalQueryParams = uploadCompleteParams.additionalQueryParams.toBuilder() } - fun uploadId(uploadId: String) = apply { this.uploadId = uploadId } + fun uploadId(uploadId: String?) = apply { this.uploadId = uploadId } + + /** Alias for calling [Builder.uploadId] with `uploadId.orElse(null)`. */ + fun uploadId(uploadId: Optional) = uploadId(uploadId.getOrNull()) /** * Sets the entire request body. @@ -282,7 +284,6 @@ private constructor( * * The following fields are required: * ```java - * .uploadId() * .partIds() * ``` * @@ -290,7 +291,7 @@ private constructor( */ fun build(): UploadCompleteParams = UploadCompleteParams( - checkRequired("uploadId", uploadId), + uploadId, body.build(), additionalHeaders.build(), additionalQueryParams.build(), @@ -301,7 +302,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> uploadId + 0 -> uploadId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/uploads/parts/PartCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/uploads/parts/PartCreateParams.kt index a396a730..791713e4 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/uploads/parts/PartCreateParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/uploads/parts/PartCreateParams.kt @@ -14,8 +14,10 @@ import com.openai.errors.OpenAIInvalidDataException import java.io.InputStream import java.nio.file.Path import java.util.Objects +import java.util.Optional import kotlin.io.path.inputStream import kotlin.io.path.name +import kotlin.jvm.optionals.getOrNull /** * Adds a [Part](https://platform.openai.com/docs/api-reference/uploads/part-object) to an @@ -29,13 +31,13 @@ import kotlin.io.path.name */ class PartCreateParams private constructor( - private val uploadId: String, + private val uploadId: String?, private val body: Body, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun uploadId(): String = uploadId + fun uploadId(): Optional = Optional.ofNullable(uploadId) /** * The chunk of bytes for this Part. @@ -65,7 +67,6 @@ private constructor( * * The following fields are required: * ```java - * .uploadId() * .data() * ``` */ @@ -88,7 +89,10 @@ private constructor( additionalQueryParams = partCreateParams.additionalQueryParams.toBuilder() } - fun uploadId(uploadId: String) = apply { this.uploadId = uploadId } + fun uploadId(uploadId: String?) = apply { this.uploadId = uploadId } + + /** Alias for calling [Builder.uploadId] with `uploadId.orElse(null)`. */ + fun uploadId(uploadId: Optional) = uploadId(uploadId.getOrNull()) /** * Sets the entire request body. @@ -222,7 +226,6 @@ private constructor( * * The following fields are required: * ```java - * .uploadId() * .data() * ``` * @@ -230,7 +233,7 @@ private constructor( */ fun build(): PartCreateParams = PartCreateParams( - checkRequired("uploadId", uploadId), + uploadId, body.build(), additionalHeaders.build(), additionalQueryParams.build(), @@ -241,7 +244,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> uploadId + 0 -> uploadId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreDeleteParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreDeleteParams.kt index efd70d98..b6bbda6e 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreDeleteParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreDeleteParams.kt @@ -4,23 +4,23 @@ package com.openai.models.vectorstores import com.openai.core.JsonValue import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import com.openai.core.toImmutable import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** Delete a vector store. */ class VectorStoreDeleteParams private constructor( - private val vectorStoreId: String, + private val vectorStoreId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, ) : Params { - fun vectorStoreId(): String = vectorStoreId + fun vectorStoreId(): Optional = Optional.ofNullable(vectorStoreId) fun _additionalBodyProperties(): Map = additionalBodyProperties @@ -32,14 +32,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [VectorStoreDeleteParams]. - * - * The following fields are required: - * ```java - * .vectorStoreId() - * ``` - */ + @JvmStatic fun none(): VectorStoreDeleteParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [VectorStoreDeleteParams]. */ @JvmStatic fun builder() = Builder() } @@ -60,7 +55,11 @@ private constructor( vectorStoreDeleteParams.additionalBodyProperties.toMutableMap() } - fun vectorStoreId(vectorStoreId: String) = apply { this.vectorStoreId = vectorStoreId } + fun vectorStoreId(vectorStoreId: String?) = apply { this.vectorStoreId = vectorStoreId } + + /** Alias for calling [Builder.vectorStoreId] with `vectorStoreId.orElse(null)`. */ + fun vectorStoreId(vectorStoreId: Optional) = + vectorStoreId(vectorStoreId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -186,17 +185,10 @@ private constructor( * Returns an immutable instance of [VectorStoreDeleteParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .vectorStoreId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): VectorStoreDeleteParams = VectorStoreDeleteParams( - checkRequired("vectorStoreId", vectorStoreId), + vectorStoreId, additionalHeaders.build(), additionalQueryParams.build(), additionalBodyProperties.toImmutable(), @@ -208,7 +200,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> vectorStoreId + 0 -> vectorStoreId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreListPage.kt b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreListPage.kt index fcb7958e..52852ddb 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreListPage.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreListPage.kt @@ -2,12 +2,12 @@ package com.openai.models.vectorstores +import com.openai.core.AutoPager +import com.openai.core.Page import com.openai.core.checkRequired import com.openai.services.blocking.VectorStoreService import java.util.Objects import java.util.Optional -import java.util.stream.Stream -import java.util.stream.StreamSupport import kotlin.jvm.optionals.getOrNull /** @see [VectorStoreService.list] */ @@ -16,7 +16,7 @@ private constructor( private val service: VectorStoreService, private val params: VectorStoreListParams, private val response: VectorStoreListPageResponse, -) { +) : Page { /** * Delegates to [VectorStoreListPageResponse], but gracefully handles missing data. @@ -32,19 +32,16 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): VectorStoreListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): Optional = getNextPageParams().map { service.list(it) } + override fun nextPage(): VectorStoreListPage = service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPager = AutoPager.from(this) /** The parameters that were used to request this page. */ fun params(): VectorStoreListParams = params @@ -113,25 +110,6 @@ private constructor( ) } - class AutoPager(private val firstPage: VectorStoreListPage) : Iterable { - - override fun iterator(): Iterator = iterator { - var page = firstPage - var index = 0 - while (true) { - while (index < page.data().size) { - yield(page.data()[index++]) - } - page = page.getNextPage().getOrNull() ?: break - index = 0 - } - } - - fun stream(): Stream { - return StreamSupport.stream(spliterator(), false) - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreListPageAsync.kt b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreListPageAsync.kt index 1e2daf96..785cf997 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreListPageAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreListPageAsync.kt @@ -2,22 +2,24 @@ package com.openai.models.vectorstores +import com.openai.core.AutoPagerAsync +import com.openai.core.PageAsync import com.openai.core.checkRequired import com.openai.services.async.VectorStoreServiceAsync import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor -import java.util.function.Predicate import kotlin.jvm.optionals.getOrNull /** @see [VectorStoreServiceAsync.list] */ class VectorStoreListPageAsync private constructor( private val service: VectorStoreServiceAsync, + private val streamHandlerExecutor: Executor, private val params: VectorStoreListParams, private val response: VectorStoreListPageResponse, -) { +) : PageAsync { /** * Delegates to [VectorStoreListPageResponse], but gracefully handles missing data. @@ -33,22 +35,17 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): VectorStoreListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): CompletableFuture> = - getNextPageParams() - .map { service.list(it).thenApply { Optional.of(it) } } - .orElseGet { CompletableFuture.completedFuture(Optional.empty()) } + override fun nextPage(): CompletableFuture = + service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPagerAsync = AutoPagerAsync.from(this, streamHandlerExecutor) /** The parameters that were used to request this page. */ fun params(): VectorStoreListParams = params @@ -66,6 +63,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -77,18 +75,24 @@ private constructor( class Builder internal constructor() { private var service: VectorStoreServiceAsync? = null + private var streamHandlerExecutor: Executor? = null private var params: VectorStoreListParams? = null private var response: VectorStoreListPageResponse? = null @JvmSynthetic internal fun from(vectorStoreListPageAsync: VectorStoreListPageAsync) = apply { service = vectorStoreListPageAsync.service + streamHandlerExecutor = vectorStoreListPageAsync.streamHandlerExecutor params = vectorStoreListPageAsync.params response = vectorStoreListPageAsync.response } fun service(service: VectorStoreServiceAsync) = apply { this.service = service } + fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply { + this.streamHandlerExecutor = streamHandlerExecutor + } + /** The parameters that were used to request this page. */ fun params(params: VectorStoreListParams) = apply { this.params = params } @@ -103,6 +107,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -112,47 +117,22 @@ private constructor( fun build(): VectorStoreListPageAsync = VectorStoreListPageAsync( checkRequired("service", service), + checkRequired("streamHandlerExecutor", streamHandlerExecutor), checkRequired("params", params), checkRequired("response", response), ) } - class AutoPager(private val firstPage: VectorStoreListPageAsync) { - - fun forEach(action: Predicate, executor: Executor): CompletableFuture { - fun CompletableFuture>.forEach( - action: (VectorStore) -> Boolean, - executor: Executor, - ): CompletableFuture = - thenComposeAsync( - { page -> - page - .filter { it.data().all(action) } - .map { it.getNextPage().forEach(action, executor) } - .orElseGet { CompletableFuture.completedFuture(null) } - }, - executor, - ) - return CompletableFuture.completedFuture(Optional.of(firstPage)) - .forEach(action::test, executor) - } - - fun toList(executor: Executor): CompletableFuture> { - val values = mutableListOf() - return forEach(values::add, executor).thenApply { values } - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return /* spotless:off */ other is VectorStoreListPageAsync && service == other.service && params == other.params && response == other.response /* spotless:on */ + return /* spotless:off */ other is VectorStoreListPageAsync && service == other.service && streamHandlerExecutor == other.streamHandlerExecutor && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, params, response) /* spotless:on */ + override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, streamHandlerExecutor, params, response) /* spotless:on */ override fun toString() = - "VectorStoreListPageAsync{service=$service, params=$params, response=$response}" + "VectorStoreListPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, response=$response}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreRetrieveParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreRetrieveParams.kt index f8fc087d..87d3f482 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreRetrieveParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreRetrieveParams.kt @@ -3,20 +3,21 @@ package com.openai.models.vectorstores import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** Retrieves a vector store. */ class VectorStoreRetrieveParams private constructor( - private val vectorStoreId: String, + private val vectorStoreId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun vectorStoreId(): String = vectorStoreId + fun vectorStoreId(): Optional = Optional.ofNullable(vectorStoreId) fun _additionalHeaders(): Headers = additionalHeaders @@ -26,13 +27,10 @@ private constructor( companion object { + @JvmStatic fun none(): VectorStoreRetrieveParams = builder().build() + /** * Returns a mutable builder for constructing an instance of [VectorStoreRetrieveParams]. - * - * The following fields are required: - * ```java - * .vectorStoreId() - * ``` */ @JvmStatic fun builder() = Builder() } @@ -51,7 +49,11 @@ private constructor( additionalQueryParams = vectorStoreRetrieveParams.additionalQueryParams.toBuilder() } - fun vectorStoreId(vectorStoreId: String) = apply { this.vectorStoreId = vectorStoreId } + fun vectorStoreId(vectorStoreId: String?) = apply { this.vectorStoreId = vectorStoreId } + + /** Alias for calling [Builder.vectorStoreId] with `vectorStoreId.orElse(null)`. */ + fun vectorStoreId(vectorStoreId: Optional) = + vectorStoreId(vectorStoreId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -155,17 +157,10 @@ private constructor( * Returns an immutable instance of [VectorStoreRetrieveParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .vectorStoreId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): VectorStoreRetrieveParams = VectorStoreRetrieveParams( - checkRequired("vectorStoreId", vectorStoreId), + vectorStoreId, additionalHeaders.build(), additionalQueryParams.build(), ) @@ -173,7 +168,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> vectorStoreId + 0 -> vectorStoreId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreSearchPage.kt b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreSearchPage.kt index fcdefb6c..a45345a0 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreSearchPage.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreSearchPage.kt @@ -2,13 +2,12 @@ package com.openai.models.vectorstores +import com.openai.core.AutoPager import com.openai.core.JsonValue +import com.openai.core.Page import com.openai.core.checkRequired import com.openai.services.blocking.VectorStoreService import java.util.Objects -import java.util.Optional -import java.util.stream.Stream -import java.util.stream.StreamSupport import kotlin.jvm.optionals.getOrNull /** @see [VectorStoreService.search] */ @@ -17,7 +16,7 @@ private constructor( private val service: VectorStoreService, private val params: VectorStoreSearchParams, private val response: VectorStoreSearchPageResponse, -) { +) : Page { /** * Delegates to [VectorStoreSearchPageResponse], but gracefully handles missing data. @@ -30,14 +29,16 @@ private constructor( /** @see [VectorStoreSearchPageResponse.object_] */ fun object_(): JsonValue = response._object_() - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional = Optional.empty() + override fun hasNextPage(): Boolean = items().isNotEmpty() - fun getNextPage(): Optional = - getNextPageParams().map { service.search(it) } + fun nextPageParams(): VectorStoreSearchParams = + throw IllegalStateException("Cannot construct next page params") - fun autoPager(): AutoPager = AutoPager(this) + override fun nextPage(): VectorStoreSearchPage = service.search(nextPageParams()) + + fun autoPager(): AutoPager = AutoPager.from(this) /** The parameters that were used to request this page. */ fun params(): VectorStoreSearchParams = params @@ -106,26 +107,6 @@ private constructor( ) } - class AutoPager(private val firstPage: VectorStoreSearchPage) : - Iterable { - - override fun iterator(): Iterator = iterator { - var page = firstPage - var index = 0 - while (true) { - while (index < page.data().size) { - yield(page.data()[index++]) - } - page = page.getNextPage().getOrNull() ?: break - index = 0 - } - } - - fun stream(): Stream { - return StreamSupport.stream(spliterator(), false) - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreSearchPageAsync.kt b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreSearchPageAsync.kt index 0b7c1d85..00431ef9 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreSearchPageAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreSearchPageAsync.kt @@ -2,23 +2,24 @@ package com.openai.models.vectorstores +import com.openai.core.AutoPagerAsync import com.openai.core.JsonValue +import com.openai.core.PageAsync import com.openai.core.checkRequired import com.openai.services.async.VectorStoreServiceAsync import java.util.Objects -import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor -import java.util.function.Predicate import kotlin.jvm.optionals.getOrNull /** @see [VectorStoreServiceAsync.search] */ class VectorStoreSearchPageAsync private constructor( private val service: VectorStoreServiceAsync, + private val streamHandlerExecutor: Executor, private val params: VectorStoreSearchParams, private val response: VectorStoreSearchPageResponse, -) { +) : PageAsync { /** * Delegates to [VectorStoreSearchPageResponse], but gracefully handles missing data. @@ -31,16 +32,18 @@ private constructor( /** @see [VectorStoreSearchPageResponse.object_] */ fun object_(): JsonValue = response._object_() - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional = Optional.empty() + override fun hasNextPage(): Boolean = items().isNotEmpty() - fun getNextPage(): CompletableFuture> = - getNextPageParams() - .map { service.search(it).thenApply { Optional.of(it) } } - .orElseGet { CompletableFuture.completedFuture(Optional.empty()) } + fun nextPageParams(): VectorStoreSearchParams = + throw IllegalStateException("Cannot construct next page params") - fun autoPager(): AutoPager = AutoPager(this) + override fun nextPage(): CompletableFuture = + service.search(nextPageParams()) + + fun autoPager(): AutoPagerAsync = + AutoPagerAsync.from(this, streamHandlerExecutor) /** The parameters that were used to request this page. */ fun params(): VectorStoreSearchParams = params @@ -58,6 +61,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -69,18 +73,24 @@ private constructor( class Builder internal constructor() { private var service: VectorStoreServiceAsync? = null + private var streamHandlerExecutor: Executor? = null private var params: VectorStoreSearchParams? = null private var response: VectorStoreSearchPageResponse? = null @JvmSynthetic internal fun from(vectorStoreSearchPageAsync: VectorStoreSearchPageAsync) = apply { service = vectorStoreSearchPageAsync.service + streamHandlerExecutor = vectorStoreSearchPageAsync.streamHandlerExecutor params = vectorStoreSearchPageAsync.params response = vectorStoreSearchPageAsync.response } fun service(service: VectorStoreServiceAsync) = apply { this.service = service } + fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply { + this.streamHandlerExecutor = streamHandlerExecutor + } + /** The parameters that were used to request this page. */ fun params(params: VectorStoreSearchParams) = apply { this.params = params } @@ -95,6 +105,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -104,50 +115,22 @@ private constructor( fun build(): VectorStoreSearchPageAsync = VectorStoreSearchPageAsync( checkRequired("service", service), + checkRequired("streamHandlerExecutor", streamHandlerExecutor), checkRequired("params", params), checkRequired("response", response), ) } - class AutoPager(private val firstPage: VectorStoreSearchPageAsync) { - - fun forEach( - action: Predicate, - executor: Executor, - ): CompletableFuture { - fun CompletableFuture>.forEach( - action: (VectorStoreSearchResponse) -> Boolean, - executor: Executor, - ): CompletableFuture = - thenComposeAsync( - { page -> - page - .filter { it.data().all(action) } - .map { it.getNextPage().forEach(action, executor) } - .orElseGet { CompletableFuture.completedFuture(null) } - }, - executor, - ) - return CompletableFuture.completedFuture(Optional.of(firstPage)) - .forEach(action::test, executor) - } - - fun toList(executor: Executor): CompletableFuture> { - val values = mutableListOf() - return forEach(values::add, executor).thenApply { values } - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return /* spotless:off */ other is VectorStoreSearchPageAsync && service == other.service && params == other.params && response == other.response /* spotless:on */ + return /* spotless:off */ other is VectorStoreSearchPageAsync && service == other.service && streamHandlerExecutor == other.streamHandlerExecutor && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, params, response) /* spotless:on */ + override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, streamHandlerExecutor, params, response) /* spotless:on */ override fun toString() = - "VectorStoreSearchPageAsync{service=$service, params=$params, response=$response}" + "VectorStoreSearchPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, response=$response}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreSearchParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreSearchParams.kt index 849e5ab3..0add3f17 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreSearchParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreSearchParams.kt @@ -37,13 +37,13 @@ import kotlin.jvm.optionals.getOrNull /** Search a vector store for relevant chunks based on a query and file attributes filter. */ class VectorStoreSearchParams private constructor( - private val vectorStoreId: String, + private val vectorStoreId: String?, private val body: Body, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun vectorStoreId(): String = vectorStoreId + fun vectorStoreId(): Optional = Optional.ofNullable(vectorStoreId) /** * A query string for a search @@ -135,7 +135,6 @@ private constructor( * * The following fields are required: * ```java - * .vectorStoreId() * .query() * ``` */ @@ -158,7 +157,11 @@ private constructor( additionalQueryParams = vectorStoreSearchParams.additionalQueryParams.toBuilder() } - fun vectorStoreId(vectorStoreId: String) = apply { this.vectorStoreId = vectorStoreId } + fun vectorStoreId(vectorStoreId: String?) = apply { this.vectorStoreId = vectorStoreId } + + /** Alias for calling [Builder.vectorStoreId] with `vectorStoreId.orElse(null)`. */ + fun vectorStoreId(vectorStoreId: Optional) = + vectorStoreId(vectorStoreId.getOrNull()) /** * Sets the entire request body. @@ -379,7 +382,6 @@ private constructor( * * The following fields are required: * ```java - * .vectorStoreId() * .query() * ``` * @@ -387,7 +389,7 @@ private constructor( */ fun build(): VectorStoreSearchParams = VectorStoreSearchParams( - checkRequired("vectorStoreId", vectorStoreId), + vectorStoreId, body.build(), additionalHeaders.build(), additionalQueryParams.build(), @@ -398,7 +400,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> vectorStoreId + 0 -> vectorStoreId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreUpdateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreUpdateParams.kt index e28e249a..905256cb 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreUpdateParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/VectorStoreUpdateParams.kt @@ -24,13 +24,13 @@ import kotlin.jvm.optionals.getOrNull /** Modifies a vector store. */ class VectorStoreUpdateParams private constructor( - private val vectorStoreId: String, + private val vectorStoreId: String?, private val body: Body, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun vectorStoreId(): String = vectorStoreId + fun vectorStoreId(): Optional = Optional.ofNullable(vectorStoreId) /** * The expiration policy for a vector store. @@ -92,14 +92,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [VectorStoreUpdateParams]. - * - * The following fields are required: - * ```java - * .vectorStoreId() - * ``` - */ + @JvmStatic fun none(): VectorStoreUpdateParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [VectorStoreUpdateParams]. */ @JvmStatic fun builder() = Builder() } @@ -119,7 +114,11 @@ private constructor( additionalQueryParams = vectorStoreUpdateParams.additionalQueryParams.toBuilder() } - fun vectorStoreId(vectorStoreId: String) = apply { this.vectorStoreId = vectorStoreId } + fun vectorStoreId(vectorStoreId: String?) = apply { this.vectorStoreId = vectorStoreId } + + /** Alias for calling [Builder.vectorStoreId] with `vectorStoreId.orElse(null)`. */ + fun vectorStoreId(vectorStoreId: Optional) = + vectorStoreId(vectorStoreId.getOrNull()) /** * Sets the entire request body. @@ -307,17 +306,10 @@ private constructor( * Returns an immutable instance of [VectorStoreUpdateParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .vectorStoreId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): VectorStoreUpdateParams = VectorStoreUpdateParams( - checkRequired("vectorStoreId", vectorStoreId), + vectorStoreId, body.build(), additionalHeaders.build(), additionalQueryParams.build(), @@ -328,7 +320,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> vectorStoreId + 0 -> vectorStoreId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/filebatches/FileBatchCancelParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/filebatches/FileBatchCancelParams.kt index 1cc88512..e317488b 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/filebatches/FileBatchCancelParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/filebatches/FileBatchCancelParams.kt @@ -10,6 +10,7 @@ import com.openai.core.http.QueryParams import com.openai.core.toImmutable import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** * Cancel a vector store file batch. This attempts to cancel the processing of files in this batch @@ -18,7 +19,7 @@ import java.util.Optional class FileBatchCancelParams private constructor( private val vectorStoreId: String, - private val batchId: String, + private val batchId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, @@ -26,7 +27,7 @@ private constructor( fun vectorStoreId(): String = vectorStoreId - fun batchId(): String = batchId + fun batchId(): Optional = Optional.ofNullable(batchId) fun _additionalBodyProperties(): Map = additionalBodyProperties @@ -44,7 +45,6 @@ private constructor( * The following fields are required: * ```java * .vectorStoreId() - * .batchId() * ``` */ @JvmStatic fun builder() = Builder() @@ -70,7 +70,10 @@ private constructor( fun vectorStoreId(vectorStoreId: String) = apply { this.vectorStoreId = vectorStoreId } - fun batchId(batchId: String) = apply { this.batchId = batchId } + fun batchId(batchId: String?) = apply { this.batchId = batchId } + + /** Alias for calling [Builder.batchId] with `batchId.orElse(null)`. */ + fun batchId(batchId: Optional) = batchId(batchId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -200,7 +203,6 @@ private constructor( * The following fields are required: * ```java * .vectorStoreId() - * .batchId() * ``` * * @throws IllegalStateException if any required field is unset. @@ -208,7 +210,7 @@ private constructor( fun build(): FileBatchCancelParams = FileBatchCancelParams( checkRequired("vectorStoreId", vectorStoreId), - checkRequired("batchId", batchId), + batchId, additionalHeaders.build(), additionalQueryParams.build(), additionalBodyProperties.toImmutable(), @@ -221,7 +223,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { 0 -> vectorStoreId - 1 -> batchId + 1 -> batchId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/filebatches/FileBatchCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/filebatches/FileBatchCreateParams.kt index 6109a4f1..e515321c 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/filebatches/FileBatchCreateParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/filebatches/FileBatchCreateParams.kt @@ -29,13 +29,13 @@ import kotlin.jvm.optionals.getOrNull /** Create a vector store file batch. */ class FileBatchCreateParams private constructor( - private val vectorStoreId: String, + private val vectorStoreId: String?, private val body: Body, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun vectorStoreId(): String = vectorStoreId + fun vectorStoreId(): Optional = Optional.ofNullable(vectorStoreId) /** * A list of [File](https://platform.openai.com/docs/api-reference/files) IDs that the vector @@ -103,7 +103,6 @@ private constructor( * * The following fields are required: * ```java - * .vectorStoreId() * .fileIds() * ``` */ @@ -126,7 +125,11 @@ private constructor( additionalQueryParams = fileBatchCreateParams.additionalQueryParams.toBuilder() } - fun vectorStoreId(vectorStoreId: String) = apply { this.vectorStoreId = vectorStoreId } + fun vectorStoreId(vectorStoreId: String?) = apply { this.vectorStoreId = vectorStoreId } + + /** Alias for calling [Builder.vectorStoreId] with `vectorStoreId.orElse(null)`. */ + fun vectorStoreId(vectorStoreId: Optional) = + vectorStoreId(vectorStoreId.getOrNull()) /** * Sets the entire request body. @@ -349,7 +352,6 @@ private constructor( * * The following fields are required: * ```java - * .vectorStoreId() * .fileIds() * ``` * @@ -357,7 +359,7 @@ private constructor( */ fun build(): FileBatchCreateParams = FileBatchCreateParams( - checkRequired("vectorStoreId", vectorStoreId), + vectorStoreId, body.build(), additionalHeaders.build(), additionalQueryParams.build(), @@ -368,7 +370,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> vectorStoreId + 0 -> vectorStoreId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/filebatches/FileBatchListFilesPage.kt b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/filebatches/FileBatchListFilesPage.kt index 42d724d5..96a6d8b3 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/filebatches/FileBatchListFilesPage.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/filebatches/FileBatchListFilesPage.kt @@ -2,13 +2,13 @@ package com.openai.models.vectorstores.filebatches +import com.openai.core.AutoPager +import com.openai.core.Page import com.openai.core.checkRequired import com.openai.models.vectorstores.files.VectorStoreFile import com.openai.services.blocking.vectorstores.FileBatchService import java.util.Objects import java.util.Optional -import java.util.stream.Stream -import java.util.stream.StreamSupport import kotlin.jvm.optionals.getOrNull /** @see [FileBatchService.listFiles] */ @@ -17,7 +17,7 @@ private constructor( private val service: FileBatchService, private val params: FileBatchListFilesParams, private val response: FileBatchListFilesPageResponse, -) { +) : Page { /** * Delegates to [FileBatchListFilesPageResponse], but gracefully handles missing data. @@ -34,20 +34,16 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): FileBatchListFilesParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): Optional = - getNextPageParams().map { service.listFiles(it) } + override fun nextPage(): FileBatchListFilesPage = service.listFiles(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPager = AutoPager.from(this) /** The parameters that were used to request this page. */ fun params(): FileBatchListFilesParams = params @@ -116,25 +112,6 @@ private constructor( ) } - class AutoPager(private val firstPage: FileBatchListFilesPage) : Iterable { - - override fun iterator(): Iterator = iterator { - var page = firstPage - var index = 0 - while (true) { - while (index < page.data().size) { - yield(page.data()[index++]) - } - page = page.getNextPage().getOrNull() ?: break - index = 0 - } - } - - fun stream(): Stream { - return StreamSupport.stream(spliterator(), false) - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/filebatches/FileBatchListFilesPageAsync.kt b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/filebatches/FileBatchListFilesPageAsync.kt index 7c52c45b..c6ea04c1 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/filebatches/FileBatchListFilesPageAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/filebatches/FileBatchListFilesPageAsync.kt @@ -2,6 +2,8 @@ package com.openai.models.vectorstores.filebatches +import com.openai.core.AutoPagerAsync +import com.openai.core.PageAsync import com.openai.core.checkRequired import com.openai.models.vectorstores.files.VectorStoreFile import com.openai.services.async.vectorstores.FileBatchServiceAsync @@ -9,16 +11,16 @@ import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor -import java.util.function.Predicate import kotlin.jvm.optionals.getOrNull /** @see [FileBatchServiceAsync.listFiles] */ class FileBatchListFilesPageAsync private constructor( private val service: FileBatchServiceAsync, + private val streamHandlerExecutor: Executor, private val params: FileBatchListFilesParams, private val response: FileBatchListFilesPageResponse, -) { +) : PageAsync { /** * Delegates to [FileBatchListFilesPageResponse], but gracefully handles missing data. @@ -35,22 +37,18 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): FileBatchListFilesParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): CompletableFuture> = - getNextPageParams() - .map { service.listFiles(it).thenApply { Optional.of(it) } } - .orElseGet { CompletableFuture.completedFuture(Optional.empty()) } + override fun nextPage(): CompletableFuture = + service.listFiles(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPagerAsync = + AutoPagerAsync.from(this, streamHandlerExecutor) /** The parameters that were used to request this page. */ fun params(): FileBatchListFilesParams = params @@ -68,6 +66,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -79,18 +78,24 @@ private constructor( class Builder internal constructor() { private var service: FileBatchServiceAsync? = null + private var streamHandlerExecutor: Executor? = null private var params: FileBatchListFilesParams? = null private var response: FileBatchListFilesPageResponse? = null @JvmSynthetic internal fun from(fileBatchListFilesPageAsync: FileBatchListFilesPageAsync) = apply { service = fileBatchListFilesPageAsync.service + streamHandlerExecutor = fileBatchListFilesPageAsync.streamHandlerExecutor params = fileBatchListFilesPageAsync.params response = fileBatchListFilesPageAsync.response } fun service(service: FileBatchServiceAsync) = apply { this.service = service } + fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply { + this.streamHandlerExecutor = streamHandlerExecutor + } + /** The parameters that were used to request this page. */ fun params(params: FileBatchListFilesParams) = apply { this.params = params } @@ -105,6 +110,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -114,50 +120,22 @@ private constructor( fun build(): FileBatchListFilesPageAsync = FileBatchListFilesPageAsync( checkRequired("service", service), + checkRequired("streamHandlerExecutor", streamHandlerExecutor), checkRequired("params", params), checkRequired("response", response), ) } - class AutoPager(private val firstPage: FileBatchListFilesPageAsync) { - - fun forEach( - action: Predicate, - executor: Executor, - ): CompletableFuture { - fun CompletableFuture>.forEach( - action: (VectorStoreFile) -> Boolean, - executor: Executor, - ): CompletableFuture = - thenComposeAsync( - { page -> - page - .filter { it.data().all(action) } - .map { it.getNextPage().forEach(action, executor) } - .orElseGet { CompletableFuture.completedFuture(null) } - }, - executor, - ) - return CompletableFuture.completedFuture(Optional.of(firstPage)) - .forEach(action::test, executor) - } - - fun toList(executor: Executor): CompletableFuture> { - val values = mutableListOf() - return forEach(values::add, executor).thenApply { values } - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return /* spotless:off */ other is FileBatchListFilesPageAsync && service == other.service && params == other.params && response == other.response /* spotless:on */ + return /* spotless:off */ other is FileBatchListFilesPageAsync && service == other.service && streamHandlerExecutor == other.streamHandlerExecutor && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, params, response) /* spotless:on */ + override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, streamHandlerExecutor, params, response) /* spotless:on */ override fun toString() = - "FileBatchListFilesPageAsync{service=$service, params=$params, response=$response}" + "FileBatchListFilesPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, response=$response}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/filebatches/FileBatchListFilesParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/filebatches/FileBatchListFilesParams.kt index 2be57ce8..e0b95a1d 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/filebatches/FileBatchListFilesParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/filebatches/FileBatchListFilesParams.kt @@ -18,7 +18,7 @@ import kotlin.jvm.optionals.getOrNull class FileBatchListFilesParams private constructor( private val vectorStoreId: String, - private val batchId: String, + private val batchId: String?, private val after: String?, private val before: String?, private val filter: Filter?, @@ -30,7 +30,7 @@ private constructor( fun vectorStoreId(): String = vectorStoreId - fun batchId(): String = batchId + fun batchId(): Optional = Optional.ofNullable(batchId) /** * A cursor for use in pagination. `after` is an object ID that defines your place in the list. @@ -75,7 +75,6 @@ private constructor( * The following fields are required: * ```java * .vectorStoreId() - * .batchId() * ``` */ @JvmStatic fun builder() = Builder() @@ -109,7 +108,10 @@ private constructor( fun vectorStoreId(vectorStoreId: String) = apply { this.vectorStoreId = vectorStoreId } - fun batchId(batchId: String) = apply { this.batchId = batchId } + fun batchId(batchId: String?) = apply { this.batchId = batchId } + + /** Alias for calling [Builder.batchId] with `batchId.orElse(null)`. */ + fun batchId(batchId: Optional) = batchId(batchId.getOrNull()) /** * A cursor for use in pagination. `after` is an object ID that defines your place in the @@ -270,7 +272,6 @@ private constructor( * The following fields are required: * ```java * .vectorStoreId() - * .batchId() * ``` * * @throws IllegalStateException if any required field is unset. @@ -278,7 +279,7 @@ private constructor( fun build(): FileBatchListFilesParams = FileBatchListFilesParams( checkRequired("vectorStoreId", vectorStoreId), - checkRequired("batchId", batchId), + batchId, after, before, filter, @@ -292,7 +293,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { 0 -> vectorStoreId - 1 -> batchId + 1 -> batchId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/filebatches/FileBatchRetrieveParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/filebatches/FileBatchRetrieveParams.kt index de2b16bd..8a3acc77 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/filebatches/FileBatchRetrieveParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/filebatches/FileBatchRetrieveParams.kt @@ -7,19 +7,21 @@ import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** Retrieves a vector store file batch. */ class FileBatchRetrieveParams private constructor( private val vectorStoreId: String, - private val batchId: String, + private val batchId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { fun vectorStoreId(): String = vectorStoreId - fun batchId(): String = batchId + fun batchId(): Optional = Optional.ofNullable(batchId) fun _additionalHeaders(): Headers = additionalHeaders @@ -35,7 +37,6 @@ private constructor( * The following fields are required: * ```java * .vectorStoreId() - * .batchId() * ``` */ @JvmStatic fun builder() = Builder() @@ -59,7 +60,10 @@ private constructor( fun vectorStoreId(vectorStoreId: String) = apply { this.vectorStoreId = vectorStoreId } - fun batchId(batchId: String) = apply { this.batchId = batchId } + fun batchId(batchId: String?) = apply { this.batchId = batchId } + + /** Alias for calling [Builder.batchId] with `batchId.orElse(null)`. */ + fun batchId(batchId: Optional) = batchId(batchId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -167,7 +171,6 @@ private constructor( * The following fields are required: * ```java * .vectorStoreId() - * .batchId() * ``` * * @throws IllegalStateException if any required field is unset. @@ -175,7 +178,7 @@ private constructor( fun build(): FileBatchRetrieveParams = FileBatchRetrieveParams( checkRequired("vectorStoreId", vectorStoreId), - checkRequired("batchId", batchId), + batchId, additionalHeaders.build(), additionalQueryParams.build(), ) @@ -184,7 +187,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { 0 -> vectorStoreId - 1 -> batchId + 1 -> batchId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileContentPage.kt b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileContentPage.kt index 6bbd3084..e1980ef9 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileContentPage.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileContentPage.kt @@ -2,13 +2,12 @@ package com.openai.models.vectorstores.files +import com.openai.core.AutoPager import com.openai.core.JsonValue +import com.openai.core.Page import com.openai.core.checkRequired import com.openai.services.blocking.vectorstores.FileService import java.util.Objects -import java.util.Optional -import java.util.stream.Stream -import java.util.stream.StreamSupport import kotlin.jvm.optionals.getOrNull /** @see [FileService.content] */ @@ -17,7 +16,7 @@ private constructor( private val service: FileService, private val params: FileContentParams, private val response: FileContentPageResponse, -) { +) : Page { /** * Delegates to [FileContentPageResponse], but gracefully handles missing data. @@ -30,13 +29,16 @@ private constructor( /** @see [FileContentPageResponse.object_] */ fun object_(): JsonValue = response._object_() - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional = Optional.empty() + override fun hasNextPage(): Boolean = items().isNotEmpty() - fun getNextPage(): Optional = getNextPageParams().map { service.content(it) } + fun nextPageParams(): FileContentParams = + throw IllegalStateException("Cannot construct next page params") - fun autoPager(): AutoPager = AutoPager(this) + override fun nextPage(): FileContentPage = service.content(nextPageParams()) + + fun autoPager(): AutoPager = AutoPager.from(this) /** The parameters that were used to request this page. */ fun params(): FileContentParams = params @@ -105,25 +107,6 @@ private constructor( ) } - class AutoPager(private val firstPage: FileContentPage) : Iterable { - - override fun iterator(): Iterator = iterator { - var page = firstPage - var index = 0 - while (true) { - while (index < page.data().size) { - yield(page.data()[index++]) - } - page = page.getNextPage().getOrNull() ?: break - index = 0 - } - } - - fun stream(): Stream { - return StreamSupport.stream(spliterator(), false) - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileContentPageAsync.kt b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileContentPageAsync.kt index a55657f1..30fb9db2 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileContentPageAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileContentPageAsync.kt @@ -2,23 +2,24 @@ package com.openai.models.vectorstores.files +import com.openai.core.AutoPagerAsync import com.openai.core.JsonValue +import com.openai.core.PageAsync import com.openai.core.checkRequired import com.openai.services.async.vectorstores.FileServiceAsync import java.util.Objects -import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor -import java.util.function.Predicate import kotlin.jvm.optionals.getOrNull /** @see [FileServiceAsync.content] */ class FileContentPageAsync private constructor( private val service: FileServiceAsync, + private val streamHandlerExecutor: Executor, private val params: FileContentParams, private val response: FileContentPageResponse, -) { +) : PageAsync { /** * Delegates to [FileContentPageResponse], but gracefully handles missing data. @@ -31,16 +32,18 @@ private constructor( /** @see [FileContentPageResponse.object_] */ fun object_(): JsonValue = response._object_() - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional = Optional.empty() + override fun hasNextPage(): Boolean = items().isNotEmpty() - fun getNextPage(): CompletableFuture> = - getNextPageParams() - .map { service.content(it).thenApply { Optional.of(it) } } - .orElseGet { CompletableFuture.completedFuture(Optional.empty()) } + fun nextPageParams(): FileContentParams = + throw IllegalStateException("Cannot construct next page params") - fun autoPager(): AutoPager = AutoPager(this) + override fun nextPage(): CompletableFuture = + service.content(nextPageParams()) + + fun autoPager(): AutoPagerAsync = + AutoPagerAsync.from(this, streamHandlerExecutor) /** The parameters that were used to request this page. */ fun params(): FileContentParams = params @@ -58,6 +61,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -69,18 +73,24 @@ private constructor( class Builder internal constructor() { private var service: FileServiceAsync? = null + private var streamHandlerExecutor: Executor? = null private var params: FileContentParams? = null private var response: FileContentPageResponse? = null @JvmSynthetic internal fun from(fileContentPageAsync: FileContentPageAsync) = apply { service = fileContentPageAsync.service + streamHandlerExecutor = fileContentPageAsync.streamHandlerExecutor params = fileContentPageAsync.params response = fileContentPageAsync.response } fun service(service: FileServiceAsync) = apply { this.service = service } + fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply { + this.streamHandlerExecutor = streamHandlerExecutor + } + /** The parameters that were used to request this page. */ fun params(params: FileContentParams) = apply { this.params = params } @@ -95,6 +105,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -104,50 +115,22 @@ private constructor( fun build(): FileContentPageAsync = FileContentPageAsync( checkRequired("service", service), + checkRequired("streamHandlerExecutor", streamHandlerExecutor), checkRequired("params", params), checkRequired("response", response), ) } - class AutoPager(private val firstPage: FileContentPageAsync) { - - fun forEach( - action: Predicate, - executor: Executor, - ): CompletableFuture { - fun CompletableFuture>.forEach( - action: (FileContentResponse) -> Boolean, - executor: Executor, - ): CompletableFuture = - thenComposeAsync( - { page -> - page - .filter { it.data().all(action) } - .map { it.getNextPage().forEach(action, executor) } - .orElseGet { CompletableFuture.completedFuture(null) } - }, - executor, - ) - return CompletableFuture.completedFuture(Optional.of(firstPage)) - .forEach(action::test, executor) - } - - fun toList(executor: Executor): CompletableFuture> { - val values = mutableListOf() - return forEach(values::add, executor).thenApply { values } - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return /* spotless:off */ other is FileContentPageAsync && service == other.service && params == other.params && response == other.response /* spotless:on */ + return /* spotless:off */ other is FileContentPageAsync && service == other.service && streamHandlerExecutor == other.streamHandlerExecutor && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, params, response) /* spotless:on */ + override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, streamHandlerExecutor, params, response) /* spotless:on */ override fun toString() = - "FileContentPageAsync{service=$service, params=$params, response=$response}" + "FileContentPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, response=$response}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileContentParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileContentParams.kt index e52fe40d..24503213 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileContentParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileContentParams.kt @@ -7,19 +7,21 @@ import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** Retrieve the parsed contents of a vector store file. */ class FileContentParams private constructor( private val vectorStoreId: String, - private val fileId: String, + private val fileId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { fun vectorStoreId(): String = vectorStoreId - fun fileId(): String = fileId + fun fileId(): Optional = Optional.ofNullable(fileId) fun _additionalHeaders(): Headers = additionalHeaders @@ -35,7 +37,6 @@ private constructor( * The following fields are required: * ```java * .vectorStoreId() - * .fileId() * ``` */ @JvmStatic fun builder() = Builder() @@ -59,7 +60,10 @@ private constructor( fun vectorStoreId(vectorStoreId: String) = apply { this.vectorStoreId = vectorStoreId } - fun fileId(fileId: String) = apply { this.fileId = fileId } + fun fileId(fileId: String?) = apply { this.fileId = fileId } + + /** Alias for calling [Builder.fileId] with `fileId.orElse(null)`. */ + fun fileId(fileId: Optional) = fileId(fileId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -167,7 +171,6 @@ private constructor( * The following fields are required: * ```java * .vectorStoreId() - * .fileId() * ``` * * @throws IllegalStateException if any required field is unset. @@ -175,7 +178,7 @@ private constructor( fun build(): FileContentParams = FileContentParams( checkRequired("vectorStoreId", vectorStoreId), - checkRequired("fileId", fileId), + fileId, additionalHeaders.build(), additionalQueryParams.build(), ) @@ -184,7 +187,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { 0 -> vectorStoreId - 1 -> fileId + 1 -> fileId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileCreateParams.kt index 339559a0..d6c0af37 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileCreateParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileCreateParams.kt @@ -32,13 +32,13 @@ import kotlin.jvm.optionals.getOrNull */ class FileCreateParams private constructor( - private val vectorStoreId: String, + private val vectorStoreId: String?, private val body: Body, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun vectorStoreId(): String = vectorStoreId + fun vectorStoreId(): Optional = Optional.ofNullable(vectorStoreId) /** * A [File](https://platform.openai.com/docs/api-reference/files) ID that the vector store @@ -106,7 +106,6 @@ private constructor( * * The following fields are required: * ```java - * .vectorStoreId() * .fileId() * ``` */ @@ -129,7 +128,11 @@ private constructor( additionalQueryParams = fileCreateParams.additionalQueryParams.toBuilder() } - fun vectorStoreId(vectorStoreId: String) = apply { this.vectorStoreId = vectorStoreId } + fun vectorStoreId(vectorStoreId: String?) = apply { this.vectorStoreId = vectorStoreId } + + /** Alias for calling [Builder.vectorStoreId] with `vectorStoreId.orElse(null)`. */ + fun vectorStoreId(vectorStoreId: Optional) = + vectorStoreId(vectorStoreId.getOrNull()) /** * Sets the entire request body. @@ -344,7 +347,6 @@ private constructor( * * The following fields are required: * ```java - * .vectorStoreId() * .fileId() * ``` * @@ -352,7 +354,7 @@ private constructor( */ fun build(): FileCreateParams = FileCreateParams( - checkRequired("vectorStoreId", vectorStoreId), + vectorStoreId, body.build(), additionalHeaders.build(), additionalQueryParams.build(), @@ -363,7 +365,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> vectorStoreId + 0 -> vectorStoreId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileDeleteParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileDeleteParams.kt index 7ac510f2..c739cb62 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileDeleteParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileDeleteParams.kt @@ -10,6 +10,7 @@ import com.openai.core.http.QueryParams import com.openai.core.toImmutable import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** * Delete a vector store file. This will remove the file from the vector store but the file itself @@ -19,7 +20,7 @@ import java.util.Optional class FileDeleteParams private constructor( private val vectorStoreId: String, - private val fileId: String, + private val fileId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, @@ -27,7 +28,7 @@ private constructor( fun vectorStoreId(): String = vectorStoreId - fun fileId(): String = fileId + fun fileId(): Optional = Optional.ofNullable(fileId) fun _additionalBodyProperties(): Map = additionalBodyProperties @@ -45,7 +46,6 @@ private constructor( * The following fields are required: * ```java * .vectorStoreId() - * .fileId() * ``` */ @JvmStatic fun builder() = Builder() @@ -71,7 +71,10 @@ private constructor( fun vectorStoreId(vectorStoreId: String) = apply { this.vectorStoreId = vectorStoreId } - fun fileId(fileId: String) = apply { this.fileId = fileId } + fun fileId(fileId: String?) = apply { this.fileId = fileId } + + /** Alias for calling [Builder.fileId] with `fileId.orElse(null)`. */ + fun fileId(fileId: Optional) = fileId(fileId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -201,7 +204,6 @@ private constructor( * The following fields are required: * ```java * .vectorStoreId() - * .fileId() * ``` * * @throws IllegalStateException if any required field is unset. @@ -209,7 +211,7 @@ private constructor( fun build(): FileDeleteParams = FileDeleteParams( checkRequired("vectorStoreId", vectorStoreId), - checkRequired("fileId", fileId), + fileId, additionalHeaders.build(), additionalQueryParams.build(), additionalBodyProperties.toImmutable(), @@ -222,7 +224,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { 0 -> vectorStoreId - 1 -> fileId + 1 -> fileId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileListPage.kt b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileListPage.kt index 51c03261..d77b54c0 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileListPage.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileListPage.kt @@ -2,12 +2,12 @@ package com.openai.models.vectorstores.files +import com.openai.core.AutoPager +import com.openai.core.Page import com.openai.core.checkRequired import com.openai.services.blocking.vectorstores.FileService import java.util.Objects import java.util.Optional -import java.util.stream.Stream -import java.util.stream.StreamSupport import kotlin.jvm.optionals.getOrNull /** @see [FileService.list] */ @@ -16,7 +16,7 @@ private constructor( private val service: FileService, private val params: FileListParams, private val response: FileListPageResponse, -) { +) : Page { /** * Delegates to [FileListPageResponse], but gracefully handles missing data. @@ -33,19 +33,16 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): FileListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): Optional = getNextPageParams().map { service.list(it) } + override fun nextPage(): FileListPage = service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPager = AutoPager.from(this) /** The parameters that were used to request this page. */ fun params(): FileListParams = params @@ -114,25 +111,6 @@ private constructor( ) } - class AutoPager(private val firstPage: FileListPage) : Iterable { - - override fun iterator(): Iterator = iterator { - var page = firstPage - var index = 0 - while (true) { - while (index < page.data().size) { - yield(page.data()[index++]) - } - page = page.getNextPage().getOrNull() ?: break - index = 0 - } - } - - fun stream(): Stream { - return StreamSupport.stream(spliterator(), false) - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileListPageAsync.kt b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileListPageAsync.kt index ace12328..f4211867 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileListPageAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileListPageAsync.kt @@ -2,22 +2,24 @@ package com.openai.models.vectorstores.files +import com.openai.core.AutoPagerAsync +import com.openai.core.PageAsync import com.openai.core.checkRequired import com.openai.services.async.vectorstores.FileServiceAsync import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor -import java.util.function.Predicate import kotlin.jvm.optionals.getOrNull /** @see [FileServiceAsync.list] */ class FileListPageAsync private constructor( private val service: FileServiceAsync, + private val streamHandlerExecutor: Executor, private val params: FileListParams, private val response: FileListPageResponse, -) { +) : PageAsync { /** * Delegates to [FileListPageResponse], but gracefully handles missing data. @@ -34,22 +36,17 @@ private constructor( */ fun hasMore(): Optional = response._hasMore().getOptional("has_more") - fun hasNextPage(): Boolean = data().isNotEmpty() + override fun items(): List = data() - fun getNextPageParams(): Optional { - if (!hasNextPage()) { - return Optional.empty() - } + override fun hasNextPage(): Boolean = items().isNotEmpty() - return Optional.of(params.toBuilder().after(data().last()._id().getOptional("id")).build()) - } + fun nextPageParams(): FileListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() - fun getNextPage(): CompletableFuture> = - getNextPageParams() - .map { service.list(it).thenApply { Optional.of(it) } } - .orElseGet { CompletableFuture.completedFuture(Optional.empty()) } + override fun nextPage(): CompletableFuture = service.list(nextPageParams()) - fun autoPager(): AutoPager = AutoPager(this) + fun autoPager(): AutoPagerAsync = + AutoPagerAsync.from(this, streamHandlerExecutor) /** The parameters that were used to request this page. */ fun params(): FileListParams = params @@ -67,6 +64,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -78,18 +76,24 @@ private constructor( class Builder internal constructor() { private var service: FileServiceAsync? = null + private var streamHandlerExecutor: Executor? = null private var params: FileListParams? = null private var response: FileListPageResponse? = null @JvmSynthetic internal fun from(fileListPageAsync: FileListPageAsync) = apply { service = fileListPageAsync.service + streamHandlerExecutor = fileListPageAsync.streamHandlerExecutor params = fileListPageAsync.params response = fileListPageAsync.response } fun service(service: FileServiceAsync) = apply { this.service = service } + fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply { + this.streamHandlerExecutor = streamHandlerExecutor + } + /** The parameters that were used to request this page. */ fun params(params: FileListParams) = apply { this.params = params } @@ -104,6 +108,7 @@ private constructor( * The following fields are required: * ```java * .service() + * .streamHandlerExecutor() * .params() * .response() * ``` @@ -113,50 +118,22 @@ private constructor( fun build(): FileListPageAsync = FileListPageAsync( checkRequired("service", service), + checkRequired("streamHandlerExecutor", streamHandlerExecutor), checkRequired("params", params), checkRequired("response", response), ) } - class AutoPager(private val firstPage: FileListPageAsync) { - - fun forEach( - action: Predicate, - executor: Executor, - ): CompletableFuture { - fun CompletableFuture>.forEach( - action: (VectorStoreFile) -> Boolean, - executor: Executor, - ): CompletableFuture = - thenComposeAsync( - { page -> - page - .filter { it.data().all(action) } - .map { it.getNextPage().forEach(action, executor) } - .orElseGet { CompletableFuture.completedFuture(null) } - }, - executor, - ) - return CompletableFuture.completedFuture(Optional.of(firstPage)) - .forEach(action::test, executor) - } - - fun toList(executor: Executor): CompletableFuture> { - val values = mutableListOf() - return forEach(values::add, executor).thenApply { values } - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return /* spotless:off */ other is FileListPageAsync && service == other.service && params == other.params && response == other.response /* spotless:on */ + return /* spotless:off */ other is FileListPageAsync && service == other.service && streamHandlerExecutor == other.streamHandlerExecutor && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, params, response) /* spotless:on */ + override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, streamHandlerExecutor, params, response) /* spotless:on */ override fun toString() = - "FileListPageAsync{service=$service, params=$params, response=$response}" + "FileListPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, response=$response}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileListParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileListParams.kt index 4f0240de..c2ca930c 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileListParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileListParams.kt @@ -6,7 +6,6 @@ import com.fasterxml.jackson.annotation.JsonCreator import com.openai.core.Enum import com.openai.core.JsonField import com.openai.core.Params -import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import com.openai.errors.OpenAIInvalidDataException @@ -17,7 +16,7 @@ import kotlin.jvm.optionals.getOrNull /** Returns a list of vector store files. */ class FileListParams private constructor( - private val vectorStoreId: String, + private val vectorStoreId: String?, private val after: String?, private val before: String?, private val filter: Filter?, @@ -27,7 +26,7 @@ private constructor( private val additionalQueryParams: QueryParams, ) : Params { - fun vectorStoreId(): String = vectorStoreId + fun vectorStoreId(): Optional = Optional.ofNullable(vectorStoreId) /** * A cursor for use in pagination. `after` is an object ID that defines your place in the list. @@ -66,14 +65,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [FileListParams]. - * - * The following fields are required: - * ```java - * .vectorStoreId() - * ``` - */ + @JvmStatic fun none(): FileListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [FileListParams]. */ @JvmStatic fun builder() = Builder() } @@ -101,7 +95,11 @@ private constructor( additionalQueryParams = fileListParams.additionalQueryParams.toBuilder() } - fun vectorStoreId(vectorStoreId: String) = apply { this.vectorStoreId = vectorStoreId } + fun vectorStoreId(vectorStoreId: String?) = apply { this.vectorStoreId = vectorStoreId } + + /** Alias for calling [Builder.vectorStoreId] with `vectorStoreId.orElse(null)`. */ + fun vectorStoreId(vectorStoreId: Optional) = + vectorStoreId(vectorStoreId.getOrNull()) /** * A cursor for use in pagination. `after` is an object ID that defines your place in the @@ -258,17 +256,10 @@ private constructor( * Returns an immutable instance of [FileListParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .vectorStoreId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): FileListParams = FileListParams( - checkRequired("vectorStoreId", vectorStoreId), + vectorStoreId, after, before, filter, @@ -281,7 +272,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> vectorStoreId + 0 -> vectorStoreId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileRetrieveParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileRetrieveParams.kt index 5ab12455..f81b1127 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileRetrieveParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileRetrieveParams.kt @@ -7,19 +7,21 @@ import com.openai.core.checkRequired import com.openai.core.http.Headers import com.openai.core.http.QueryParams import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** Retrieves a vector store file. */ class FileRetrieveParams private constructor( private val vectorStoreId: String, - private val fileId: String, + private val fileId: String?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { fun vectorStoreId(): String = vectorStoreId - fun fileId(): String = fileId + fun fileId(): Optional = Optional.ofNullable(fileId) fun _additionalHeaders(): Headers = additionalHeaders @@ -35,7 +37,6 @@ private constructor( * The following fields are required: * ```java * .vectorStoreId() - * .fileId() * ``` */ @JvmStatic fun builder() = Builder() @@ -59,7 +60,10 @@ private constructor( fun vectorStoreId(vectorStoreId: String) = apply { this.vectorStoreId = vectorStoreId } - fun fileId(fileId: String) = apply { this.fileId = fileId } + fun fileId(fileId: String?) = apply { this.fileId = fileId } + + /** Alias for calling [Builder.fileId] with `fileId.orElse(null)`. */ + fun fileId(fileId: Optional) = fileId(fileId.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -167,7 +171,6 @@ private constructor( * The following fields are required: * ```java * .vectorStoreId() - * .fileId() * ``` * * @throws IllegalStateException if any required field is unset. @@ -175,7 +178,7 @@ private constructor( fun build(): FileRetrieveParams = FileRetrieveParams( checkRequired("vectorStoreId", vectorStoreId), - checkRequired("fileId", fileId), + fileId, additionalHeaders.build(), additionalQueryParams.build(), ) @@ -184,7 +187,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { 0 -> vectorStoreId - 1 -> fileId + 1 -> fileId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileUpdateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileUpdateParams.kt index c5dbccbd..2377d4d2 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileUpdateParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/vectorstores/files/FileUpdateParams.kt @@ -25,7 +25,7 @@ import kotlin.jvm.optionals.getOrNull class FileUpdateParams private constructor( private val vectorStoreId: String, - private val fileId: String, + private val fileId: String?, private val body: Body, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, @@ -33,7 +33,7 @@ private constructor( fun vectorStoreId(): String = vectorStoreId - fun fileId(): String = fileId + fun fileId(): Optional = Optional.ofNullable(fileId) /** * Set of 16 key-value pairs that can be attached to an object. This can be useful for storing @@ -69,7 +69,6 @@ private constructor( * The following fields are required: * ```java * .vectorStoreId() - * .fileId() * .attributes() * ``` */ @@ -96,7 +95,10 @@ private constructor( fun vectorStoreId(vectorStoreId: String) = apply { this.vectorStoreId = vectorStoreId } - fun fileId(fileId: String) = apply { this.fileId = fileId } + fun fileId(fileId: String?) = apply { this.fileId = fileId } + + /** Alias for calling [Builder.fileId] with `fileId.orElse(null)`. */ + fun fileId(fileId: Optional) = fileId(fileId.getOrNull()) /** * Sets the entire request body. @@ -253,7 +255,6 @@ private constructor( * The following fields are required: * ```java * .vectorStoreId() - * .fileId() * .attributes() * ``` * @@ -262,7 +263,7 @@ private constructor( fun build(): FileUpdateParams = FileUpdateParams( checkRequired("vectorStoreId", vectorStoreId), - checkRequired("fileId", fileId), + fileId, body.build(), additionalHeaders.build(), additionalQueryParams.build(), @@ -274,7 +275,7 @@ private constructor( fun _pathParam(index: Int): String = when (index) { 0 -> vectorStoreId - 1 -> fileId + 1 -> fileId ?: "" else -> "" } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/BatchServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/BatchServiceAsync.kt index 45dd0c24..84bc4043 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/BatchServiceAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/BatchServiceAsync.kt @@ -31,8 +31,22 @@ interface BatchServiceAsync { ): CompletableFuture /** Retrieves a batch. */ - fun retrieve(params: BatchRetrieveParams): CompletableFuture = - retrieve(params, RequestOptions.none()) + fun retrieve(batchId: String): CompletableFuture = + retrieve(batchId, BatchRetrieveParams.none()) + + /** @see [retrieve] */ + fun retrieve( + batchId: String, + params: BatchRetrieveParams = BatchRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + retrieve(params.toBuilder().batchId(batchId).build(), requestOptions) + + /** @see [retrieve] */ + fun retrieve( + batchId: String, + params: BatchRetrieveParams = BatchRetrieveParams.none(), + ): CompletableFuture = retrieve(batchId, params, RequestOptions.none()) /** @see [retrieve] */ fun retrieve( @@ -40,6 +54,14 @@ interface BatchServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [retrieve] */ + fun retrieve(params: BatchRetrieveParams): CompletableFuture = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve(batchId: String, requestOptions: RequestOptions): CompletableFuture = + retrieve(batchId, BatchRetrieveParams.none(), requestOptions) + /** List your organization's batches. */ fun list(): CompletableFuture = list(BatchListParams.none()) @@ -63,8 +85,22 @@ interface BatchServiceAsync { * before changing to `cancelled`, where it will have partial results (if any) available in the * output file. */ - fun cancel(params: BatchCancelParams): CompletableFuture = - cancel(params, RequestOptions.none()) + fun cancel(batchId: String): CompletableFuture = + cancel(batchId, BatchCancelParams.none()) + + /** @see [cancel] */ + fun cancel( + batchId: String, + params: BatchCancelParams = BatchCancelParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + cancel(params.toBuilder().batchId(batchId).build(), requestOptions) + + /** @see [cancel] */ + fun cancel( + batchId: String, + params: BatchCancelParams = BatchCancelParams.none(), + ): CompletableFuture = cancel(batchId, params, RequestOptions.none()) /** @see [cancel] */ fun cancel( @@ -72,6 +108,14 @@ interface BatchServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [cancel] */ + fun cancel(params: BatchCancelParams): CompletableFuture = + cancel(params, RequestOptions.none()) + + /** @see [cancel] */ + fun cancel(batchId: String, requestOptions: RequestOptions): CompletableFuture = + cancel(batchId, BatchCancelParams.none(), requestOptions) + /** A view of [BatchServiceAsync] that provides access to raw HTTP responses for each method. */ interface WithRawResponse { @@ -95,8 +139,25 @@ interface BatchServiceAsync { * [BatchServiceAsync.retrieve]. */ @MustBeClosed - fun retrieve(params: BatchRetrieveParams): CompletableFuture> = - retrieve(params, RequestOptions.none()) + fun retrieve(batchId: String): CompletableFuture> = + retrieve(batchId, BatchRetrieveParams.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + batchId: String, + params: BatchRetrieveParams = BatchRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + retrieve(params.toBuilder().batchId(batchId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + batchId: String, + params: BatchRetrieveParams = BatchRetrieveParams.none(), + ): CompletableFuture> = + retrieve(batchId, params, RequestOptions.none()) /** @see [retrieve] */ @MustBeClosed @@ -105,6 +166,19 @@ interface BatchServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** @see [retrieve] */ + @MustBeClosed + fun retrieve(params: BatchRetrieveParams): CompletableFuture> = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + batchId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + retrieve(batchId, BatchRetrieveParams.none(), requestOptions) + /** * Returns a raw HTTP response for `get /batches`, but is otherwise the same as * [BatchServiceAsync.list]. @@ -139,8 +213,25 @@ interface BatchServiceAsync { * same as [BatchServiceAsync.cancel]. */ @MustBeClosed - fun cancel(params: BatchCancelParams): CompletableFuture> = - cancel(params, RequestOptions.none()) + fun cancel(batchId: String): CompletableFuture> = + cancel(batchId, BatchCancelParams.none()) + + /** @see [cancel] */ + @MustBeClosed + fun cancel( + batchId: String, + params: BatchCancelParams = BatchCancelParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + cancel(params.toBuilder().batchId(batchId).build(), requestOptions) + + /** @see [cancel] */ + @MustBeClosed + fun cancel( + batchId: String, + params: BatchCancelParams = BatchCancelParams.none(), + ): CompletableFuture> = + cancel(batchId, params, RequestOptions.none()) /** @see [cancel] */ @MustBeClosed @@ -148,5 +239,18 @@ interface BatchServiceAsync { params: BatchCancelParams, requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + + /** @see [cancel] */ + @MustBeClosed + fun cancel(params: BatchCancelParams): CompletableFuture> = + cancel(params, RequestOptions.none()) + + /** @see [cancel] */ + @MustBeClosed + fun cancel( + batchId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + cancel(batchId, BatchCancelParams.none(), requestOptions) } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/BatchServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/BatchServiceAsyncImpl.kt index 82fbc507..bcd74110 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/BatchServiceAsyncImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/BatchServiceAsyncImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.async import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -23,6 +24,7 @@ import com.openai.models.batches.BatchListPageResponse import com.openai.models.batches.BatchListParams import com.openai.models.batches.BatchRetrieveParams import java.util.concurrent.CompletableFuture +import kotlin.jvm.optionals.getOrNull class BatchServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : BatchServiceAsync { @@ -103,6 +105,9 @@ class BatchServiceAsyncImpl internal constructor(private val clientOptions: Clie params: BatchRetrieveParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("batchId", params.batchId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -154,6 +159,7 @@ class BatchServiceAsyncImpl internal constructor(private val clientOptions: Clie .let { BatchListPageAsync.builder() .service(BatchServiceAsyncImpl(clientOptions)) + .streamHandlerExecutor(clientOptions.streamHandlerExecutor) .params(params) .response(it) .build() @@ -169,6 +175,9 @@ class BatchServiceAsyncImpl internal constructor(private val clientOptions: Clie params: BatchCancelParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("batchId", params.batchId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/EvalServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/EvalServiceAsync.kt index 8c2fad82..d3b27075 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/EvalServiceAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/EvalServiceAsync.kt @@ -44,8 +44,22 @@ interface EvalServiceAsync { ): CompletableFuture /** Get an evaluation by ID. */ - fun retrieve(params: EvalRetrieveParams): CompletableFuture = - retrieve(params, RequestOptions.none()) + fun retrieve(evalId: String): CompletableFuture = + retrieve(evalId, EvalRetrieveParams.none()) + + /** @see [retrieve] */ + fun retrieve( + evalId: String, + params: EvalRetrieveParams = EvalRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + retrieve(params.toBuilder().evalId(evalId).build(), requestOptions) + + /** @see [retrieve] */ + fun retrieve( + evalId: String, + params: EvalRetrieveParams = EvalRetrieveParams.none(), + ): CompletableFuture = retrieve(evalId, params, RequestOptions.none()) /** @see [retrieve] */ fun retrieve( @@ -53,9 +67,34 @@ interface EvalServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [retrieve] */ + fun retrieve(params: EvalRetrieveParams): CompletableFuture = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve( + evalId: String, + requestOptions: RequestOptions, + ): CompletableFuture = + retrieve(evalId, EvalRetrieveParams.none(), requestOptions) + /** Update certain properties of an evaluation. */ - fun update(params: EvalUpdateParams): CompletableFuture = - update(params, RequestOptions.none()) + fun update(evalId: String): CompletableFuture = + update(evalId, EvalUpdateParams.none()) + + /** @see [update] */ + fun update( + evalId: String, + params: EvalUpdateParams = EvalUpdateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + update(params.toBuilder().evalId(evalId).build(), requestOptions) + + /** @see [update] */ + fun update( + evalId: String, + params: EvalUpdateParams = EvalUpdateParams.none(), + ): CompletableFuture = update(evalId, params, RequestOptions.none()) /** @see [update] */ fun update( @@ -63,6 +102,17 @@ interface EvalServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [update] */ + fun update(params: EvalUpdateParams): CompletableFuture = + update(params, RequestOptions.none()) + + /** @see [update] */ + fun update( + evalId: String, + requestOptions: RequestOptions, + ): CompletableFuture = + update(evalId, EvalUpdateParams.none(), requestOptions) + /** List evaluations for a project. */ fun list(): CompletableFuture = list(EvalListParams.none()) @@ -81,8 +131,22 @@ interface EvalServiceAsync { list(EvalListParams.none(), requestOptions) /** Delete an evaluation. */ - fun delete(params: EvalDeleteParams): CompletableFuture = - delete(params, RequestOptions.none()) + fun delete(evalId: String): CompletableFuture = + delete(evalId, EvalDeleteParams.none()) + + /** @see [delete] */ + fun delete( + evalId: String, + params: EvalDeleteParams = EvalDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + delete(params.toBuilder().evalId(evalId).build(), requestOptions) + + /** @see [delete] */ + fun delete( + evalId: String, + params: EvalDeleteParams = EvalDeleteParams.none(), + ): CompletableFuture = delete(evalId, params, RequestOptions.none()) /** @see [delete] */ fun delete( @@ -90,6 +154,17 @@ interface EvalServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [delete] */ + fun delete(params: EvalDeleteParams): CompletableFuture = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + fun delete( + evalId: String, + requestOptions: RequestOptions, + ): CompletableFuture = + delete(evalId, EvalDeleteParams.none(), requestOptions) + /** A view of [EvalServiceAsync] that provides access to raw HTTP responses for each method. */ interface WithRawResponse { @@ -117,10 +192,25 @@ interface EvalServiceAsync { * [EvalServiceAsync.retrieve]. */ @MustBeClosed + fun retrieve(evalId: String): CompletableFuture> = + retrieve(evalId, EvalRetrieveParams.none()) + + /** @see [retrieve] */ + @MustBeClosed fun retrieve( - params: EvalRetrieveParams + evalId: String, + params: EvalRetrieveParams = EvalRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> = - retrieve(params, RequestOptions.none()) + retrieve(params.toBuilder().evalId(evalId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + evalId: String, + params: EvalRetrieveParams = EvalRetrieveParams.none(), + ): CompletableFuture> = + retrieve(evalId, params, RequestOptions.none()) /** @see [retrieve] */ @MustBeClosed @@ -129,15 +219,45 @@ interface EvalServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: EvalRetrieveParams + ): CompletableFuture> = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + evalId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + retrieve(evalId, EvalRetrieveParams.none(), requestOptions) + /** * Returns a raw HTTP response for `post /evals/{eval_id}`, but is otherwise the same as * [EvalServiceAsync.update]. */ @MustBeClosed + fun update(evalId: String): CompletableFuture> = + update(evalId, EvalUpdateParams.none()) + + /** @see [update] */ + @MustBeClosed fun update( - params: EvalUpdateParams + evalId: String, + params: EvalUpdateParams = EvalUpdateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> = - update(params, RequestOptions.none()) + update(params.toBuilder().evalId(evalId).build(), requestOptions) + + /** @see [update] */ + @MustBeClosed + fun update( + evalId: String, + params: EvalUpdateParams = EvalUpdateParams.none(), + ): CompletableFuture> = + update(evalId, params, RequestOptions.none()) /** @see [update] */ @MustBeClosed @@ -146,6 +266,21 @@ interface EvalServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** @see [update] */ + @MustBeClosed + fun update( + params: EvalUpdateParams + ): CompletableFuture> = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + evalId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + update(evalId, EvalUpdateParams.none(), requestOptions) + /** * Returns a raw HTTP response for `get /evals`, but is otherwise the same as * [EvalServiceAsync.list]. @@ -180,10 +315,25 @@ interface EvalServiceAsync { * [EvalServiceAsync.delete]. */ @MustBeClosed + fun delete(evalId: String): CompletableFuture> = + delete(evalId, EvalDeleteParams.none()) + + /** @see [delete] */ + @MustBeClosed fun delete( - params: EvalDeleteParams + evalId: String, + params: EvalDeleteParams = EvalDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> = - delete(params, RequestOptions.none()) + delete(params.toBuilder().evalId(evalId).build(), requestOptions) + + /** @see [delete] */ + @MustBeClosed + fun delete( + evalId: String, + params: EvalDeleteParams = EvalDeleteParams.none(), + ): CompletableFuture> = + delete(evalId, params, RequestOptions.none()) /** @see [delete] */ @MustBeClosed @@ -191,5 +341,20 @@ interface EvalServiceAsync { params: EvalDeleteParams, requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: EvalDeleteParams + ): CompletableFuture> = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + evalId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + delete(evalId, EvalDeleteParams.none(), requestOptions) } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/EvalServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/EvalServiceAsyncImpl.kt index 46b90a99..8ceac275 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/EvalServiceAsyncImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/EvalServiceAsyncImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.async import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -29,6 +30,7 @@ import com.openai.models.evals.EvalUpdateResponse import com.openai.services.async.evals.RunServiceAsync import com.openai.services.async.evals.RunServiceAsyncImpl import java.util.concurrent.CompletableFuture +import kotlin.jvm.optionals.getOrNull class EvalServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : EvalServiceAsync { @@ -127,6 +129,9 @@ class EvalServiceAsyncImpl internal constructor(private val clientOptions: Clien params: EvalRetrieveParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("evalId", params.evalId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -156,6 +161,9 @@ class EvalServiceAsyncImpl internal constructor(private val clientOptions: Clien params: EvalUpdateParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("evalId", params.evalId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -208,6 +216,7 @@ class EvalServiceAsyncImpl internal constructor(private val clientOptions: Clien .let { EvalListPageAsync.builder() .service(EvalServiceAsyncImpl(clientOptions)) + .streamHandlerExecutor(clientOptions.streamHandlerExecutor) .params(params) .response(it) .build() @@ -223,6 +232,9 @@ class EvalServiceAsyncImpl internal constructor(private val clientOptions: Clien params: EvalDeleteParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("evalId", params.evalId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.DELETE) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/FileServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/FileServiceAsync.kt index 1da62fdf..6cc13c80 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/FileServiceAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/FileServiceAsync.kt @@ -52,8 +52,22 @@ interface FileServiceAsync { ): CompletableFuture /** Returns information about a specific file. */ - fun retrieve(params: FileRetrieveParams): CompletableFuture = - retrieve(params, RequestOptions.none()) + fun retrieve(fileId: String): CompletableFuture = + retrieve(fileId, FileRetrieveParams.none()) + + /** @see [retrieve] */ + fun retrieve( + fileId: String, + params: FileRetrieveParams = FileRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + retrieve(params.toBuilder().fileId(fileId).build(), requestOptions) + + /** @see [retrieve] */ + fun retrieve( + fileId: String, + params: FileRetrieveParams = FileRetrieveParams.none(), + ): CompletableFuture = retrieve(fileId, params, RequestOptions.none()) /** @see [retrieve] */ fun retrieve( @@ -61,6 +75,14 @@ interface FileServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [retrieve] */ + fun retrieve(params: FileRetrieveParams): CompletableFuture = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve(fileId: String, requestOptions: RequestOptions): CompletableFuture = + retrieve(fileId, FileRetrieveParams.none(), requestOptions) + /** Returns a list of files. */ fun list(): CompletableFuture = list(FileListParams.none()) @@ -79,8 +101,22 @@ interface FileServiceAsync { list(FileListParams.none(), requestOptions) /** Delete a file. */ - fun delete(params: FileDeleteParams): CompletableFuture = - delete(params, RequestOptions.none()) + fun delete(fileId: String): CompletableFuture = + delete(fileId, FileDeleteParams.none()) + + /** @see [delete] */ + fun delete( + fileId: String, + params: FileDeleteParams = FileDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + delete(params.toBuilder().fileId(fileId).build(), requestOptions) + + /** @see [delete] */ + fun delete( + fileId: String, + params: FileDeleteParams = FileDeleteParams.none(), + ): CompletableFuture = delete(fileId, params, RequestOptions.none()) /** @see [delete] */ fun delete( @@ -88,10 +124,34 @@ interface FileServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [delete] */ + fun delete(params: FileDeleteParams): CompletableFuture = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + fun delete(fileId: String, requestOptions: RequestOptions): CompletableFuture = + delete(fileId, FileDeleteParams.none(), requestOptions) + /** Returns the contents of the specified file. */ @MustBeClosed - fun content(params: FileContentParams): CompletableFuture = - content(params, RequestOptions.none()) + fun content(fileId: String): CompletableFuture = + content(fileId, FileContentParams.none()) + + /** @see [content] */ + @MustBeClosed + fun content( + fileId: String, + params: FileContentParams = FileContentParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + content(params.toBuilder().fileId(fileId).build(), requestOptions) + + /** @see [content] */ + @MustBeClosed + fun content( + fileId: String, + params: FileContentParams = FileContentParams.none(), + ): CompletableFuture = content(fileId, params, RequestOptions.none()) /** @see [content] */ @MustBeClosed @@ -100,6 +160,16 @@ interface FileServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [content] */ + @MustBeClosed + fun content(params: FileContentParams): CompletableFuture = + content(params, RequestOptions.none()) + + /** @see [content] */ + @MustBeClosed + fun content(fileId: String, requestOptions: RequestOptions): CompletableFuture = + content(fileId, FileContentParams.none(), requestOptions) + /** A view of [FileServiceAsync] that provides access to raw HTTP responses for each method. */ interface WithRawResponse { @@ -123,8 +193,25 @@ interface FileServiceAsync { * [FileServiceAsync.retrieve]. */ @MustBeClosed - fun retrieve(params: FileRetrieveParams): CompletableFuture> = - retrieve(params, RequestOptions.none()) + fun retrieve(fileId: String): CompletableFuture> = + retrieve(fileId, FileRetrieveParams.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + fileId: String, + params: FileRetrieveParams = FileRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + retrieve(params.toBuilder().fileId(fileId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + fileId: String, + params: FileRetrieveParams = FileRetrieveParams.none(), + ): CompletableFuture> = + retrieve(fileId, params, RequestOptions.none()) /** @see [retrieve] */ @MustBeClosed @@ -133,6 +220,19 @@ interface FileServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** @see [retrieve] */ + @MustBeClosed + fun retrieve(params: FileRetrieveParams): CompletableFuture> = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + fileId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + retrieve(fileId, FileRetrieveParams.none(), requestOptions) + /** * Returns a raw HTTP response for `get /files`, but is otherwise the same as * [FileServiceAsync.list]. @@ -167,8 +267,25 @@ interface FileServiceAsync { * [FileServiceAsync.delete]. */ @MustBeClosed - fun delete(params: FileDeleteParams): CompletableFuture> = - delete(params, RequestOptions.none()) + fun delete(fileId: String): CompletableFuture> = + delete(fileId, FileDeleteParams.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + fileId: String, + params: FileDeleteParams = FileDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + delete(params.toBuilder().fileId(fileId).build(), requestOptions) + + /** @see [delete] */ + @MustBeClosed + fun delete( + fileId: String, + params: FileDeleteParams = FileDeleteParams.none(), + ): CompletableFuture> = + delete(fileId, params, RequestOptions.none()) /** @see [delete] */ @MustBeClosed @@ -177,13 +294,42 @@ interface FileServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** @see [delete] */ + @MustBeClosed + fun delete(params: FileDeleteParams): CompletableFuture> = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + fileId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + delete(fileId, FileDeleteParams.none(), requestOptions) + /** * Returns a raw HTTP response for `get /files/{file_id}/content`, but is otherwise the same * as [FileServiceAsync.content]. */ @MustBeClosed - fun content(params: FileContentParams): CompletableFuture = - content(params, RequestOptions.none()) + fun content(fileId: String): CompletableFuture = + content(fileId, FileContentParams.none()) + + /** @see [content] */ + @MustBeClosed + fun content( + fileId: String, + params: FileContentParams = FileContentParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + content(params.toBuilder().fileId(fileId).build(), requestOptions) + + /** @see [content] */ + @MustBeClosed + fun content( + fileId: String, + params: FileContentParams = FileContentParams.none(), + ): CompletableFuture = content(fileId, params, RequestOptions.none()) /** @see [content] */ @MustBeClosed @@ -191,5 +337,18 @@ interface FileServiceAsync { params: FileContentParams, requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + + /** @see [content] */ + @MustBeClosed + fun content(params: FileContentParams): CompletableFuture = + content(params, RequestOptions.none()) + + /** @see [content] */ + @MustBeClosed + fun content( + fileId: String, + requestOptions: RequestOptions, + ): CompletableFuture = + content(fileId, FileContentParams.none(), requestOptions) } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/FileServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/FileServiceAsyncImpl.kt index a60ded87..83a8c11c 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/FileServiceAsyncImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/FileServiceAsyncImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.async import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -27,6 +28,7 @@ import com.openai.models.files.FileListParams import com.openai.models.files.FileObject import com.openai.models.files.FileRetrieveParams import java.util.concurrent.CompletableFuture +import kotlin.jvm.optionals.getOrNull class FileServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : FileServiceAsync { @@ -114,6 +116,9 @@ class FileServiceAsyncImpl internal constructor(private val clientOptions: Clien params: FileRetrieveParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("fileId", params.fileId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -165,6 +170,7 @@ class FileServiceAsyncImpl internal constructor(private val clientOptions: Clien .let { FileListPageAsync.builder() .service(FileServiceAsyncImpl(clientOptions)) + .streamHandlerExecutor(clientOptions.streamHandlerExecutor) .params(params) .response(it) .build() @@ -180,6 +186,9 @@ class FileServiceAsyncImpl internal constructor(private val clientOptions: Clien params: FileDeleteParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("fileId", params.fileId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.DELETE) @@ -207,6 +216,9 @@ class FileServiceAsyncImpl internal constructor(private val clientOptions: Clien params: FileContentParams, requestOptions: RequestOptions, ): CompletableFuture { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("fileId", params.fileId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/FineTuningServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/FineTuningServiceAsync.kt index aaa7bc2c..920bcfcc 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/FineTuningServiceAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/FineTuningServiceAsync.kt @@ -2,8 +2,10 @@ package com.openai.services.async +import com.openai.services.async.finetuning.AlphaServiceAsync import com.openai.services.async.finetuning.CheckpointServiceAsync import com.openai.services.async.finetuning.JobServiceAsync +import com.openai.services.async.finetuning.MethodServiceAsync interface FineTuningServiceAsync { @@ -12,18 +14,26 @@ interface FineTuningServiceAsync { */ fun withRawResponse(): WithRawResponse + fun methods(): MethodServiceAsync + fun jobs(): JobServiceAsync fun checkpoints(): CheckpointServiceAsync + fun alpha(): AlphaServiceAsync + /** * A view of [FineTuningServiceAsync] that provides access to raw HTTP responses for each * method. */ interface WithRawResponse { + fun methods(): MethodServiceAsync.WithRawResponse + fun jobs(): JobServiceAsync.WithRawResponse fun checkpoints(): CheckpointServiceAsync.WithRawResponse + + fun alpha(): AlphaServiceAsync.WithRawResponse } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/FineTuningServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/FineTuningServiceAsyncImpl.kt index ca6f7643..59413489 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/FineTuningServiceAsyncImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/FineTuningServiceAsyncImpl.kt @@ -3,10 +3,14 @@ package com.openai.services.async import com.openai.core.ClientOptions +import com.openai.services.async.finetuning.AlphaServiceAsync +import com.openai.services.async.finetuning.AlphaServiceAsyncImpl import com.openai.services.async.finetuning.CheckpointServiceAsync import com.openai.services.async.finetuning.CheckpointServiceAsyncImpl import com.openai.services.async.finetuning.JobServiceAsync import com.openai.services.async.finetuning.JobServiceAsyncImpl +import com.openai.services.async.finetuning.MethodServiceAsync +import com.openai.services.async.finetuning.MethodServiceAsyncImpl class FineTuningServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : FineTuningServiceAsync { @@ -15,21 +19,33 @@ class FineTuningServiceAsyncImpl internal constructor(private val clientOptions: WithRawResponseImpl(clientOptions) } + private val methods: MethodServiceAsync by lazy { MethodServiceAsyncImpl(clientOptions) } + private val jobs: JobServiceAsync by lazy { JobServiceAsyncImpl(clientOptions) } private val checkpoints: CheckpointServiceAsync by lazy { CheckpointServiceAsyncImpl(clientOptions) } + private val alpha: AlphaServiceAsync by lazy { AlphaServiceAsyncImpl(clientOptions) } + override fun withRawResponse(): FineTuningServiceAsync.WithRawResponse = withRawResponse + override fun methods(): MethodServiceAsync = methods + override fun jobs(): JobServiceAsync = jobs override fun checkpoints(): CheckpointServiceAsync = checkpoints + override fun alpha(): AlphaServiceAsync = alpha + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : FineTuningServiceAsync.WithRawResponse { + private val methods: MethodServiceAsync.WithRawResponse by lazy { + MethodServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + private val jobs: JobServiceAsync.WithRawResponse by lazy { JobServiceAsyncImpl.WithRawResponseImpl(clientOptions) } @@ -38,8 +54,16 @@ class FineTuningServiceAsyncImpl internal constructor(private val clientOptions: CheckpointServiceAsyncImpl.WithRawResponseImpl(clientOptions) } + private val alpha: AlphaServiceAsync.WithRawResponse by lazy { + AlphaServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + override fun methods(): MethodServiceAsync.WithRawResponse = methods + override fun jobs(): JobServiceAsync.WithRawResponse = jobs override fun checkpoints(): CheckpointServiceAsync.WithRawResponse = checkpoints + + override fun alpha(): AlphaServiceAsync.WithRawResponse = alpha } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/GraderServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/GraderServiceAsync.kt new file mode 100644 index 00000000..fdc63d85 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/GraderServiceAsync.kt @@ -0,0 +1,23 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.services.async + +import com.openai.services.async.graders.GraderModelServiceAsync + +interface GraderServiceAsync { + + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + + fun graderModels(): GraderModelServiceAsync + + /** + * A view of [GraderServiceAsync] that provides access to raw HTTP responses for each method. + */ + interface WithRawResponse { + + fun graderModels(): GraderModelServiceAsync.WithRawResponse + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/GraderServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/GraderServiceAsyncImpl.kt new file mode 100644 index 00000000..28ac64f3 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/GraderServiceAsyncImpl.kt @@ -0,0 +1,33 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.services.async + +import com.openai.core.ClientOptions +import com.openai.services.async.graders.GraderModelServiceAsync +import com.openai.services.async.graders.GraderModelServiceAsyncImpl + +class GraderServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + GraderServiceAsync { + + private val withRawResponse: GraderServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + private val graderModels: GraderModelServiceAsync by lazy { + GraderModelServiceAsyncImpl(clientOptions) + } + + override fun withRawResponse(): GraderServiceAsync.WithRawResponse = withRawResponse + + override fun graderModels(): GraderModelServiceAsync = graderModels + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + GraderServiceAsync.WithRawResponse { + + private val graderModels: GraderModelServiceAsync.WithRawResponse by lazy { + GraderModelServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + override fun graderModels(): GraderModelServiceAsync.WithRawResponse = graderModels + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/ModelServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/ModelServiceAsync.kt index 33205d21..993f48db 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/ModelServiceAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/ModelServiceAsync.kt @@ -24,8 +24,21 @@ interface ModelServiceAsync { * Retrieves a model instance, providing basic information about the model such as the owner and * permissioning. */ - fun retrieve(params: ModelRetrieveParams): CompletableFuture = - retrieve(params, RequestOptions.none()) + fun retrieve(model: String): CompletableFuture = + retrieve(model, ModelRetrieveParams.none()) + + /** @see [retrieve] */ + fun retrieve( + model: String, + params: ModelRetrieveParams = ModelRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = retrieve(params.toBuilder().model(model).build(), requestOptions) + + /** @see [retrieve] */ + fun retrieve( + model: String, + params: ModelRetrieveParams = ModelRetrieveParams.none(), + ): CompletableFuture = retrieve(model, params, RequestOptions.none()) /** @see [retrieve] */ fun retrieve( @@ -33,6 +46,14 @@ interface ModelServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [retrieve] */ + fun retrieve(params: ModelRetrieveParams): CompletableFuture = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve(model: String, requestOptions: RequestOptions): CompletableFuture = + retrieve(model, ModelRetrieveParams.none(), requestOptions) + /** * Lists the currently available models, and provides basic information about each one such as * the owner and availability. @@ -58,8 +79,22 @@ interface ModelServiceAsync { * Delete a fine-tuned model. You must have the Owner role in your organization to delete a * model. */ - fun delete(params: ModelDeleteParams): CompletableFuture = - delete(params, RequestOptions.none()) + fun delete(model: String): CompletableFuture = + delete(model, ModelDeleteParams.none()) + + /** @see [delete] */ + fun delete( + model: String, + params: ModelDeleteParams = ModelDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + delete(params.toBuilder().model(model).build(), requestOptions) + + /** @see [delete] */ + fun delete( + model: String, + params: ModelDeleteParams = ModelDeleteParams.none(), + ): CompletableFuture = delete(model, params, RequestOptions.none()) /** @see [delete] */ fun delete( @@ -67,6 +102,14 @@ interface ModelServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [delete] */ + fun delete(params: ModelDeleteParams): CompletableFuture = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + fun delete(model: String, requestOptions: RequestOptions): CompletableFuture = + delete(model, ModelDeleteParams.none(), requestOptions) + /** A view of [ModelServiceAsync] that provides access to raw HTTP responses for each method. */ interface WithRawResponse { @@ -75,8 +118,25 @@ interface ModelServiceAsync { * [ModelServiceAsync.retrieve]. */ @MustBeClosed - fun retrieve(params: ModelRetrieveParams): CompletableFuture> = - retrieve(params, RequestOptions.none()) + fun retrieve(model: String): CompletableFuture> = + retrieve(model, ModelRetrieveParams.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + model: String, + params: ModelRetrieveParams = ModelRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + retrieve(params.toBuilder().model(model).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + model: String, + params: ModelRetrieveParams = ModelRetrieveParams.none(), + ): CompletableFuture> = + retrieve(model, params, RequestOptions.none()) /** @see [retrieve] */ @MustBeClosed @@ -85,6 +145,19 @@ interface ModelServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** @see [retrieve] */ + @MustBeClosed + fun retrieve(params: ModelRetrieveParams): CompletableFuture> = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + model: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + retrieve(model, ModelRetrieveParams.none(), requestOptions) + /** * Returns a raw HTTP response for `get /models`, but is otherwise the same as * [ModelServiceAsync.list]. @@ -119,8 +192,25 @@ interface ModelServiceAsync { * [ModelServiceAsync.delete]. */ @MustBeClosed - fun delete(params: ModelDeleteParams): CompletableFuture> = - delete(params, RequestOptions.none()) + fun delete(model: String): CompletableFuture> = + delete(model, ModelDeleteParams.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + model: String, + params: ModelDeleteParams = ModelDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + delete(params.toBuilder().model(model).build(), requestOptions) + + /** @see [delete] */ + @MustBeClosed + fun delete( + model: String, + params: ModelDeleteParams = ModelDeleteParams.none(), + ): CompletableFuture> = + delete(model, params, RequestOptions.none()) /** @see [delete] */ @MustBeClosed @@ -128,5 +218,18 @@ interface ModelServiceAsync { params: ModelDeleteParams, requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + + /** @see [delete] */ + @MustBeClosed + fun delete(params: ModelDeleteParams): CompletableFuture> = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + model: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + delete(model, ModelDeleteParams.none(), requestOptions) } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/ModelServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/ModelServiceAsyncImpl.kt index 7973eaa3..9f15cdea 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/ModelServiceAsyncImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/ModelServiceAsyncImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.async import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -23,6 +24,7 @@ import com.openai.models.models.ModelListPageResponse import com.openai.models.models.ModelListParams import com.openai.models.models.ModelRetrieveParams import java.util.concurrent.CompletableFuture +import kotlin.jvm.optionals.getOrNull class ModelServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : ModelServiceAsync { @@ -66,12 +68,15 @@ class ModelServiceAsyncImpl internal constructor(private val clientOptions: Clie params: ModelRetrieveParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("model", params.model().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) .addPathSegments("models", params._pathParam(0)) .build() - .prepareAsync(clientOptions, params, params.model()) + .prepareAsync(clientOptions, params, params.model().get()) val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) return request .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } @@ -117,6 +122,7 @@ class ModelServiceAsyncImpl internal constructor(private val clientOptions: Clie .let { ModelListPageAsync.builder() .service(ModelServiceAsyncImpl(clientOptions)) + .streamHandlerExecutor(clientOptions.streamHandlerExecutor) .params(params) .response(it) .build() @@ -132,13 +138,16 @@ class ModelServiceAsyncImpl internal constructor(private val clientOptions: Clie params: ModelDeleteParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("model", params.model().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.DELETE) .addPathSegments("models", params._pathParam(0)) .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } .build() - .prepareAsync(clientOptions, params, params.model()) + .prepareAsync(clientOptions, params, params.model().get()) val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) return request .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/ResponseServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/ResponseServiceAsync.kt index 34042fd2..f66149de 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/ResponseServiceAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/ResponseServiceAsync.kt @@ -66,8 +66,22 @@ interface ResponseServiceAsync { ): AsyncStreamResponse /** Retrieves a model response with the given ID. */ - fun retrieve(params: ResponseRetrieveParams): CompletableFuture = - retrieve(params, RequestOptions.none()) + fun retrieve(responseId: String): CompletableFuture = + retrieve(responseId, ResponseRetrieveParams.none()) + + /** @see [retrieve] */ + fun retrieve( + responseId: String, + params: ResponseRetrieveParams = ResponseRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + retrieve(params.toBuilder().responseId(responseId).build(), requestOptions) + + /** @see [retrieve] */ + fun retrieve( + responseId: String, + params: ResponseRetrieveParams = ResponseRetrieveParams.none(), + ): CompletableFuture = retrieve(responseId, params, RequestOptions.none()) /** @see [retrieve] */ fun retrieve( @@ -75,9 +89,31 @@ interface ResponseServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [retrieve] */ + fun retrieve(params: ResponseRetrieveParams): CompletableFuture = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve(responseId: String, requestOptions: RequestOptions): CompletableFuture = + retrieve(responseId, ResponseRetrieveParams.none(), requestOptions) + /** Deletes a model response with the given ID. */ - fun delete(params: ResponseDeleteParams): CompletableFuture = - delete(params, RequestOptions.none()) + fun delete(responseId: String): CompletableFuture = + delete(responseId, ResponseDeleteParams.none()) + + /** @see [delete] */ + fun delete( + responseId: String, + params: ResponseDeleteParams = ResponseDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + delete(params.toBuilder().responseId(responseId).build(), requestOptions) + + /** @see [delete] */ + fun delete( + responseId: String, + params: ResponseDeleteParams = ResponseDeleteParams.none(), + ): CompletableFuture = delete(responseId, params, RequestOptions.none()) /** @see [delete] */ fun delete( @@ -85,6 +121,14 @@ interface ResponseServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [delete] */ + fun delete(params: ResponseDeleteParams): CompletableFuture = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + fun delete(responseId: String, requestOptions: RequestOptions): CompletableFuture = + delete(responseId, ResponseDeleteParams.none(), requestOptions) + /** * A view of [ResponseServiceAsync] that provides access to raw HTTP responses for each method. */ @@ -129,8 +173,25 @@ interface ResponseServiceAsync { * as [ResponseServiceAsync.retrieve]. */ @MustBeClosed - fun retrieve(params: ResponseRetrieveParams): CompletableFuture> = - retrieve(params, RequestOptions.none()) + fun retrieve(responseId: String): CompletableFuture> = + retrieve(responseId, ResponseRetrieveParams.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + responseId: String, + params: ResponseRetrieveParams = ResponseRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + retrieve(params.toBuilder().responseId(responseId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + responseId: String, + params: ResponseRetrieveParams = ResponseRetrieveParams.none(), + ): CompletableFuture> = + retrieve(responseId, params, RequestOptions.none()) /** @see [retrieve] */ @MustBeClosed @@ -139,13 +200,42 @@ interface ResponseServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** @see [retrieve] */ + @MustBeClosed + fun retrieve(params: ResponseRetrieveParams): CompletableFuture> = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + responseId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + retrieve(responseId, ResponseRetrieveParams.none(), requestOptions) + /** * Returns a raw HTTP response for `delete /responses/{response_id}`, but is otherwise the * same as [ResponseServiceAsync.delete]. */ @MustBeClosed - fun delete(params: ResponseDeleteParams): CompletableFuture = - delete(params, RequestOptions.none()) + fun delete(responseId: String): CompletableFuture = + delete(responseId, ResponseDeleteParams.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + responseId: String, + params: ResponseDeleteParams = ResponseDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + delete(params.toBuilder().responseId(responseId).build(), requestOptions) + + /** @see [delete] */ + @MustBeClosed + fun delete( + responseId: String, + params: ResponseDeleteParams = ResponseDeleteParams.none(), + ): CompletableFuture = delete(responseId, params, RequestOptions.none()) /** @see [delete] */ @MustBeClosed @@ -153,5 +243,18 @@ interface ResponseServiceAsync { params: ResponseDeleteParams, requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + + /** @see [delete] */ + @MustBeClosed + fun delete(params: ResponseDeleteParams): CompletableFuture = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + responseId: String, + requestOptions: RequestOptions, + ): CompletableFuture = + delete(responseId, ResponseDeleteParams.none(), requestOptions) } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/ResponseServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/ResponseServiceAsyncImpl.kt index 122e68f4..7f90cea5 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/ResponseServiceAsyncImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/ResponseServiceAsyncImpl.kt @@ -5,6 +5,7 @@ package com.openai.services.async import com.openai.core.ClientOptions import com.openai.core.JsonValue import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.emptyHandler import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler @@ -32,6 +33,7 @@ import com.openai.models.responses.ResponseStreamEvent import com.openai.services.async.responses.InputItemServiceAsync import com.openai.services.async.responses.InputItemServiceAsyncImpl import java.util.concurrent.CompletableFuture +import kotlin.jvm.optionals.getOrNull class ResponseServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : ResponseServiceAsync { @@ -170,6 +172,9 @@ class ResponseServiceAsyncImpl internal constructor(private val clientOptions: C params: ResponseRetrieveParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("responseId", params.responseId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -198,6 +203,9 @@ class ResponseServiceAsyncImpl internal constructor(private val clientOptions: C params: ResponseDeleteParams, requestOptions: RequestOptions, ): CompletableFuture { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("responseId", params.responseId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.DELETE) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/UploadServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/UploadServiceAsync.kt index 7e0dce0c..98218ac5 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/UploadServiceAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/UploadServiceAsync.kt @@ -51,8 +51,22 @@ interface UploadServiceAsync { ): CompletableFuture /** Cancels the Upload. No Parts may be added after an Upload is cancelled. */ - fun cancel(params: UploadCancelParams): CompletableFuture = - cancel(params, RequestOptions.none()) + fun cancel(uploadId: String): CompletableFuture = + cancel(uploadId, UploadCancelParams.none()) + + /** @see [cancel] */ + fun cancel( + uploadId: String, + params: UploadCancelParams = UploadCancelParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + cancel(params.toBuilder().uploadId(uploadId).build(), requestOptions) + + /** @see [cancel] */ + fun cancel( + uploadId: String, + params: UploadCancelParams = UploadCancelParams.none(), + ): CompletableFuture = cancel(uploadId, params, RequestOptions.none()) /** @see [cancel] */ fun cancel( @@ -60,6 +74,14 @@ interface UploadServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [cancel] */ + fun cancel(params: UploadCancelParams): CompletableFuture = + cancel(params, RequestOptions.none()) + + /** @see [cancel] */ + fun cancel(uploadId: String, requestOptions: RequestOptions): CompletableFuture = + cancel(uploadId, UploadCancelParams.none(), requestOptions) + /** * Completes the [Upload](https://platform.openai.com/docs/api-reference/uploads/object). * @@ -73,6 +95,18 @@ interface UploadServiceAsync { * specified when creating the Upload object. No Parts may be added after an Upload is * completed. */ + fun complete(uploadId: String, params: UploadCompleteParams): CompletableFuture = + complete(uploadId, params, RequestOptions.none()) + + /** @see [complete] */ + fun complete( + uploadId: String, + params: UploadCompleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + complete(params.toBuilder().uploadId(uploadId).build(), requestOptions) + + /** @see [complete] */ fun complete(params: UploadCompleteParams): CompletableFuture = complete(params, RequestOptions.none()) @@ -109,8 +143,25 @@ interface UploadServiceAsync { * same as [UploadServiceAsync.cancel]. */ @MustBeClosed - fun cancel(params: UploadCancelParams): CompletableFuture> = - cancel(params, RequestOptions.none()) + fun cancel(uploadId: String): CompletableFuture> = + cancel(uploadId, UploadCancelParams.none()) + + /** @see [cancel] */ + @MustBeClosed + fun cancel( + uploadId: String, + params: UploadCancelParams = UploadCancelParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + cancel(params.toBuilder().uploadId(uploadId).build(), requestOptions) + + /** @see [cancel] */ + @MustBeClosed + fun cancel( + uploadId: String, + params: UploadCancelParams = UploadCancelParams.none(), + ): CompletableFuture> = + cancel(uploadId, params, RequestOptions.none()) /** @see [cancel] */ @MustBeClosed @@ -119,11 +170,41 @@ interface UploadServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** @see [cancel] */ + @MustBeClosed + fun cancel(params: UploadCancelParams): CompletableFuture> = + cancel(params, RequestOptions.none()) + + /** @see [cancel] */ + @MustBeClosed + fun cancel( + uploadId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + cancel(uploadId, UploadCancelParams.none(), requestOptions) + /** * Returns a raw HTTP response for `post /uploads/{upload_id}/complete`, but is otherwise * the same as [UploadServiceAsync.complete]. */ @MustBeClosed + fun complete( + uploadId: String, + params: UploadCompleteParams, + ): CompletableFuture> = + complete(uploadId, params, RequestOptions.none()) + + /** @see [complete] */ + @MustBeClosed + fun complete( + uploadId: String, + params: UploadCompleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + complete(params.toBuilder().uploadId(uploadId).build(), requestOptions) + + /** @see [complete] */ + @MustBeClosed fun complete(params: UploadCompleteParams): CompletableFuture> = complete(params, RequestOptions.none()) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/UploadServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/UploadServiceAsyncImpl.kt index 9877742d..30cc034a 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/UploadServiceAsyncImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/UploadServiceAsyncImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.async import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -22,6 +23,7 @@ import com.openai.models.uploads.UploadCreateParams import com.openai.services.async.uploads.PartServiceAsync import com.openai.services.async.uploads.PartServiceAsyncImpl import java.util.concurrent.CompletableFuture +import kotlin.jvm.optionals.getOrNull class UploadServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : UploadServiceAsync { @@ -105,6 +107,9 @@ class UploadServiceAsyncImpl internal constructor(private val clientOptions: Cli params: UploadCancelParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("uploadId", params.uploadId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -135,6 +140,9 @@ class UploadServiceAsyncImpl internal constructor(private val clientOptions: Cli params: UploadCompleteParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("uploadId", params.uploadId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/VectorStoreServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/VectorStoreServiceAsync.kt index 4fb10a20..ff07354c 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/VectorStoreServiceAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/VectorStoreServiceAsync.kt @@ -49,8 +49,22 @@ interface VectorStoreServiceAsync { create(VectorStoreCreateParams.none(), requestOptions) /** Retrieves a vector store. */ - fun retrieve(params: VectorStoreRetrieveParams): CompletableFuture = - retrieve(params, RequestOptions.none()) + fun retrieve(vectorStoreId: String): CompletableFuture = + retrieve(vectorStoreId, VectorStoreRetrieveParams.none()) + + /** @see [retrieve] */ + fun retrieve( + vectorStoreId: String, + params: VectorStoreRetrieveParams = VectorStoreRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + retrieve(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) + + /** @see [retrieve] */ + fun retrieve( + vectorStoreId: String, + params: VectorStoreRetrieveParams = VectorStoreRetrieveParams.none(), + ): CompletableFuture = retrieve(vectorStoreId, params, RequestOptions.none()) /** @see [retrieve] */ fun retrieve( @@ -58,9 +72,34 @@ interface VectorStoreServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [retrieve] */ + fun retrieve(params: VectorStoreRetrieveParams): CompletableFuture = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve( + vectorStoreId: String, + requestOptions: RequestOptions, + ): CompletableFuture = + retrieve(vectorStoreId, VectorStoreRetrieveParams.none(), requestOptions) + /** Modifies a vector store. */ - fun update(params: VectorStoreUpdateParams): CompletableFuture = - update(params, RequestOptions.none()) + fun update(vectorStoreId: String): CompletableFuture = + update(vectorStoreId, VectorStoreUpdateParams.none()) + + /** @see [update] */ + fun update( + vectorStoreId: String, + params: VectorStoreUpdateParams = VectorStoreUpdateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + update(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) + + /** @see [update] */ + fun update( + vectorStoreId: String, + params: VectorStoreUpdateParams = VectorStoreUpdateParams.none(), + ): CompletableFuture = update(vectorStoreId, params, RequestOptions.none()) /** @see [update] */ fun update( @@ -68,6 +107,17 @@ interface VectorStoreServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [update] */ + fun update(params: VectorStoreUpdateParams): CompletableFuture = + update(params, RequestOptions.none()) + + /** @see [update] */ + fun update( + vectorStoreId: String, + requestOptions: RequestOptions, + ): CompletableFuture = + update(vectorStoreId, VectorStoreUpdateParams.none(), requestOptions) + /** Returns a list of vector stores. */ fun list(): CompletableFuture = list(VectorStoreListParams.none()) @@ -87,8 +137,22 @@ interface VectorStoreServiceAsync { list(VectorStoreListParams.none(), requestOptions) /** Delete a vector store. */ - fun delete(params: VectorStoreDeleteParams): CompletableFuture = - delete(params, RequestOptions.none()) + fun delete(vectorStoreId: String): CompletableFuture = + delete(vectorStoreId, VectorStoreDeleteParams.none()) + + /** @see [delete] */ + fun delete( + vectorStoreId: String, + params: VectorStoreDeleteParams = VectorStoreDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + delete(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) + + /** @see [delete] */ + fun delete( + vectorStoreId: String, + params: VectorStoreDeleteParams = VectorStoreDeleteParams.none(), + ): CompletableFuture = delete(vectorStoreId, params, RequestOptions.none()) /** @see [delete] */ fun delete( @@ -96,7 +160,33 @@ interface VectorStoreServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [delete] */ + fun delete(params: VectorStoreDeleteParams): CompletableFuture = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + fun delete( + vectorStoreId: String, + requestOptions: RequestOptions, + ): CompletableFuture = + delete(vectorStoreId, VectorStoreDeleteParams.none(), requestOptions) + /** Search a vector store for relevant chunks based on a query and file attributes filter. */ + fun search( + vectorStoreId: String, + params: VectorStoreSearchParams, + ): CompletableFuture = + search(vectorStoreId, params, RequestOptions.none()) + + /** @see [search] */ + fun search( + vectorStoreId: String, + params: VectorStoreSearchParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + search(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) + + /** @see [search] */ fun search(params: VectorStoreSearchParams): CompletableFuture = search(params, RequestOptions.none()) @@ -149,9 +239,25 @@ interface VectorStoreServiceAsync { * the same as [VectorStoreServiceAsync.retrieve]. */ @MustBeClosed + fun retrieve(vectorStoreId: String): CompletableFuture> = + retrieve(vectorStoreId, VectorStoreRetrieveParams.none()) + + /** @see [retrieve] */ + @MustBeClosed fun retrieve( - params: VectorStoreRetrieveParams - ): CompletableFuture> = retrieve(params, RequestOptions.none()) + vectorStoreId: String, + params: VectorStoreRetrieveParams = VectorStoreRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + retrieve(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + vectorStoreId: String, + params: VectorStoreRetrieveParams = VectorStoreRetrieveParams.none(), + ): CompletableFuture> = + retrieve(vectorStoreId, params, RequestOptions.none()) /** @see [retrieve] */ @MustBeClosed @@ -160,14 +266,44 @@ interface VectorStoreServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: VectorStoreRetrieveParams + ): CompletableFuture> = retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + vectorStoreId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + retrieve(vectorStoreId, VectorStoreRetrieveParams.none(), requestOptions) + /** * Returns a raw HTTP response for `post /vector_stores/{vector_store_id}`, but is otherwise * the same as [VectorStoreServiceAsync.update]. */ @MustBeClosed + fun update(vectorStoreId: String): CompletableFuture> = + update(vectorStoreId, VectorStoreUpdateParams.none()) + + /** @see [update] */ + @MustBeClosed fun update( - params: VectorStoreUpdateParams - ): CompletableFuture> = update(params, RequestOptions.none()) + vectorStoreId: String, + params: VectorStoreUpdateParams = VectorStoreUpdateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + update(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) + + /** @see [update] */ + @MustBeClosed + fun update( + vectorStoreId: String, + params: VectorStoreUpdateParams = VectorStoreUpdateParams.none(), + ): CompletableFuture> = + update(vectorStoreId, params, RequestOptions.none()) /** @see [update] */ @MustBeClosed @@ -176,6 +312,20 @@ interface VectorStoreServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** @see [update] */ + @MustBeClosed + fun update( + params: VectorStoreUpdateParams + ): CompletableFuture> = update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + vectorStoreId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + update(vectorStoreId, VectorStoreUpdateParams.none(), requestOptions) + /** * Returns a raw HTTP response for `get /vector_stores`, but is otherwise the same as * [VectorStoreServiceAsync.list]. @@ -210,10 +360,25 @@ interface VectorStoreServiceAsync { * otherwise the same as [VectorStoreServiceAsync.delete]. */ @MustBeClosed + fun delete(vectorStoreId: String): CompletableFuture> = + delete(vectorStoreId, VectorStoreDeleteParams.none()) + + /** @see [delete] */ + @MustBeClosed fun delete( - params: VectorStoreDeleteParams + vectorStoreId: String, + params: VectorStoreDeleteParams = VectorStoreDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> = - delete(params, RequestOptions.none()) + delete(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) + + /** @see [delete] */ + @MustBeClosed + fun delete( + vectorStoreId: String, + params: VectorStoreDeleteParams = VectorStoreDeleteParams.none(), + ): CompletableFuture> = + delete(vectorStoreId, params, RequestOptions.none()) /** @see [delete] */ @MustBeClosed @@ -222,11 +387,43 @@ interface VectorStoreServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** @see [delete] */ + @MustBeClosed + fun delete( + params: VectorStoreDeleteParams + ): CompletableFuture> = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + vectorStoreId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + delete(vectorStoreId, VectorStoreDeleteParams.none(), requestOptions) + /** * Returns a raw HTTP response for `post /vector_stores/{vector_store_id}/search`, but is * otherwise the same as [VectorStoreServiceAsync.search]. */ @MustBeClosed + fun search( + vectorStoreId: String, + params: VectorStoreSearchParams, + ): CompletableFuture> = + search(vectorStoreId, params, RequestOptions.none()) + + /** @see [search] */ + @MustBeClosed + fun search( + vectorStoreId: String, + params: VectorStoreSearchParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + search(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) + + /** @see [search] */ + @MustBeClosed fun search( params: VectorStoreSearchParams ): CompletableFuture> = diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/VectorStoreServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/VectorStoreServiceAsyncImpl.kt index da248f22..346bb073 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/VectorStoreServiceAsyncImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/VectorStoreServiceAsyncImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.async import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -33,6 +34,7 @@ import com.openai.services.async.vectorstores.FileBatchServiceAsyncImpl import com.openai.services.async.vectorstores.FileServiceAsync import com.openai.services.async.vectorstores.FileServiceAsyncImpl import java.util.concurrent.CompletableFuture +import kotlin.jvm.optionals.getOrNull class VectorStoreServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : VectorStoreServiceAsync { @@ -155,6 +157,9 @@ class VectorStoreServiceAsyncImpl internal constructor(private val clientOptions params: VectorStoreRetrieveParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("vectorStoreId", params.vectorStoreId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -185,6 +190,9 @@ class VectorStoreServiceAsyncImpl internal constructor(private val clientOptions params: VectorStoreUpdateParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("vectorStoreId", params.vectorStoreId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -239,6 +247,7 @@ class VectorStoreServiceAsyncImpl internal constructor(private val clientOptions .let { VectorStoreListPageAsync.builder() .service(VectorStoreServiceAsyncImpl(clientOptions)) + .streamHandlerExecutor(clientOptions.streamHandlerExecutor) .params(params) .response(it) .build() @@ -254,6 +263,9 @@ class VectorStoreServiceAsyncImpl internal constructor(private val clientOptions params: VectorStoreDeleteParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("vectorStoreId", params.vectorStoreId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.DELETE) @@ -286,6 +298,9 @@ class VectorStoreServiceAsyncImpl internal constructor(private val clientOptions params: VectorStoreSearchParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("vectorStoreId", params.vectorStoreId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -309,6 +324,7 @@ class VectorStoreServiceAsyncImpl internal constructor(private val clientOptions .let { VectorStoreSearchPageAsync.builder() .service(VectorStoreServiceAsyncImpl(clientOptions)) + .streamHandlerExecutor(clientOptions.streamHandlerExecutor) .params(params) .response(it) .build() diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/beta/AssistantServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/beta/AssistantServiceAsync.kt index 84e33a14..b36485ed 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/beta/AssistantServiceAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/beta/AssistantServiceAsync.kt @@ -33,8 +33,22 @@ interface AssistantServiceAsync { ): CompletableFuture /** Retrieves an assistant. */ - fun retrieve(params: AssistantRetrieveParams): CompletableFuture = - retrieve(params, RequestOptions.none()) + fun retrieve(assistantId: String): CompletableFuture = + retrieve(assistantId, AssistantRetrieveParams.none()) + + /** @see [retrieve] */ + fun retrieve( + assistantId: String, + params: AssistantRetrieveParams = AssistantRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + retrieve(params.toBuilder().assistantId(assistantId).build(), requestOptions) + + /** @see [retrieve] */ + fun retrieve( + assistantId: String, + params: AssistantRetrieveParams = AssistantRetrieveParams.none(), + ): CompletableFuture = retrieve(assistantId, params, RequestOptions.none()) /** @see [retrieve] */ fun retrieve( @@ -42,9 +56,34 @@ interface AssistantServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [retrieve] */ + fun retrieve(params: AssistantRetrieveParams): CompletableFuture = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve( + assistantId: String, + requestOptions: RequestOptions, + ): CompletableFuture = + retrieve(assistantId, AssistantRetrieveParams.none(), requestOptions) + /** Modifies an assistant. */ - fun update(params: AssistantUpdateParams): CompletableFuture = - update(params, RequestOptions.none()) + fun update(assistantId: String): CompletableFuture = + update(assistantId, AssistantUpdateParams.none()) + + /** @see [update] */ + fun update( + assistantId: String, + params: AssistantUpdateParams = AssistantUpdateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + update(params.toBuilder().assistantId(assistantId).build(), requestOptions) + + /** @see [update] */ + fun update( + assistantId: String, + params: AssistantUpdateParams = AssistantUpdateParams.none(), + ): CompletableFuture = update(assistantId, params, RequestOptions.none()) /** @see [update] */ fun update( @@ -52,6 +91,14 @@ interface AssistantServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [update] */ + fun update(params: AssistantUpdateParams): CompletableFuture = + update(params, RequestOptions.none()) + + /** @see [update] */ + fun update(assistantId: String, requestOptions: RequestOptions): CompletableFuture = + update(assistantId, AssistantUpdateParams.none(), requestOptions) + /** Returns a list of assistants. */ fun list(): CompletableFuture = list(AssistantListParams.none()) @@ -71,8 +118,22 @@ interface AssistantServiceAsync { list(AssistantListParams.none(), requestOptions) /** Delete an assistant. */ - fun delete(params: AssistantDeleteParams): CompletableFuture = - delete(params, RequestOptions.none()) + fun delete(assistantId: String): CompletableFuture = + delete(assistantId, AssistantDeleteParams.none()) + + /** @see [delete] */ + fun delete( + assistantId: String, + params: AssistantDeleteParams = AssistantDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + delete(params.toBuilder().assistantId(assistantId).build(), requestOptions) + + /** @see [delete] */ + fun delete( + assistantId: String, + params: AssistantDeleteParams = AssistantDeleteParams.none(), + ): CompletableFuture = delete(assistantId, params, RequestOptions.none()) /** @see [delete] */ fun delete( @@ -80,6 +141,17 @@ interface AssistantServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [delete] */ + fun delete(params: AssistantDeleteParams): CompletableFuture = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + fun delete( + assistantId: String, + requestOptions: RequestOptions, + ): CompletableFuture = + delete(assistantId, AssistantDeleteParams.none(), requestOptions) + /** * A view of [AssistantServiceAsync] that provides access to raw HTTP responses for each method. */ @@ -105,9 +177,25 @@ interface AssistantServiceAsync { * same as [AssistantServiceAsync.retrieve]. */ @MustBeClosed + fun retrieve(assistantId: String): CompletableFuture> = + retrieve(assistantId, AssistantRetrieveParams.none()) + + /** @see [retrieve] */ + @MustBeClosed fun retrieve( - params: AssistantRetrieveParams - ): CompletableFuture> = retrieve(params, RequestOptions.none()) + assistantId: String, + params: AssistantRetrieveParams = AssistantRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + retrieve(params.toBuilder().assistantId(assistantId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + assistantId: String, + params: AssistantRetrieveParams = AssistantRetrieveParams.none(), + ): CompletableFuture> = + retrieve(assistantId, params, RequestOptions.none()) /** @see [retrieve] */ @MustBeClosed @@ -116,13 +204,44 @@ interface AssistantServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: AssistantRetrieveParams + ): CompletableFuture> = retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + assistantId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + retrieve(assistantId, AssistantRetrieveParams.none(), requestOptions) + /** * Returns a raw HTTP response for `post /assistants/{assistant_id}`, but is otherwise the * same as [AssistantServiceAsync.update]. */ @MustBeClosed - fun update(params: AssistantUpdateParams): CompletableFuture> = - update(params, RequestOptions.none()) + fun update(assistantId: String): CompletableFuture> = + update(assistantId, AssistantUpdateParams.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + assistantId: String, + params: AssistantUpdateParams = AssistantUpdateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + update(params.toBuilder().assistantId(assistantId).build(), requestOptions) + + /** @see [update] */ + @MustBeClosed + fun update( + assistantId: String, + params: AssistantUpdateParams = AssistantUpdateParams.none(), + ): CompletableFuture> = + update(assistantId, params, RequestOptions.none()) /** @see [update] */ @MustBeClosed @@ -131,6 +250,19 @@ interface AssistantServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** @see [update] */ + @MustBeClosed + fun update(params: AssistantUpdateParams): CompletableFuture> = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + assistantId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + update(assistantId, AssistantUpdateParams.none(), requestOptions) + /** * Returns a raw HTTP response for `get /assistants`, but is otherwise the same as * [AssistantServiceAsync.list]. @@ -165,10 +297,25 @@ interface AssistantServiceAsync { * same as [AssistantServiceAsync.delete]. */ @MustBeClosed + fun delete(assistantId: String): CompletableFuture> = + delete(assistantId, AssistantDeleteParams.none()) + + /** @see [delete] */ + @MustBeClosed fun delete( - params: AssistantDeleteParams + assistantId: String, + params: AssistantDeleteParams = AssistantDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> = - delete(params, RequestOptions.none()) + delete(params.toBuilder().assistantId(assistantId).build(), requestOptions) + + /** @see [delete] */ + @MustBeClosed + fun delete( + assistantId: String, + params: AssistantDeleteParams = AssistantDeleteParams.none(), + ): CompletableFuture> = + delete(assistantId, params, RequestOptions.none()) /** @see [delete] */ @MustBeClosed @@ -176,5 +323,20 @@ interface AssistantServiceAsync { params: AssistantDeleteParams, requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: AssistantDeleteParams + ): CompletableFuture> = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + assistantId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + delete(assistantId, AssistantDeleteParams.none(), requestOptions) } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/beta/AssistantServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/beta/AssistantServiceAsyncImpl.kt index 7eb20393..d7d746f2 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/beta/AssistantServiceAsyncImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/beta/AssistantServiceAsyncImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.async.beta import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -26,6 +27,7 @@ import com.openai.models.beta.assistants.AssistantListParams import com.openai.models.beta.assistants.AssistantRetrieveParams import com.openai.models.beta.assistants.AssistantUpdateParams import java.util.concurrent.CompletableFuture +import kotlin.jvm.optionals.getOrNull class AssistantServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : AssistantServiceAsync { @@ -119,6 +121,9 @@ class AssistantServiceAsyncImpl internal constructor(private val clientOptions: params: AssistantRetrieveParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("assistantId", params.assistantId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -149,6 +154,9 @@ class AssistantServiceAsyncImpl internal constructor(private val clientOptions: params: AssistantUpdateParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("assistantId", params.assistantId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -207,6 +215,7 @@ class AssistantServiceAsyncImpl internal constructor(private val clientOptions: .let { AssistantListPageAsync.builder() .service(AssistantServiceAsyncImpl(clientOptions)) + .streamHandlerExecutor(clientOptions.streamHandlerExecutor) .params(params) .response(it) .build() @@ -222,6 +231,9 @@ class AssistantServiceAsyncImpl internal constructor(private val clientOptions: params: AssistantDeleteParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("assistantId", params.assistantId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.DELETE) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/beta/ThreadServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/beta/ThreadServiceAsync.kt index 76a89f63..5eaf8642 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/beta/ThreadServiceAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/beta/ThreadServiceAsync.kt @@ -49,8 +49,22 @@ interface ThreadServiceAsync { create(ThreadCreateParams.none(), requestOptions) /** Retrieves a thread. */ - fun retrieve(params: ThreadRetrieveParams): CompletableFuture = - retrieve(params, RequestOptions.none()) + fun retrieve(threadId: String): CompletableFuture = + retrieve(threadId, ThreadRetrieveParams.none()) + + /** @see [retrieve] */ + fun retrieve( + threadId: String, + params: ThreadRetrieveParams = ThreadRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + retrieve(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [retrieve] */ + fun retrieve( + threadId: String, + params: ThreadRetrieveParams = ThreadRetrieveParams.none(), + ): CompletableFuture = retrieve(threadId, params, RequestOptions.none()) /** @see [retrieve] */ fun retrieve( @@ -58,9 +72,31 @@ interface ThreadServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [retrieve] */ + fun retrieve(params: ThreadRetrieveParams): CompletableFuture = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve(threadId: String, requestOptions: RequestOptions): CompletableFuture = + retrieve(threadId, ThreadRetrieveParams.none(), requestOptions) + /** Modifies a thread. */ - fun update(params: ThreadUpdateParams): CompletableFuture = - update(params, RequestOptions.none()) + fun update(threadId: String): CompletableFuture = + update(threadId, ThreadUpdateParams.none()) + + /** @see [update] */ + fun update( + threadId: String, + params: ThreadUpdateParams = ThreadUpdateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + update(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [update] */ + fun update( + threadId: String, + params: ThreadUpdateParams = ThreadUpdateParams.none(), + ): CompletableFuture = update(threadId, params, RequestOptions.none()) /** @see [update] */ fun update( @@ -68,9 +104,31 @@ interface ThreadServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [update] */ + fun update(params: ThreadUpdateParams): CompletableFuture = + update(params, RequestOptions.none()) + + /** @see [update] */ + fun update(threadId: String, requestOptions: RequestOptions): CompletableFuture = + update(threadId, ThreadUpdateParams.none(), requestOptions) + /** Delete a thread. */ - fun delete(params: ThreadDeleteParams): CompletableFuture = - delete(params, RequestOptions.none()) + fun delete(threadId: String): CompletableFuture = + delete(threadId, ThreadDeleteParams.none()) + + /** @see [delete] */ + fun delete( + threadId: String, + params: ThreadDeleteParams = ThreadDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + delete(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [delete] */ + fun delete( + threadId: String, + params: ThreadDeleteParams = ThreadDeleteParams.none(), + ): CompletableFuture = delete(threadId, params, RequestOptions.none()) /** @see [delete] */ fun delete( @@ -78,6 +136,14 @@ interface ThreadServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [delete] */ + fun delete(params: ThreadDeleteParams): CompletableFuture = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + fun delete(threadId: String, requestOptions: RequestOptions): CompletableFuture = + delete(threadId, ThreadDeleteParams.none(), requestOptions) + /** Create a thread and run it in one request. */ fun createAndRun(params: ThreadCreateAndRunParams): CompletableFuture = createAndRun(params, RequestOptions.none()) @@ -139,8 +205,25 @@ interface ThreadServiceAsync { * [ThreadServiceAsync.retrieve]. */ @MustBeClosed - fun retrieve(params: ThreadRetrieveParams): CompletableFuture> = - retrieve(params, RequestOptions.none()) + fun retrieve(threadId: String): CompletableFuture> = + retrieve(threadId, ThreadRetrieveParams.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + threadId: String, + params: ThreadRetrieveParams = ThreadRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + retrieve(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + threadId: String, + params: ThreadRetrieveParams = ThreadRetrieveParams.none(), + ): CompletableFuture> = + retrieve(threadId, params, RequestOptions.none()) /** @see [retrieve] */ @MustBeClosed @@ -149,13 +232,43 @@ interface ThreadServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** @see [retrieve] */ + @MustBeClosed + fun retrieve(params: ThreadRetrieveParams): CompletableFuture> = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + threadId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + retrieve(threadId, ThreadRetrieveParams.none(), requestOptions) + /** * Returns a raw HTTP response for `post /threads/{thread_id}`, but is otherwise the same as * [ThreadServiceAsync.update]. */ @MustBeClosed - fun update(params: ThreadUpdateParams): CompletableFuture> = - update(params, RequestOptions.none()) + fun update(threadId: String): CompletableFuture> = + update(threadId, ThreadUpdateParams.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + threadId: String, + params: ThreadUpdateParams = ThreadUpdateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + update(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [update] */ + @MustBeClosed + fun update( + threadId: String, + params: ThreadUpdateParams = ThreadUpdateParams.none(), + ): CompletableFuture> = + update(threadId, params, RequestOptions.none()) /** @see [update] */ @MustBeClosed @@ -164,13 +277,43 @@ interface ThreadServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** @see [update] */ + @MustBeClosed + fun update(params: ThreadUpdateParams): CompletableFuture> = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + threadId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + update(threadId, ThreadUpdateParams.none(), requestOptions) + /** * Returns a raw HTTP response for `delete /threads/{thread_id}`, but is otherwise the same * as [ThreadServiceAsync.delete]. */ @MustBeClosed - fun delete(params: ThreadDeleteParams): CompletableFuture> = - delete(params, RequestOptions.none()) + fun delete(threadId: String): CompletableFuture> = + delete(threadId, ThreadDeleteParams.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + threadId: String, + params: ThreadDeleteParams = ThreadDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + delete(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [delete] */ + @MustBeClosed + fun delete( + threadId: String, + params: ThreadDeleteParams = ThreadDeleteParams.none(), + ): CompletableFuture> = + delete(threadId, params, RequestOptions.none()) /** @see [delete] */ @MustBeClosed @@ -179,6 +322,19 @@ interface ThreadServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** @see [delete] */ + @MustBeClosed + fun delete(params: ThreadDeleteParams): CompletableFuture> = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + threadId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + delete(threadId, ThreadDeleteParams.none(), requestOptions) + /** * Returns a raw HTTP response for `post /threads/runs`, but is otherwise the same as * [ThreadServiceAsync.createAndRun]. diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/beta/ThreadServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/beta/ThreadServiceAsyncImpl.kt index c8334900..a0193523 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/beta/ThreadServiceAsyncImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/beta/ThreadServiceAsyncImpl.kt @@ -5,6 +5,7 @@ package com.openai.services.async.beta import com.openai.core.ClientOptions import com.openai.core.JsonValue import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.mapJson @@ -37,6 +38,7 @@ import com.openai.services.async.beta.threads.MessageServiceAsyncImpl import com.openai.services.async.beta.threads.RunServiceAsync import com.openai.services.async.beta.threads.RunServiceAsyncImpl import java.util.concurrent.CompletableFuture +import kotlin.jvm.optionals.getOrNull class ThreadServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : ThreadServiceAsync { @@ -160,6 +162,9 @@ class ThreadServiceAsyncImpl internal constructor(private val clientOptions: Cli params: ThreadRetrieveParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("threadId", params.threadId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -190,6 +195,9 @@ class ThreadServiceAsyncImpl internal constructor(private val clientOptions: Cli params: ThreadUpdateParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("threadId", params.threadId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -221,6 +229,9 @@ class ThreadServiceAsyncImpl internal constructor(private val clientOptions: Cli params: ThreadDeleteParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("threadId", params.threadId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.DELETE) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/beta/threads/MessageServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/beta/threads/MessageServiceAsync.kt index 364851ad..4ec7a151 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/beta/threads/MessageServiceAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/beta/threads/MessageServiceAsync.kt @@ -23,6 +23,18 @@ interface MessageServiceAsync { fun withRawResponse(): WithRawResponse /** Create a message. */ + fun create(threadId: String, params: MessageCreateParams): CompletableFuture = + create(threadId, params, RequestOptions.none()) + + /** @see [create] */ + fun create( + threadId: String, + params: MessageCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + create(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [create] */ fun create(params: MessageCreateParams): CompletableFuture = create(params, RequestOptions.none()) @@ -33,6 +45,18 @@ interface MessageServiceAsync { ): CompletableFuture /** Retrieve a message. */ + fun retrieve(messageId: String, params: MessageRetrieveParams): CompletableFuture = + retrieve(messageId, params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve( + messageId: String, + params: MessageRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + retrieve(params.toBuilder().messageId(messageId).build(), requestOptions) + + /** @see [retrieve] */ fun retrieve(params: MessageRetrieveParams): CompletableFuture = retrieve(params, RequestOptions.none()) @@ -43,6 +67,18 @@ interface MessageServiceAsync { ): CompletableFuture /** Modifies a message. */ + fun update(messageId: String, params: MessageUpdateParams): CompletableFuture = + update(messageId, params, RequestOptions.none()) + + /** @see [update] */ + fun update( + messageId: String, + params: MessageUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + update(params.toBuilder().messageId(messageId).build(), requestOptions) + + /** @see [update] */ fun update(params: MessageUpdateParams): CompletableFuture = update(params, RequestOptions.none()) @@ -53,8 +89,22 @@ interface MessageServiceAsync { ): CompletableFuture /** Returns a list of messages for a given thread. */ - fun list(params: MessageListParams): CompletableFuture = - list(params, RequestOptions.none()) + fun list(threadId: String): CompletableFuture = + list(threadId, MessageListParams.none()) + + /** @see [list] */ + fun list( + threadId: String, + params: MessageListParams = MessageListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + list(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [list] */ + fun list( + threadId: String, + params: MessageListParams = MessageListParams.none(), + ): CompletableFuture = list(threadId, params, RequestOptions.none()) /** @see [list] */ fun list( @@ -62,7 +112,30 @@ interface MessageServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [list] */ + fun list(params: MessageListParams): CompletableFuture = + list(params, RequestOptions.none()) + + /** @see [list] */ + fun list( + threadId: String, + requestOptions: RequestOptions, + ): CompletableFuture = + list(threadId, MessageListParams.none(), requestOptions) + /** Deletes a message. */ + fun delete(messageId: String, params: MessageDeleteParams): CompletableFuture = + delete(messageId, params, RequestOptions.none()) + + /** @see [delete] */ + fun delete( + messageId: String, + params: MessageDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + delete(params.toBuilder().messageId(messageId).build(), requestOptions) + + /** @see [delete] */ fun delete(params: MessageDeleteParams): CompletableFuture = delete(params, RequestOptions.none()) @@ -82,6 +155,23 @@ interface MessageServiceAsync { * the same as [MessageServiceAsync.create]. */ @MustBeClosed + fun create( + threadId: String, + params: MessageCreateParams, + ): CompletableFuture> = + create(threadId, params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + threadId: String, + params: MessageCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + create(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [create] */ + @MustBeClosed fun create(params: MessageCreateParams): CompletableFuture> = create(params, RequestOptions.none()) @@ -97,6 +187,23 @@ interface MessageServiceAsync { * otherwise the same as [MessageServiceAsync.retrieve]. */ @MustBeClosed + fun retrieve( + messageId: String, + params: MessageRetrieveParams, + ): CompletableFuture> = + retrieve(messageId, params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + messageId: String, + params: MessageRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + retrieve(params.toBuilder().messageId(messageId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed fun retrieve(params: MessageRetrieveParams): CompletableFuture> = retrieve(params, RequestOptions.none()) @@ -112,6 +219,23 @@ interface MessageServiceAsync { * otherwise the same as [MessageServiceAsync.update]. */ @MustBeClosed + fun update( + messageId: String, + params: MessageUpdateParams, + ): CompletableFuture> = + update(messageId, params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + messageId: String, + params: MessageUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + update(params.toBuilder().messageId(messageId).build(), requestOptions) + + /** @see [update] */ + @MustBeClosed fun update(params: MessageUpdateParams): CompletableFuture> = update(params, RequestOptions.none()) @@ -127,10 +251,25 @@ interface MessageServiceAsync { * same as [MessageServiceAsync.list]. */ @MustBeClosed + fun list(threadId: String): CompletableFuture> = + list(threadId, MessageListParams.none()) + + /** @see [list] */ + @MustBeClosed fun list( - params: MessageListParams + threadId: String, + params: MessageListParams = MessageListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> = - list(params, RequestOptions.none()) + list(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [list] */ + @MustBeClosed + fun list( + threadId: String, + params: MessageListParams = MessageListParams.none(), + ): CompletableFuture> = + list(threadId, params, RequestOptions.none()) /** @see [list] */ @MustBeClosed @@ -139,11 +278,43 @@ interface MessageServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** @see [list] */ + @MustBeClosed + fun list( + params: MessageListParams + ): CompletableFuture> = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + threadId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + list(threadId, MessageListParams.none(), requestOptions) + /** * Returns a raw HTTP response for `delete /threads/{thread_id}/messages/{message_id}`, but * is otherwise the same as [MessageServiceAsync.delete]. */ @MustBeClosed + fun delete( + messageId: String, + params: MessageDeleteParams, + ): CompletableFuture> = + delete(messageId, params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + messageId: String, + params: MessageDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + delete(params.toBuilder().messageId(messageId).build(), requestOptions) + + /** @see [delete] */ + @MustBeClosed fun delete( params: MessageDeleteParams ): CompletableFuture> = diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/beta/threads/MessageServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/beta/threads/MessageServiceAsyncImpl.kt index 9753c5f6..07aad9be 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/beta/threads/MessageServiceAsyncImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/beta/threads/MessageServiceAsyncImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.async.beta.threads import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -26,6 +27,7 @@ import com.openai.models.beta.threads.messages.MessageListParams import com.openai.models.beta.threads.messages.MessageRetrieveParams import com.openai.models.beta.threads.messages.MessageUpdateParams import java.util.concurrent.CompletableFuture +import kotlin.jvm.optionals.getOrNull class MessageServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : MessageServiceAsync { @@ -88,6 +90,9 @@ class MessageServiceAsyncImpl internal constructor(private val clientOptions: Cl params: MessageCreateParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("threadId", params.threadId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -119,6 +124,9 @@ class MessageServiceAsyncImpl internal constructor(private val clientOptions: Cl params: MessageRetrieveParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("messageId", params.messageId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -154,6 +162,9 @@ class MessageServiceAsyncImpl internal constructor(private val clientOptions: Cl params: MessageUpdateParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("messageId", params.messageId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -191,6 +202,9 @@ class MessageServiceAsyncImpl internal constructor(private val clientOptions: Cl params: MessageListParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("threadId", params.threadId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -213,6 +227,7 @@ class MessageServiceAsyncImpl internal constructor(private val clientOptions: Cl .let { MessageListPageAsync.builder() .service(MessageServiceAsyncImpl(clientOptions)) + .streamHandlerExecutor(clientOptions.streamHandlerExecutor) .params(params) .response(it) .build() @@ -228,6 +243,9 @@ class MessageServiceAsyncImpl internal constructor(private val clientOptions: Cl params: MessageDeleteParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("messageId", params.messageId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.DELETE) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/beta/threads/RunServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/beta/threads/RunServiceAsync.kt index ca8f68ad..660d74de 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/beta/threads/RunServiceAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/beta/threads/RunServiceAsync.kt @@ -29,6 +29,18 @@ interface RunServiceAsync { fun steps(): StepServiceAsync /** Create a run. */ + fun create(threadId: String, params: RunCreateParams): CompletableFuture = + create(threadId, params, RequestOptions.none()) + + /** @see [create] */ + fun create( + threadId: String, + params: RunCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + create(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [create] */ fun create(params: RunCreateParams): CompletableFuture = create(params, RequestOptions.none()) @@ -39,6 +51,21 @@ interface RunServiceAsync { ): CompletableFuture /** Create a run. */ + fun createStreaming( + threadId: String, + params: RunCreateParams, + ): AsyncStreamResponse = + createStreaming(threadId, params, RequestOptions.none()) + + /** @see [createStreaming] */ + fun createStreaming( + threadId: String, + params: RunCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): AsyncStreamResponse = + createStreaming(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [createStreaming] */ fun createStreaming(params: RunCreateParams): AsyncStreamResponse = createStreaming(params, RequestOptions.none()) @@ -49,6 +76,17 @@ interface RunServiceAsync { ): AsyncStreamResponse /** Retrieves a run. */ + fun retrieve(runId: String, params: RunRetrieveParams): CompletableFuture = + retrieve(runId, params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve( + runId: String, + params: RunRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = retrieve(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [retrieve] */ fun retrieve(params: RunRetrieveParams): CompletableFuture = retrieve(params, RequestOptions.none()) @@ -59,6 +97,17 @@ interface RunServiceAsync { ): CompletableFuture /** Modifies a run. */ + fun update(runId: String, params: RunUpdateParams): CompletableFuture = + update(runId, params, RequestOptions.none()) + + /** @see [update] */ + fun update( + runId: String, + params: RunUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = update(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [update] */ fun update(params: RunUpdateParams): CompletableFuture = update(params, RequestOptions.none()) @@ -69,8 +118,22 @@ interface RunServiceAsync { ): CompletableFuture /** Returns a list of runs belonging to a thread. */ - fun list(params: RunListParams): CompletableFuture = - list(params, RequestOptions.none()) + fun list(threadId: String): CompletableFuture = + list(threadId, RunListParams.none()) + + /** @see [list] */ + fun list( + threadId: String, + params: RunListParams = RunListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + list(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [list] */ + fun list( + threadId: String, + params: RunListParams = RunListParams.none(), + ): CompletableFuture = list(threadId, params, RequestOptions.none()) /** @see [list] */ fun list( @@ -78,7 +141,28 @@ interface RunServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [list] */ + fun list(params: RunListParams): CompletableFuture = + list(params, RequestOptions.none()) + + /** @see [list] */ + fun list( + threadId: String, + requestOptions: RequestOptions, + ): CompletableFuture = list(threadId, RunListParams.none(), requestOptions) + /** Cancels a run that is `in_progress`. */ + fun cancel(runId: String, params: RunCancelParams): CompletableFuture = + cancel(runId, params, RequestOptions.none()) + + /** @see [cancel] */ + fun cancel( + runId: String, + params: RunCancelParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = cancel(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [cancel] */ fun cancel(params: RunCancelParams): CompletableFuture = cancel(params, RequestOptions.none()) @@ -93,6 +177,20 @@ interface RunServiceAsync { * `submit_tool_outputs`, this endpoint can be used to submit the outputs from the tool calls * once they're all completed. All outputs must be submitted in a single request. */ + fun submitToolOutputs( + runId: String, + params: RunSubmitToolOutputsParams, + ): CompletableFuture = submitToolOutputs(runId, params, RequestOptions.none()) + + /** @see [submitToolOutputs] */ + fun submitToolOutputs( + runId: String, + params: RunSubmitToolOutputsParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + submitToolOutputs(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [submitToolOutputs] */ fun submitToolOutputs(params: RunSubmitToolOutputsParams): CompletableFuture = submitToolOutputs(params, RequestOptions.none()) @@ -107,6 +205,21 @@ interface RunServiceAsync { * `submit_tool_outputs`, this endpoint can be used to submit the outputs from the tool calls * once they're all completed. All outputs must be submitted in a single request. */ + fun submitToolOutputsStreaming( + runId: String, + params: RunSubmitToolOutputsParams, + ): AsyncStreamResponse = + submitToolOutputsStreaming(runId, params, RequestOptions.none()) + + /** @see [submitToolOutputsStreaming] */ + fun submitToolOutputsStreaming( + runId: String, + params: RunSubmitToolOutputsParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): AsyncStreamResponse = + submitToolOutputsStreaming(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [submitToolOutputsStreaming] */ fun submitToolOutputsStreaming( params: RunSubmitToolOutputsParams ): AsyncStreamResponse = @@ -128,6 +241,22 @@ interface RunServiceAsync { * same as [RunServiceAsync.create]. */ @MustBeClosed + fun create( + threadId: String, + params: RunCreateParams, + ): CompletableFuture> = create(threadId, params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + threadId: String, + params: RunCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + create(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [create] */ + @MustBeClosed fun create(params: RunCreateParams): CompletableFuture> = create(params, RequestOptions.none()) @@ -143,6 +272,23 @@ interface RunServiceAsync { * same as [RunServiceAsync.createStreaming]. */ @MustBeClosed + fun createStreaming( + threadId: String, + params: RunCreateParams, + ): CompletableFuture>> = + createStreaming(threadId, params, RequestOptions.none()) + + /** @see [createStreaming] */ + @MustBeClosed + fun createStreaming( + threadId: String, + params: RunCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture>> = + createStreaming(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [createStreaming] */ + @MustBeClosed fun createStreaming( params: RunCreateParams ): CompletableFuture>> = @@ -160,6 +306,22 @@ interface RunServiceAsync { * otherwise the same as [RunServiceAsync.retrieve]. */ @MustBeClosed + fun retrieve( + runId: String, + params: RunRetrieveParams, + ): CompletableFuture> = retrieve(runId, params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + runId: String, + params: RunRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + retrieve(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed fun retrieve(params: RunRetrieveParams): CompletableFuture> = retrieve(params, RequestOptions.none()) @@ -175,6 +337,22 @@ interface RunServiceAsync { * otherwise the same as [RunServiceAsync.update]. */ @MustBeClosed + fun update( + runId: String, + params: RunUpdateParams, + ): CompletableFuture> = update(runId, params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + runId: String, + params: RunUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + update(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [update] */ + @MustBeClosed fun update(params: RunUpdateParams): CompletableFuture> = update(params, RequestOptions.none()) @@ -190,8 +368,25 @@ interface RunServiceAsync { * same as [RunServiceAsync.list]. */ @MustBeClosed - fun list(params: RunListParams): CompletableFuture> = - list(params, RequestOptions.none()) + fun list(threadId: String): CompletableFuture> = + list(threadId, RunListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + threadId: String, + params: RunListParams = RunListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + list(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [list] */ + @MustBeClosed + fun list( + threadId: String, + params: RunListParams = RunListParams.none(), + ): CompletableFuture> = + list(threadId, params, RequestOptions.none()) /** @see [list] */ @MustBeClosed @@ -200,11 +395,40 @@ interface RunServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** @see [list] */ + @MustBeClosed + fun list(params: RunListParams): CompletableFuture> = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + threadId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + list(threadId, RunListParams.none(), requestOptions) + /** * Returns a raw HTTP response for `post /threads/{thread_id}/runs/{run_id}/cancel`, but is * otherwise the same as [RunServiceAsync.cancel]. */ @MustBeClosed + fun cancel( + runId: String, + params: RunCancelParams, + ): CompletableFuture> = cancel(runId, params, RequestOptions.none()) + + /** @see [cancel] */ + @MustBeClosed + fun cancel( + runId: String, + params: RunCancelParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + cancel(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [cancel] */ + @MustBeClosed fun cancel(params: RunCancelParams): CompletableFuture> = cancel(params, RequestOptions.none()) @@ -221,6 +445,23 @@ interface RunServiceAsync { * [RunServiceAsync.submitToolOutputs]. */ @MustBeClosed + fun submitToolOutputs( + runId: String, + params: RunSubmitToolOutputsParams, + ): CompletableFuture> = + submitToolOutputs(runId, params, RequestOptions.none()) + + /** @see [submitToolOutputs] */ + @MustBeClosed + fun submitToolOutputs( + runId: String, + params: RunSubmitToolOutputsParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + submitToolOutputs(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [submitToolOutputs] */ + @MustBeClosed fun submitToolOutputs( params: RunSubmitToolOutputsParams ): CompletableFuture> = @@ -239,6 +480,23 @@ interface RunServiceAsync { * [RunServiceAsync.submitToolOutputsStreaming]. */ @MustBeClosed + fun submitToolOutputsStreaming( + runId: String, + params: RunSubmitToolOutputsParams, + ): CompletableFuture>> = + submitToolOutputsStreaming(runId, params, RequestOptions.none()) + + /** @see [submitToolOutputsStreaming] */ + @MustBeClosed + fun submitToolOutputsStreaming( + runId: String, + params: RunSubmitToolOutputsParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture>> = + submitToolOutputsStreaming(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [submitToolOutputsStreaming] */ + @MustBeClosed fun submitToolOutputsStreaming( params: RunSubmitToolOutputsParams ): CompletableFuture>> = diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/beta/threads/RunServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/beta/threads/RunServiceAsyncImpl.kt index 9a15dc34..34ff4855 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/beta/threads/RunServiceAsyncImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/beta/threads/RunServiceAsyncImpl.kt @@ -5,6 +5,7 @@ package com.openai.services.async.beta.threads import com.openai.core.ClientOptions import com.openai.core.JsonValue import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.mapJson @@ -36,6 +37,7 @@ import com.openai.models.beta.threads.runs.RunUpdateParams import com.openai.services.async.beta.threads.runs.StepServiceAsync import com.openai.services.async.beta.threads.runs.StepServiceAsyncImpl import java.util.concurrent.CompletableFuture +import kotlin.jvm.optionals.getOrNull class RunServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : RunServiceAsync { @@ -135,6 +137,9 @@ class RunServiceAsyncImpl internal constructor(private val clientOptions: Client params: RunCreateParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("threadId", params.threadId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -172,6 +177,9 @@ class RunServiceAsyncImpl internal constructor(private val clientOptions: Client params: RunCreateParams, requestOptions: RequestOptions, ): CompletableFuture>> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("threadId", params.threadId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -218,6 +226,9 @@ class RunServiceAsyncImpl internal constructor(private val clientOptions: Client params: RunRetrieveParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("runId", params.runId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -248,6 +259,9 @@ class RunServiceAsyncImpl internal constructor(private val clientOptions: Client params: RunUpdateParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("runId", params.runId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -280,6 +294,9 @@ class RunServiceAsyncImpl internal constructor(private val clientOptions: Client params: RunListParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("threadId", params.threadId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -302,6 +319,7 @@ class RunServiceAsyncImpl internal constructor(private val clientOptions: Client .let { RunListPageAsync.builder() .service(RunServiceAsyncImpl(clientOptions)) + .streamHandlerExecutor(clientOptions.streamHandlerExecutor) .params(params) .response(it) .build() @@ -317,6 +335,9 @@ class RunServiceAsyncImpl internal constructor(private val clientOptions: Client params: RunCancelParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("runId", params.runId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -354,6 +375,9 @@ class RunServiceAsyncImpl internal constructor(private val clientOptions: Client params: RunSubmitToolOutputsParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("runId", params.runId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -394,6 +418,9 @@ class RunServiceAsyncImpl internal constructor(private val clientOptions: Client params: RunSubmitToolOutputsParams, requestOptions: RequestOptions, ): CompletableFuture>> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("runId", params.runId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/beta/threads/runs/StepServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/beta/threads/runs/StepServiceAsync.kt index 3718a766..6f92544a 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/beta/threads/runs/StepServiceAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/beta/threads/runs/StepServiceAsync.kt @@ -19,6 +19,18 @@ interface StepServiceAsync { fun withRawResponse(): WithRawResponse /** Retrieves a run step. */ + fun retrieve(stepId: String, params: StepRetrieveParams): CompletableFuture = + retrieve(stepId, params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve( + stepId: String, + params: StepRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + retrieve(params.toBuilder().stepId(stepId).build(), requestOptions) + + /** @see [retrieve] */ fun retrieve(params: StepRetrieveParams): CompletableFuture = retrieve(params, RequestOptions.none()) @@ -29,6 +41,18 @@ interface StepServiceAsync { ): CompletableFuture /** Returns a list of run steps belonging to a run. */ + fun list(runId: String, params: StepListParams): CompletableFuture = + list(runId, params, RequestOptions.none()) + + /** @see [list] */ + fun list( + runId: String, + params: StepListParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + list(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [list] */ fun list(params: StepListParams): CompletableFuture = list(params, RequestOptions.none()) @@ -46,6 +70,23 @@ interface StepServiceAsync { * but is otherwise the same as [StepServiceAsync.retrieve]. */ @MustBeClosed + fun retrieve( + stepId: String, + params: StepRetrieveParams, + ): CompletableFuture> = + retrieve(stepId, params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + stepId: String, + params: StepRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + retrieve(params.toBuilder().stepId(stepId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed fun retrieve(params: StepRetrieveParams): CompletableFuture> = retrieve(params, RequestOptions.none()) @@ -61,6 +102,23 @@ interface StepServiceAsync { * otherwise the same as [StepServiceAsync.list]. */ @MustBeClosed + fun list( + runId: String, + params: StepListParams, + ): CompletableFuture> = + list(runId, params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + runId: String, + params: StepListParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + list(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [list] */ + @MustBeClosed fun list(params: StepListParams): CompletableFuture> = list(params, RequestOptions.none()) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/beta/threads/runs/StepServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/beta/threads/runs/StepServiceAsyncImpl.kt index 9f3f8350..49b9797b 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/beta/threads/runs/StepServiceAsyncImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/beta/threads/runs/StepServiceAsyncImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.async.beta.threads.runs import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -21,6 +22,7 @@ import com.openai.models.beta.threads.runs.steps.StepListPageResponse import com.openai.models.beta.threads.runs.steps.StepListParams import com.openai.models.beta.threads.runs.steps.StepRetrieveParams import java.util.concurrent.CompletableFuture +import kotlin.jvm.optionals.getOrNull class StepServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : StepServiceAsync { @@ -62,6 +64,9 @@ class StepServiceAsyncImpl internal constructor(private val clientOptions: Clien params: StepRetrieveParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("stepId", params.stepId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -100,6 +105,9 @@ class StepServiceAsyncImpl internal constructor(private val clientOptions: Clien params: StepListParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("runId", params.runId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -128,6 +136,7 @@ class StepServiceAsyncImpl internal constructor(private val clientOptions: Clien .let { StepListPageAsync.builder() .service(StepServiceAsyncImpl(clientOptions)) + .streamHandlerExecutor(clientOptions.streamHandlerExecutor) .params(params) .response(it) .build() diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/chat/ChatCompletionServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/chat/ChatCompletionServiceAsync.kt index 50e7adff..2890cb31 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/chat/ChatCompletionServiceAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/chat/ChatCompletionServiceAsync.kt @@ -87,8 +87,22 @@ interface ChatCompletionServiceAsync { * Get a stored chat completion. Only Chat Completions that have been created with the `store` * parameter set to `true` will be returned. */ - fun retrieve(params: ChatCompletionRetrieveParams): CompletableFuture = - retrieve(params, RequestOptions.none()) + fun retrieve(completionId: String): CompletableFuture = + retrieve(completionId, ChatCompletionRetrieveParams.none()) + + /** @see [retrieve] */ + fun retrieve( + completionId: String, + params: ChatCompletionRetrieveParams = ChatCompletionRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + retrieve(params.toBuilder().completionId(completionId).build(), requestOptions) + + /** @see [retrieve] */ + fun retrieve( + completionId: String, + params: ChatCompletionRetrieveParams = ChatCompletionRetrieveParams.none(), + ): CompletableFuture = retrieve(completionId, params, RequestOptions.none()) /** @see [retrieve] */ fun retrieve( @@ -96,11 +110,36 @@ interface ChatCompletionServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [retrieve] */ + fun retrieve(params: ChatCompletionRetrieveParams): CompletableFuture = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve( + completionId: String, + requestOptions: RequestOptions, + ): CompletableFuture = + retrieve(completionId, ChatCompletionRetrieveParams.none(), requestOptions) + /** * Modify a stored chat completion. Only Chat Completions that have been created with the * `store` parameter set to `true` can be modified. Currently, the only supported modification * is to update the `metadata` field. */ + fun update( + completionId: String, + params: ChatCompletionUpdateParams, + ): CompletableFuture = update(completionId, params, RequestOptions.none()) + + /** @see [update] */ + fun update( + completionId: String, + params: ChatCompletionUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + update(params.toBuilder().completionId(completionId).build(), requestOptions) + + /** @see [update] */ fun update(params: ChatCompletionUpdateParams): CompletableFuture = update(params, RequestOptions.none()) @@ -136,8 +175,23 @@ interface ChatCompletionServiceAsync { * Delete a stored chat completion. Only Chat Completions that have been created with the * `store` parameter set to `true` can be deleted. */ - fun delete(params: ChatCompletionDeleteParams): CompletableFuture = - delete(params, RequestOptions.none()) + fun delete(completionId: String): CompletableFuture = + delete(completionId, ChatCompletionDeleteParams.none()) + + /** @see [delete] */ + fun delete( + completionId: String, + params: ChatCompletionDeleteParams = ChatCompletionDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + delete(params.toBuilder().completionId(completionId).build(), requestOptions) + + /** @see [delete] */ + fun delete( + completionId: String, + params: ChatCompletionDeleteParams = ChatCompletionDeleteParams.none(), + ): CompletableFuture = + delete(completionId, params, RequestOptions.none()) /** @see [delete] */ fun delete( @@ -145,6 +199,17 @@ interface ChatCompletionServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [delete] */ + fun delete(params: ChatCompletionDeleteParams): CompletableFuture = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + fun delete( + completionId: String, + requestOptions: RequestOptions, + ): CompletableFuture = + delete(completionId, ChatCompletionDeleteParams.none(), requestOptions) + /** * A view of [ChatCompletionServiceAsync] that provides access to raw HTTP responses for each * method. @@ -192,10 +257,25 @@ interface ChatCompletionServiceAsync { * the same as [ChatCompletionServiceAsync.retrieve]. */ @MustBeClosed + fun retrieve(completionId: String): CompletableFuture> = + retrieve(completionId, ChatCompletionRetrieveParams.none()) + + /** @see [retrieve] */ + @MustBeClosed fun retrieve( - params: ChatCompletionRetrieveParams + completionId: String, + params: ChatCompletionRetrieveParams = ChatCompletionRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> = - retrieve(params, RequestOptions.none()) + retrieve(params.toBuilder().completionId(completionId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + completionId: String, + params: ChatCompletionRetrieveParams = ChatCompletionRetrieveParams.none(), + ): CompletableFuture> = + retrieve(completionId, params, RequestOptions.none()) /** @see [retrieve] */ @MustBeClosed @@ -204,11 +284,43 @@ interface ChatCompletionServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: ChatCompletionRetrieveParams + ): CompletableFuture> = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + completionId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + retrieve(completionId, ChatCompletionRetrieveParams.none(), requestOptions) + /** * Returns a raw HTTP response for `post /chat/completions/{completion_id}`, but is * otherwise the same as [ChatCompletionServiceAsync.update]. */ @MustBeClosed + fun update( + completionId: String, + params: ChatCompletionUpdateParams, + ): CompletableFuture> = + update(completionId, params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + completionId: String, + params: ChatCompletionUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + update(params.toBuilder().completionId(completionId).build(), requestOptions) + + /** @see [update] */ + @MustBeClosed fun update( params: ChatCompletionUpdateParams ): CompletableFuture> = @@ -256,9 +368,26 @@ interface ChatCompletionServiceAsync { */ @MustBeClosed fun delete( - params: ChatCompletionDeleteParams + completionId: String ): CompletableFuture> = - delete(params, RequestOptions.none()) + delete(completionId, ChatCompletionDeleteParams.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + completionId: String, + params: ChatCompletionDeleteParams = ChatCompletionDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + delete(params.toBuilder().completionId(completionId).build(), requestOptions) + + /** @see [delete] */ + @MustBeClosed + fun delete( + completionId: String, + params: ChatCompletionDeleteParams = ChatCompletionDeleteParams.none(), + ): CompletableFuture> = + delete(completionId, params, RequestOptions.none()) /** @see [delete] */ @MustBeClosed @@ -266,5 +395,20 @@ interface ChatCompletionServiceAsync { params: ChatCompletionDeleteParams, requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: ChatCompletionDeleteParams + ): CompletableFuture> = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + completionId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + delete(completionId, ChatCompletionDeleteParams.none(), requestOptions) } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/chat/ChatCompletionServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/chat/ChatCompletionServiceAsyncImpl.kt index 783a608d..260a4619 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/chat/ChatCompletionServiceAsyncImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/chat/ChatCompletionServiceAsyncImpl.kt @@ -5,6 +5,7 @@ package com.openai.services.async.chat import com.openai.core.ClientOptions import com.openai.core.JsonValue import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.mapJson @@ -186,6 +187,9 @@ internal constructor(private val clientOptions: ClientOptions) : ChatCompletionS params: ChatCompletionRetrieveParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("completionId", params.completionId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -215,6 +219,9 @@ internal constructor(private val clientOptions: ClientOptions) : ChatCompletionS params: ChatCompletionUpdateParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("completionId", params.completionId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -271,6 +278,7 @@ internal constructor(private val clientOptions: ClientOptions) : ChatCompletionS .let { ChatCompletionListPageAsync.builder() .service(ChatCompletionServiceAsyncImpl(clientOptions)) + .streamHandlerExecutor(clientOptions.streamHandlerExecutor) .params(params) .response(it) .build() @@ -287,6 +295,9 @@ internal constructor(private val clientOptions: ClientOptions) : ChatCompletionS params: ChatCompletionDeleteParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("completionId", params.completionId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.DELETE) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/chat/completions/MessageServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/chat/completions/MessageServiceAsync.kt index 3c5d17d3..6edcc5a0 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/chat/completions/MessageServiceAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/chat/completions/MessageServiceAsync.kt @@ -20,8 +20,22 @@ interface MessageServiceAsync { * Get the messages in a stored chat completion. Only Chat Completions that have been created * with the `store` parameter set to `true` will be returned. */ - fun list(params: MessageListParams): CompletableFuture = - list(params, RequestOptions.none()) + fun list(completionId: String): CompletableFuture = + list(completionId, MessageListParams.none()) + + /** @see [list] */ + fun list( + completionId: String, + params: MessageListParams = MessageListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + list(params.toBuilder().completionId(completionId).build(), requestOptions) + + /** @see [list] */ + fun list( + completionId: String, + params: MessageListParams = MessageListParams.none(), + ): CompletableFuture = list(completionId, params, RequestOptions.none()) /** @see [list] */ fun list( @@ -29,6 +43,17 @@ interface MessageServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [list] */ + fun list(params: MessageListParams): CompletableFuture = + list(params, RequestOptions.none()) + + /** @see [list] */ + fun list( + completionId: String, + requestOptions: RequestOptions, + ): CompletableFuture = + list(completionId, MessageListParams.none(), requestOptions) + /** * A view of [MessageServiceAsync] that provides access to raw HTTP responses for each method. */ @@ -39,10 +64,25 @@ interface MessageServiceAsync { * otherwise the same as [MessageServiceAsync.list]. */ @MustBeClosed + fun list(completionId: String): CompletableFuture> = + list(completionId, MessageListParams.none()) + + /** @see [list] */ + @MustBeClosed fun list( - params: MessageListParams + completionId: String, + params: MessageListParams = MessageListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> = - list(params, RequestOptions.none()) + list(params.toBuilder().completionId(completionId).build(), requestOptions) + + /** @see [list] */ + @MustBeClosed + fun list( + completionId: String, + params: MessageListParams = MessageListParams.none(), + ): CompletableFuture> = + list(completionId, params, RequestOptions.none()) /** @see [list] */ @MustBeClosed @@ -50,5 +90,20 @@ interface MessageServiceAsync { params: MessageListParams, requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + + /** @see [list] */ + @MustBeClosed + fun list( + params: MessageListParams + ): CompletableFuture> = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + completionId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + list(completionId, MessageListParams.none(), requestOptions) } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/chat/completions/MessageServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/chat/completions/MessageServiceAsyncImpl.kt index c66410b5..271a18a6 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/chat/completions/MessageServiceAsyncImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/chat/completions/MessageServiceAsyncImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.async.chat.completions import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -18,6 +19,7 @@ import com.openai.models.chat.completions.messages.MessageListPageAsync import com.openai.models.chat.completions.messages.MessageListPageResponse import com.openai.models.chat.completions.messages.MessageListParams import java.util.concurrent.CompletableFuture +import kotlin.jvm.optionals.getOrNull class MessageServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : MessageServiceAsync { @@ -48,6 +50,9 @@ class MessageServiceAsyncImpl internal constructor(private val clientOptions: Cl params: MessageListParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("completionId", params.completionId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -69,6 +74,7 @@ class MessageServiceAsyncImpl internal constructor(private val clientOptions: Cl .let { MessageListPageAsync.builder() .service(MessageServiceAsyncImpl(clientOptions)) + .streamHandlerExecutor(clientOptions.streamHandlerExecutor) .params(params) .response(it) .build() diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/evals/RunServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/evals/RunServiceAsync.kt index 801e00e4..630a6e69 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/evals/RunServiceAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/evals/RunServiceAsync.kt @@ -28,6 +28,18 @@ interface RunServiceAsync { fun outputItems(): OutputItemServiceAsync /** Create a new evaluation run. This is the endpoint that will kick off grading. */ + fun create(evalId: String, params: RunCreateParams): CompletableFuture = + create(evalId, params, RequestOptions.none()) + + /** @see [create] */ + fun create( + evalId: String, + params: RunCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + create(params.toBuilder().evalId(evalId).build(), requestOptions) + + /** @see [create] */ fun create(params: RunCreateParams): CompletableFuture = create(params, RequestOptions.none()) @@ -38,6 +50,18 @@ interface RunServiceAsync { ): CompletableFuture /** Get an evaluation run by ID. */ + fun retrieve(runId: String, params: RunRetrieveParams): CompletableFuture = + retrieve(runId, params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve( + runId: String, + params: RunRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + retrieve(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [retrieve] */ fun retrieve(params: RunRetrieveParams): CompletableFuture = retrieve(params, RequestOptions.none()) @@ -48,8 +72,22 @@ interface RunServiceAsync { ): CompletableFuture /** Get a list of runs for an evaluation. */ - fun list(params: RunListParams): CompletableFuture = - list(params, RequestOptions.none()) + fun list(evalId: String): CompletableFuture = + list(evalId, RunListParams.none()) + + /** @see [list] */ + fun list( + evalId: String, + params: RunListParams = RunListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + list(params.toBuilder().evalId(evalId).build(), requestOptions) + + /** @see [list] */ + fun list( + evalId: String, + params: RunListParams = RunListParams.none(), + ): CompletableFuture = list(evalId, params, RequestOptions.none()) /** @see [list] */ fun list( @@ -57,7 +95,27 @@ interface RunServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [list] */ + fun list(params: RunListParams): CompletableFuture = + list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(evalId: String, requestOptions: RequestOptions): CompletableFuture = + list(evalId, RunListParams.none(), requestOptions) + /** Delete an eval run. */ + fun delete(runId: String, params: RunDeleteParams): CompletableFuture = + delete(runId, params, RequestOptions.none()) + + /** @see [delete] */ + fun delete( + runId: String, + params: RunDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + delete(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [delete] */ fun delete(params: RunDeleteParams): CompletableFuture = delete(params, RequestOptions.none()) @@ -68,6 +126,18 @@ interface RunServiceAsync { ): CompletableFuture /** Cancel an ongoing evaluation run. */ + fun cancel(runId: String, params: RunCancelParams): CompletableFuture = + cancel(runId, params, RequestOptions.none()) + + /** @see [cancel] */ + fun cancel( + runId: String, + params: RunCancelParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + cancel(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [cancel] */ fun cancel(params: RunCancelParams): CompletableFuture = cancel(params, RequestOptions.none()) @@ -87,6 +157,23 @@ interface RunServiceAsync { * as [RunServiceAsync.create]. */ @MustBeClosed + fun create( + evalId: String, + params: RunCreateParams, + ): CompletableFuture> = + create(evalId, params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + evalId: String, + params: RunCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + create(params.toBuilder().evalId(evalId).build(), requestOptions) + + /** @see [create] */ + @MustBeClosed fun create(params: RunCreateParams): CompletableFuture> = create(params, RequestOptions.none()) @@ -102,6 +189,23 @@ interface RunServiceAsync { * the same as [RunServiceAsync.retrieve]. */ @MustBeClosed + fun retrieve( + runId: String, + params: RunRetrieveParams, + ): CompletableFuture> = + retrieve(runId, params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + runId: String, + params: RunRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + retrieve(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed fun retrieve( params: RunRetrieveParams ): CompletableFuture> = @@ -119,8 +223,25 @@ interface RunServiceAsync { * [RunServiceAsync.list]. */ @MustBeClosed - fun list(params: RunListParams): CompletableFuture> = - list(params, RequestOptions.none()) + fun list(evalId: String): CompletableFuture> = + list(evalId, RunListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + evalId: String, + params: RunListParams = RunListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + list(params.toBuilder().evalId(evalId).build(), requestOptions) + + /** @see [list] */ + @MustBeClosed + fun list( + evalId: String, + params: RunListParams = RunListParams.none(), + ): CompletableFuture> = + list(evalId, params, RequestOptions.none()) /** @see [list] */ @MustBeClosed @@ -129,11 +250,41 @@ interface RunServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** @see [list] */ + @MustBeClosed + fun list(params: RunListParams): CompletableFuture> = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + evalId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + list(evalId, RunListParams.none(), requestOptions) + /** * Returns a raw HTTP response for `delete /evals/{eval_id}/runs/{run_id}`, but is otherwise * the same as [RunServiceAsync.delete]. */ @MustBeClosed + fun delete( + runId: String, + params: RunDeleteParams, + ): CompletableFuture> = + delete(runId, params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + runId: String, + params: RunDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + delete(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [delete] */ + @MustBeClosed fun delete(params: RunDeleteParams): CompletableFuture> = delete(params, RequestOptions.none()) @@ -149,6 +300,23 @@ interface RunServiceAsync { * the same as [RunServiceAsync.cancel]. */ @MustBeClosed + fun cancel( + runId: String, + params: RunCancelParams, + ): CompletableFuture> = + cancel(runId, params, RequestOptions.none()) + + /** @see [cancel] */ + @MustBeClosed + fun cancel( + runId: String, + params: RunCancelParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + cancel(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [cancel] */ + @MustBeClosed fun cancel(params: RunCancelParams): CompletableFuture> = cancel(params, RequestOptions.none()) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/evals/RunServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/evals/RunServiceAsyncImpl.kt index b39590a1..b5d6eb0e 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/evals/RunServiceAsyncImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/evals/RunServiceAsyncImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.async.evals import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -29,6 +30,7 @@ import com.openai.models.evals.runs.RunRetrieveResponse import com.openai.services.async.evals.runs.OutputItemServiceAsync import com.openai.services.async.evals.runs.OutputItemServiceAsyncImpl import java.util.concurrent.CompletableFuture +import kotlin.jvm.optionals.getOrNull class RunServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : RunServiceAsync { @@ -98,6 +100,9 @@ class RunServiceAsyncImpl internal constructor(private val clientOptions: Client params: RunCreateParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("evalId", params.evalId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -129,6 +134,9 @@ class RunServiceAsyncImpl internal constructor(private val clientOptions: Client params: RunRetrieveParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("runId", params.runId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -159,6 +167,9 @@ class RunServiceAsyncImpl internal constructor(private val clientOptions: Client params: RunListParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("evalId", params.evalId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -180,6 +191,7 @@ class RunServiceAsyncImpl internal constructor(private val clientOptions: Client .let { RunListPageAsync.builder() .service(RunServiceAsyncImpl(clientOptions)) + .streamHandlerExecutor(clientOptions.streamHandlerExecutor) .params(params) .response(it) .build() @@ -195,6 +207,9 @@ class RunServiceAsyncImpl internal constructor(private val clientOptions: Client params: RunDeleteParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("runId", params.runId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.DELETE) @@ -225,6 +240,9 @@ class RunServiceAsyncImpl internal constructor(private val clientOptions: Client params: RunCancelParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("runId", params.runId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/evals/runs/OutputItemServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/evals/runs/OutputItemServiceAsync.kt index 705932c0..6373f511 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/evals/runs/OutputItemServiceAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/evals/runs/OutputItemServiceAsync.kt @@ -19,6 +19,21 @@ interface OutputItemServiceAsync { fun withRawResponse(): WithRawResponse /** Get an evaluation run output item by ID. */ + fun retrieve( + outputItemId: String, + params: OutputItemRetrieveParams, + ): CompletableFuture = + retrieve(outputItemId, params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve( + outputItemId: String, + params: OutputItemRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + retrieve(params.toBuilder().outputItemId(outputItemId).build(), requestOptions) + + /** @see [retrieve] */ fun retrieve(params: OutputItemRetrieveParams): CompletableFuture = retrieve(params, RequestOptions.none()) @@ -29,6 +44,20 @@ interface OutputItemServiceAsync { ): CompletableFuture /** Get a list of output items for an evaluation run. */ + fun list( + runId: String, + params: OutputItemListParams, + ): CompletableFuture = list(runId, params, RequestOptions.none()) + + /** @see [list] */ + fun list( + runId: String, + params: OutputItemListParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + list(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [list] */ fun list(params: OutputItemListParams): CompletableFuture = list(params, RequestOptions.none()) @@ -50,6 +79,23 @@ interface OutputItemServiceAsync { * as [OutputItemServiceAsync.retrieve]. */ @MustBeClosed + fun retrieve( + outputItemId: String, + params: OutputItemRetrieveParams, + ): CompletableFuture> = + retrieve(outputItemId, params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + outputItemId: String, + params: OutputItemRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + retrieve(params.toBuilder().outputItemId(outputItemId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed fun retrieve( params: OutputItemRetrieveParams ): CompletableFuture> = @@ -67,6 +113,23 @@ interface OutputItemServiceAsync { * otherwise the same as [OutputItemServiceAsync.list]. */ @MustBeClosed + fun list( + runId: String, + params: OutputItemListParams, + ): CompletableFuture> = + list(runId, params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + runId: String, + params: OutputItemListParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + list(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [list] */ + @MustBeClosed fun list( params: OutputItemListParams ): CompletableFuture> = diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/evals/runs/OutputItemServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/evals/runs/OutputItemServiceAsyncImpl.kt index 05537bed..ad4cd7fa 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/evals/runs/OutputItemServiceAsyncImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/evals/runs/OutputItemServiceAsyncImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.async.evals.runs import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -20,6 +21,7 @@ import com.openai.models.evals.runs.outputitems.OutputItemListParams import com.openai.models.evals.runs.outputitems.OutputItemRetrieveParams import com.openai.models.evals.runs.outputitems.OutputItemRetrieveResponse import java.util.concurrent.CompletableFuture +import kotlin.jvm.optionals.getOrNull class OutputItemServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : OutputItemServiceAsync { @@ -57,6 +59,9 @@ class OutputItemServiceAsyncImpl internal constructor(private val clientOptions: params: OutputItemRetrieveParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("outputItemId", params.outputItemId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -94,6 +99,9 @@ class OutputItemServiceAsyncImpl internal constructor(private val clientOptions: params: OutputItemListParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("runId", params.runId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -121,6 +129,7 @@ class OutputItemServiceAsyncImpl internal constructor(private val clientOptions: .let { OutputItemListPageAsync.builder() .service(OutputItemServiceAsyncImpl(clientOptions)) + .streamHandlerExecutor(clientOptions.streamHandlerExecutor) .params(params) .response(it) .build() diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/AlphaServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/AlphaServiceAsync.kt new file mode 100644 index 00000000..58bc3d54 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/AlphaServiceAsync.kt @@ -0,0 +1,21 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.services.async.finetuning + +import com.openai.services.async.finetuning.alpha.GraderServiceAsync + +interface AlphaServiceAsync { + + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + + fun graders(): GraderServiceAsync + + /** A view of [AlphaServiceAsync] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + fun graders(): GraderServiceAsync.WithRawResponse + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/AlphaServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/AlphaServiceAsyncImpl.kt new file mode 100644 index 00000000..fff90acb --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/AlphaServiceAsyncImpl.kt @@ -0,0 +1,31 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.services.async.finetuning + +import com.openai.core.ClientOptions +import com.openai.services.async.finetuning.alpha.GraderServiceAsync +import com.openai.services.async.finetuning.alpha.GraderServiceAsyncImpl + +class AlphaServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + AlphaServiceAsync { + + private val withRawResponse: AlphaServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + private val graders: GraderServiceAsync by lazy { GraderServiceAsyncImpl(clientOptions) } + + override fun withRawResponse(): AlphaServiceAsync.WithRawResponse = withRawResponse + + override fun graders(): GraderServiceAsync = graders + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + AlphaServiceAsync.WithRawResponse { + + private val graders: GraderServiceAsync.WithRawResponse by lazy { + GraderServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + override fun graders(): GraderServiceAsync.WithRawResponse = graders + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/JobServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/JobServiceAsync.kt index b19633ee..9ed46708 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/JobServiceAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/JobServiceAsync.kt @@ -12,6 +12,8 @@ import com.openai.models.finetuning.jobs.JobListEventsPageAsync import com.openai.models.finetuning.jobs.JobListEventsParams import com.openai.models.finetuning.jobs.JobListPageAsync import com.openai.models.finetuning.jobs.JobListParams +import com.openai.models.finetuning.jobs.JobPauseParams +import com.openai.models.finetuning.jobs.JobResumeParams import com.openai.models.finetuning.jobs.JobRetrieveParams import com.openai.services.async.finetuning.jobs.CheckpointServiceAsync import java.util.concurrent.CompletableFuture @@ -48,8 +50,22 @@ interface JobServiceAsync { * * [Learn more about fine-tuning](https://platform.openai.com/docs/guides/fine-tuning) */ - fun retrieve(params: JobRetrieveParams): CompletableFuture = - retrieve(params, RequestOptions.none()) + fun retrieve(fineTuningJobId: String): CompletableFuture = + retrieve(fineTuningJobId, JobRetrieveParams.none()) + + /** @see [retrieve] */ + fun retrieve( + fineTuningJobId: String, + params: JobRetrieveParams = JobRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + retrieve(params.toBuilder().fineTuningJobId(fineTuningJobId).build(), requestOptions) + + /** @see [retrieve] */ + fun retrieve( + fineTuningJobId: String, + params: JobRetrieveParams = JobRetrieveParams.none(), + ): CompletableFuture = retrieve(fineTuningJobId, params, RequestOptions.none()) /** @see [retrieve] */ fun retrieve( @@ -57,6 +73,17 @@ interface JobServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [retrieve] */ + fun retrieve(params: JobRetrieveParams): CompletableFuture = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve( + fineTuningJobId: String, + requestOptions: RequestOptions, + ): CompletableFuture = + retrieve(fineTuningJobId, JobRetrieveParams.none(), requestOptions) + /** List your organization's fine-tuning jobs */ fun list(): CompletableFuture = list(JobListParams.none()) @@ -75,8 +102,22 @@ interface JobServiceAsync { list(JobListParams.none(), requestOptions) /** Immediately cancel a fine-tune job. */ - fun cancel(params: JobCancelParams): CompletableFuture = - cancel(params, RequestOptions.none()) + fun cancel(fineTuningJobId: String): CompletableFuture = + cancel(fineTuningJobId, JobCancelParams.none()) + + /** @see [cancel] */ + fun cancel( + fineTuningJobId: String, + params: JobCancelParams = JobCancelParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + cancel(params.toBuilder().fineTuningJobId(fineTuningJobId).build(), requestOptions) + + /** @see [cancel] */ + fun cancel( + fineTuningJobId: String, + params: JobCancelParams = JobCancelParams.none(), + ): CompletableFuture = cancel(fineTuningJobId, params, RequestOptions.none()) /** @see [cancel] */ fun cancel( @@ -84,9 +125,35 @@ interface JobServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [cancel] */ + fun cancel(params: JobCancelParams): CompletableFuture = + cancel(params, RequestOptions.none()) + + /** @see [cancel] */ + fun cancel( + fineTuningJobId: String, + requestOptions: RequestOptions, + ): CompletableFuture = + cancel(fineTuningJobId, JobCancelParams.none(), requestOptions) + /** Get status updates for a fine-tuning job. */ - fun listEvents(params: JobListEventsParams): CompletableFuture = - listEvents(params, RequestOptions.none()) + fun listEvents(fineTuningJobId: String): CompletableFuture = + listEvents(fineTuningJobId, JobListEventsParams.none()) + + /** @see [listEvents] */ + fun listEvents( + fineTuningJobId: String, + params: JobListEventsParams = JobListEventsParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + listEvents(params.toBuilder().fineTuningJobId(fineTuningJobId).build(), requestOptions) + + /** @see [listEvents] */ + fun listEvents( + fineTuningJobId: String, + params: JobListEventsParams = JobListEventsParams.none(), + ): CompletableFuture = + listEvents(fineTuningJobId, params, RequestOptions.none()) /** @see [listEvents] */ fun listEvents( @@ -94,6 +161,87 @@ interface JobServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [listEvents] */ + fun listEvents(params: JobListEventsParams): CompletableFuture = + listEvents(params, RequestOptions.none()) + + /** @see [listEvents] */ + fun listEvents( + fineTuningJobId: String, + requestOptions: RequestOptions, + ): CompletableFuture = + listEvents(fineTuningJobId, JobListEventsParams.none(), requestOptions) + + /** Pause a fine-tune job. */ + fun pause(fineTuningJobId: String): CompletableFuture = + pause(fineTuningJobId, JobPauseParams.none()) + + /** @see [pause] */ + fun pause( + fineTuningJobId: String, + params: JobPauseParams = JobPauseParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + pause(params.toBuilder().fineTuningJobId(fineTuningJobId).build(), requestOptions) + + /** @see [pause] */ + fun pause( + fineTuningJobId: String, + params: JobPauseParams = JobPauseParams.none(), + ): CompletableFuture = pause(fineTuningJobId, params, RequestOptions.none()) + + /** @see [pause] */ + fun pause( + params: JobPauseParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see [pause] */ + fun pause(params: JobPauseParams): CompletableFuture = + pause(params, RequestOptions.none()) + + /** @see [pause] */ + fun pause( + fineTuningJobId: String, + requestOptions: RequestOptions, + ): CompletableFuture = + pause(fineTuningJobId, JobPauseParams.none(), requestOptions) + + /** Resume a fine-tune job. */ + fun resume(fineTuningJobId: String): CompletableFuture = + resume(fineTuningJobId, JobResumeParams.none()) + + /** @see [resume] */ + fun resume( + fineTuningJobId: String, + params: JobResumeParams = JobResumeParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + resume(params.toBuilder().fineTuningJobId(fineTuningJobId).build(), requestOptions) + + /** @see [resume] */ + fun resume( + fineTuningJobId: String, + params: JobResumeParams = JobResumeParams.none(), + ): CompletableFuture = resume(fineTuningJobId, params, RequestOptions.none()) + + /** @see [resume] */ + fun resume( + params: JobResumeParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see [resume] */ + fun resume(params: JobResumeParams): CompletableFuture = + resume(params, RequestOptions.none()) + + /** @see [resume] */ + fun resume( + fineTuningJobId: String, + requestOptions: RequestOptions, + ): CompletableFuture = + resume(fineTuningJobId, JobResumeParams.none(), requestOptions) + /** A view of [JobServiceAsync] that provides access to raw HTTP responses for each method. */ interface WithRawResponse { @@ -119,8 +267,25 @@ interface JobServiceAsync { * otherwise the same as [JobServiceAsync.retrieve]. */ @MustBeClosed - fun retrieve(params: JobRetrieveParams): CompletableFuture> = - retrieve(params, RequestOptions.none()) + fun retrieve(fineTuningJobId: String): CompletableFuture> = + retrieve(fineTuningJobId, JobRetrieveParams.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + fineTuningJobId: String, + params: JobRetrieveParams = JobRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + retrieve(params.toBuilder().fineTuningJobId(fineTuningJobId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + fineTuningJobId: String, + params: JobRetrieveParams = JobRetrieveParams.none(), + ): CompletableFuture> = + retrieve(fineTuningJobId, params, RequestOptions.none()) /** @see [retrieve] */ @MustBeClosed @@ -129,6 +294,19 @@ interface JobServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** @see [retrieve] */ + @MustBeClosed + fun retrieve(params: JobRetrieveParams): CompletableFuture> = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + fineTuningJobId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + retrieve(fineTuningJobId, JobRetrieveParams.none(), requestOptions) + /** * Returns a raw HTTP response for `get /fine_tuning/jobs`, but is otherwise the same as * [JobServiceAsync.list]. @@ -163,8 +341,25 @@ interface JobServiceAsync { * is otherwise the same as [JobServiceAsync.cancel]. */ @MustBeClosed - fun cancel(params: JobCancelParams): CompletableFuture> = - cancel(params, RequestOptions.none()) + fun cancel(fineTuningJobId: String): CompletableFuture> = + cancel(fineTuningJobId, JobCancelParams.none()) + + /** @see [cancel] */ + @MustBeClosed + fun cancel( + fineTuningJobId: String, + params: JobCancelParams = JobCancelParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + cancel(params.toBuilder().fineTuningJobId(fineTuningJobId).build(), requestOptions) + + /** @see [cancel] */ + @MustBeClosed + fun cancel( + fineTuningJobId: String, + params: JobCancelParams = JobCancelParams.none(), + ): CompletableFuture> = + cancel(fineTuningJobId, params, RequestOptions.none()) /** @see [cancel] */ @MustBeClosed @@ -173,15 +368,45 @@ interface JobServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** @see [cancel] */ + @MustBeClosed + fun cancel(params: JobCancelParams): CompletableFuture> = + cancel(params, RequestOptions.none()) + + /** @see [cancel] */ + @MustBeClosed + fun cancel( + fineTuningJobId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + cancel(fineTuningJobId, JobCancelParams.none(), requestOptions) + /** * Returns a raw HTTP response for `get /fine_tuning/jobs/{fine_tuning_job_id}/events`, but * is otherwise the same as [JobServiceAsync.listEvents]. */ @MustBeClosed fun listEvents( - params: JobListEventsParams + fineTuningJobId: String ): CompletableFuture> = - listEvents(params, RequestOptions.none()) + listEvents(fineTuningJobId, JobListEventsParams.none()) + + /** @see [listEvents] */ + @MustBeClosed + fun listEvents( + fineTuningJobId: String, + params: JobListEventsParams = JobListEventsParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + listEvents(params.toBuilder().fineTuningJobId(fineTuningJobId).build(), requestOptions) + + /** @see [listEvents] */ + @MustBeClosed + fun listEvents( + fineTuningJobId: String, + params: JobListEventsParams = JobListEventsParams.none(), + ): CompletableFuture> = + listEvents(fineTuningJobId, params, RequestOptions.none()) /** @see [listEvents] */ @MustBeClosed @@ -189,5 +414,110 @@ interface JobServiceAsync { params: JobListEventsParams, requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + + /** @see [listEvents] */ + @MustBeClosed + fun listEvents( + params: JobListEventsParams + ): CompletableFuture> = + listEvents(params, RequestOptions.none()) + + /** @see [listEvents] */ + @MustBeClosed + fun listEvents( + fineTuningJobId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + listEvents(fineTuningJobId, JobListEventsParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `post /fine_tuning/jobs/{fine_tuning_job_id}/pause`, but + * is otherwise the same as [JobServiceAsync.pause]. + */ + @MustBeClosed + fun pause(fineTuningJobId: String): CompletableFuture> = + pause(fineTuningJobId, JobPauseParams.none()) + + /** @see [pause] */ + @MustBeClosed + fun pause( + fineTuningJobId: String, + params: JobPauseParams = JobPauseParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + pause(params.toBuilder().fineTuningJobId(fineTuningJobId).build(), requestOptions) + + /** @see [pause] */ + @MustBeClosed + fun pause( + fineTuningJobId: String, + params: JobPauseParams = JobPauseParams.none(), + ): CompletableFuture> = + pause(fineTuningJobId, params, RequestOptions.none()) + + /** @see [pause] */ + @MustBeClosed + fun pause( + params: JobPauseParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see [pause] */ + @MustBeClosed + fun pause(params: JobPauseParams): CompletableFuture> = + pause(params, RequestOptions.none()) + + /** @see [pause] */ + @MustBeClosed + fun pause( + fineTuningJobId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + pause(fineTuningJobId, JobPauseParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `post /fine_tuning/jobs/{fine_tuning_job_id}/resume`, but + * is otherwise the same as [JobServiceAsync.resume]. + */ + @MustBeClosed + fun resume(fineTuningJobId: String): CompletableFuture> = + resume(fineTuningJobId, JobResumeParams.none()) + + /** @see [resume] */ + @MustBeClosed + fun resume( + fineTuningJobId: String, + params: JobResumeParams = JobResumeParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + resume(params.toBuilder().fineTuningJobId(fineTuningJobId).build(), requestOptions) + + /** @see [resume] */ + @MustBeClosed + fun resume( + fineTuningJobId: String, + params: JobResumeParams = JobResumeParams.none(), + ): CompletableFuture> = + resume(fineTuningJobId, params, RequestOptions.none()) + + /** @see [resume] */ + @MustBeClosed + fun resume( + params: JobResumeParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see [resume] */ + @MustBeClosed + fun resume(params: JobResumeParams): CompletableFuture> = + resume(params, RequestOptions.none()) + + /** @see [resume] */ + @MustBeClosed + fun resume( + fineTuningJobId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + resume(fineTuningJobId, JobResumeParams.none(), requestOptions) } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/JobServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/JobServiceAsyncImpl.kt index 5ebe2d42..959d5660 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/JobServiceAsyncImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/JobServiceAsyncImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.async.finetuning import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -24,10 +25,13 @@ import com.openai.models.finetuning.jobs.JobListEventsParams import com.openai.models.finetuning.jobs.JobListPageAsync import com.openai.models.finetuning.jobs.JobListPageResponse import com.openai.models.finetuning.jobs.JobListParams +import com.openai.models.finetuning.jobs.JobPauseParams +import com.openai.models.finetuning.jobs.JobResumeParams import com.openai.models.finetuning.jobs.JobRetrieveParams import com.openai.services.async.finetuning.jobs.CheckpointServiceAsync import com.openai.services.async.finetuning.jobs.CheckpointServiceAsyncImpl import java.util.concurrent.CompletableFuture +import kotlin.jvm.optionals.getOrNull class JobServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : JobServiceAsync { @@ -79,6 +83,20 @@ class JobServiceAsyncImpl internal constructor(private val clientOptions: Client // get /fine_tuning/jobs/{fine_tuning_job_id}/events withRawResponse().listEvents(params, requestOptions).thenApply { it.parse() } + override fun pause( + params: JobPauseParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /fine_tuning/jobs/{fine_tuning_job_id}/pause + withRawResponse().pause(params, requestOptions).thenApply { it.parse() } + + override fun resume( + params: JobResumeParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /fine_tuning/jobs/{fine_tuning_job_id}/resume + withRawResponse().resume(params, requestOptions).thenApply { it.parse() } + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : JobServiceAsync.WithRawResponse { @@ -127,6 +145,9 @@ class JobServiceAsyncImpl internal constructor(private val clientOptions: Client params: JobRetrieveParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("fineTuningJobId", params.fineTuningJobId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -178,6 +199,7 @@ class JobServiceAsyncImpl internal constructor(private val clientOptions: Client .let { JobListPageAsync.builder() .service(JobServiceAsyncImpl(clientOptions)) + .streamHandlerExecutor(clientOptions.streamHandlerExecutor) .params(params) .response(it) .build() @@ -193,6 +215,9 @@ class JobServiceAsyncImpl internal constructor(private val clientOptions: Client params: JobCancelParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("fineTuningJobId", params.fineTuningJobId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -224,6 +249,9 @@ class JobServiceAsyncImpl internal constructor(private val clientOptions: Client params: JobListEventsParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("fineTuningJobId", params.fineTuningJobId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -245,6 +273,7 @@ class JobServiceAsyncImpl internal constructor(private val clientOptions: Client .let { JobListEventsPageAsync.builder() .service(JobServiceAsyncImpl(clientOptions)) + .streamHandlerExecutor(clientOptions.streamHandlerExecutor) .params(params) .response(it) .build() @@ -252,5 +281,71 @@ class JobServiceAsyncImpl internal constructor(private val clientOptions: Client } } } + + private val pauseHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun pause( + params: JobPauseParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("fineTuningJobId", params.fineTuningJobId().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("fine_tuning", "jobs", params._pathParam(0), "pause") + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepareAsync(clientOptions, params, deploymentModel = null) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { pauseHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + + private val resumeHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun resume( + params: JobResumeParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("fineTuningJobId", params.fineTuningJobId().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("fine_tuning", "jobs", params._pathParam(0), "resume") + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepareAsync(clientOptions, params, deploymentModel = null) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { resumeHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/MethodServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/MethodServiceAsync.kt new file mode 100644 index 00000000..6c46a35d --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/MethodServiceAsync.kt @@ -0,0 +1,16 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.services.async.finetuning + +interface MethodServiceAsync { + + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + + /** + * A view of [MethodServiceAsync] that provides access to raw HTTP responses for each method. + */ + interface WithRawResponse +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/MethodServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/MethodServiceAsyncImpl.kt new file mode 100644 index 00000000..a2803029 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/MethodServiceAsyncImpl.kt @@ -0,0 +1,18 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.services.async.finetuning + +import com.openai.core.ClientOptions + +class MethodServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + MethodServiceAsync { + + private val withRawResponse: MethodServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): MethodServiceAsync.WithRawResponse = withRawResponse + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + MethodServiceAsync.WithRawResponse +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/alpha/GraderServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/alpha/GraderServiceAsync.kt new file mode 100644 index 00000000..a11d77f1 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/alpha/GraderServiceAsync.kt @@ -0,0 +1,78 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.services.async.finetuning.alpha + +import com.google.errorprone.annotations.MustBeClosed +import com.openai.core.RequestOptions +import com.openai.core.http.HttpResponseFor +import com.openai.models.finetuning.alpha.graders.GraderRunParams +import com.openai.models.finetuning.alpha.graders.GraderRunResponse +import com.openai.models.finetuning.alpha.graders.GraderValidateParams +import com.openai.models.finetuning.alpha.graders.GraderValidateResponse +import java.util.concurrent.CompletableFuture + +interface GraderServiceAsync { + + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + + /** Run a grader. */ + fun run(params: GraderRunParams): CompletableFuture = + run(params, RequestOptions.none()) + + /** @see [run] */ + fun run( + params: GraderRunParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** Validate a grader. */ + fun validate(params: GraderValidateParams): CompletableFuture = + validate(params, RequestOptions.none()) + + /** @see [validate] */ + fun validate( + params: GraderValidateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** + * A view of [GraderServiceAsync] that provides access to raw HTTP responses for each method. + */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /fine_tuning/alpha/graders/run`, but is otherwise + * the same as [GraderServiceAsync.run]. + */ + @MustBeClosed + fun run(params: GraderRunParams): CompletableFuture> = + run(params, RequestOptions.none()) + + /** @see [run] */ + @MustBeClosed + fun run( + params: GraderRunParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `post /fine_tuning/alpha/graders/validate`, but is + * otherwise the same as [GraderServiceAsync.validate]. + */ + @MustBeClosed + fun validate( + params: GraderValidateParams + ): CompletableFuture> = + validate(params, RequestOptions.none()) + + /** @see [validate] */ + @MustBeClosed + fun validate( + params: GraderValidateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/alpha/GraderServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/alpha/GraderServiceAsyncImpl.kt new file mode 100644 index 00000000..9eb20ee4 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/alpha/GraderServiceAsyncImpl.kt @@ -0,0 +1,113 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.services.async.finetuning.alpha + +import com.openai.core.ClientOptions +import com.openai.core.RequestOptions +import com.openai.core.handlers.errorHandler +import com.openai.core.handlers.jsonHandler +import com.openai.core.handlers.withErrorHandler +import com.openai.core.http.HttpMethod +import com.openai.core.http.HttpRequest +import com.openai.core.http.HttpResponse.Handler +import com.openai.core.http.HttpResponseFor +import com.openai.core.http.json +import com.openai.core.http.parseable +import com.openai.core.prepareAsync +import com.openai.models.ErrorObject +import com.openai.models.finetuning.alpha.graders.GraderRunParams +import com.openai.models.finetuning.alpha.graders.GraderRunResponse +import com.openai.models.finetuning.alpha.graders.GraderValidateParams +import com.openai.models.finetuning.alpha.graders.GraderValidateResponse +import java.util.concurrent.CompletableFuture + +class GraderServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + GraderServiceAsync { + + private val withRawResponse: GraderServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): GraderServiceAsync.WithRawResponse = withRawResponse + + override fun run( + params: GraderRunParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /fine_tuning/alpha/graders/run + withRawResponse().run(params, requestOptions).thenApply { it.parse() } + + override fun validate( + params: GraderValidateParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /fine_tuning/alpha/graders/validate + withRawResponse().validate(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + GraderServiceAsync.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val runHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun run( + params: GraderRunParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("fine_tuning", "alpha", "graders", "run") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params, deploymentModel = null) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { runHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + + private val validateHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) + + override fun validate( + params: GraderValidateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("fine_tuning", "alpha", "graders", "validate") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params, deploymentModel = null) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { validateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/checkpoints/PermissionServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/checkpoints/PermissionServiceAsync.kt index 6fa0d154..0d293bcb 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/checkpoints/PermissionServiceAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/checkpoints/PermissionServiceAsync.kt @@ -26,6 +26,24 @@ interface PermissionServiceAsync { * This enables organization owners to share fine-tuned models with other projects in their * organization. */ + fun create( + fineTunedModelCheckpoint: String, + params: PermissionCreateParams, + ): CompletableFuture = + create(fineTunedModelCheckpoint, params, RequestOptions.none()) + + /** @see [create] */ + fun create( + fineTunedModelCheckpoint: String, + params: PermissionCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + create( + params.toBuilder().fineTunedModelCheckpoint(fineTunedModelCheckpoint).build(), + requestOptions, + ) + + /** @see [create] */ fun create(params: PermissionCreateParams): CompletableFuture = create(params, RequestOptions.none()) @@ -41,8 +59,26 @@ interface PermissionServiceAsync { * Organization owners can use this endpoint to view all permissions for a fine-tuned model * checkpoint. */ - fun retrieve(params: PermissionRetrieveParams): CompletableFuture = - retrieve(params, RequestOptions.none()) + fun retrieve(fineTunedModelCheckpoint: String): CompletableFuture = + retrieve(fineTunedModelCheckpoint, PermissionRetrieveParams.none()) + + /** @see [retrieve] */ + fun retrieve( + fineTunedModelCheckpoint: String, + params: PermissionRetrieveParams = PermissionRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + retrieve( + params.toBuilder().fineTunedModelCheckpoint(fineTunedModelCheckpoint).build(), + requestOptions, + ) + + /** @see [retrieve] */ + fun retrieve( + fineTunedModelCheckpoint: String, + params: PermissionRetrieveParams = PermissionRetrieveParams.none(), + ): CompletableFuture = + retrieve(fineTunedModelCheckpoint, params, RequestOptions.none()) /** @see [retrieve] */ fun retrieve( @@ -50,12 +86,38 @@ interface PermissionServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [retrieve] */ + fun retrieve(params: PermissionRetrieveParams): CompletableFuture = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve( + fineTunedModelCheckpoint: String, + requestOptions: RequestOptions, + ): CompletableFuture = + retrieve(fineTunedModelCheckpoint, PermissionRetrieveParams.none(), requestOptions) + /** * **NOTE:** This endpoint requires an [admin API key](../admin-api-keys). * * Organization owners can use this endpoint to delete a permission for a fine-tuned model * checkpoint. */ + fun delete( + permissionId: String, + params: PermissionDeleteParams, + ): CompletableFuture = + delete(permissionId, params, RequestOptions.none()) + + /** @see [delete] */ + fun delete( + permissionId: String, + params: PermissionDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + delete(params.toBuilder().permissionId(permissionId).build(), requestOptions) + + /** @see [delete] */ fun delete(params: PermissionDeleteParams): CompletableFuture = delete(params, RequestOptions.none()) @@ -77,6 +139,26 @@ interface PermissionServiceAsync { * same as [PermissionServiceAsync.create]. */ @MustBeClosed + fun create( + fineTunedModelCheckpoint: String, + params: PermissionCreateParams, + ): CompletableFuture> = + create(fineTunedModelCheckpoint, params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + fineTunedModelCheckpoint: String, + params: PermissionCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + create( + params.toBuilder().fineTunedModelCheckpoint(fineTunedModelCheckpoint).build(), + requestOptions, + ) + + /** @see [create] */ + @MustBeClosed fun create( params: PermissionCreateParams ): CompletableFuture> = @@ -96,9 +178,29 @@ interface PermissionServiceAsync { */ @MustBeClosed fun retrieve( - params: PermissionRetrieveParams + fineTunedModelCheckpoint: String ): CompletableFuture> = - retrieve(params, RequestOptions.none()) + retrieve(fineTunedModelCheckpoint, PermissionRetrieveParams.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + fineTunedModelCheckpoint: String, + params: PermissionRetrieveParams = PermissionRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + retrieve( + params.toBuilder().fineTunedModelCheckpoint(fineTunedModelCheckpoint).build(), + requestOptions, + ) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + fineTunedModelCheckpoint: String, + params: PermissionRetrieveParams = PermissionRetrieveParams.none(), + ): CompletableFuture> = + retrieve(fineTunedModelCheckpoint, params, RequestOptions.none()) /** @see [retrieve] */ @MustBeClosed @@ -107,12 +209,44 @@ interface PermissionServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: PermissionRetrieveParams + ): CompletableFuture> = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + fineTunedModelCheckpoint: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + retrieve(fineTunedModelCheckpoint, PermissionRetrieveParams.none(), requestOptions) + /** * Returns a raw HTTP response for `delete * /fine_tuning/checkpoints/{fine_tuned_model_checkpoint}/permissions/{permission_id}`, but * is otherwise the same as [PermissionServiceAsync.delete]. */ @MustBeClosed + fun delete( + permissionId: String, + params: PermissionDeleteParams, + ): CompletableFuture> = + delete(permissionId, params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + permissionId: String, + params: PermissionDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + delete(params.toBuilder().permissionId(permissionId).build(), requestOptions) + + /** @see [delete] */ + @MustBeClosed fun delete( params: PermissionDeleteParams ): CompletableFuture> = diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/checkpoints/PermissionServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/checkpoints/PermissionServiceAsyncImpl.kt index 9d763dd7..0d3bf5c0 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/checkpoints/PermissionServiceAsyncImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/checkpoints/PermissionServiceAsyncImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.async.finetuning.checkpoints import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -23,6 +24,7 @@ import com.openai.models.finetuning.checkpoints.permissions.PermissionDeleteResp import com.openai.models.finetuning.checkpoints.permissions.PermissionRetrieveParams import com.openai.models.finetuning.checkpoints.permissions.PermissionRetrieveResponse import java.util.concurrent.CompletableFuture +import kotlin.jvm.optionals.getOrNull class PermissionServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : PermissionServiceAsync { @@ -67,6 +69,9 @@ class PermissionServiceAsyncImpl internal constructor(private val clientOptions: params: PermissionCreateParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("fineTunedModelCheckpoint", params.fineTunedModelCheckpoint().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -94,6 +99,7 @@ class PermissionServiceAsyncImpl internal constructor(private val clientOptions: .let { PermissionCreatePageAsync.builder() .service(PermissionServiceAsyncImpl(clientOptions)) + .streamHandlerExecutor(clientOptions.streamHandlerExecutor) .params(params) .response(it) .build() @@ -110,6 +116,9 @@ class PermissionServiceAsyncImpl internal constructor(private val clientOptions: params: PermissionRetrieveParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("fineTunedModelCheckpoint", params.fineTunedModelCheckpoint().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -145,6 +154,9 @@ class PermissionServiceAsyncImpl internal constructor(private val clientOptions: params: PermissionDeleteParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("permissionId", params.permissionId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.DELETE) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/jobs/CheckpointServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/jobs/CheckpointServiceAsync.kt index a479aa81..b53b92a9 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/jobs/CheckpointServiceAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/jobs/CheckpointServiceAsync.kt @@ -17,8 +17,23 @@ interface CheckpointServiceAsync { fun withRawResponse(): WithRawResponse /** List checkpoints for a fine-tuning job. */ - fun list(params: CheckpointListParams): CompletableFuture = - list(params, RequestOptions.none()) + fun list(fineTuningJobId: String): CompletableFuture = + list(fineTuningJobId, CheckpointListParams.none()) + + /** @see [list] */ + fun list( + fineTuningJobId: String, + params: CheckpointListParams = CheckpointListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + list(params.toBuilder().fineTuningJobId(fineTuningJobId).build(), requestOptions) + + /** @see [list] */ + fun list( + fineTuningJobId: String, + params: CheckpointListParams = CheckpointListParams.none(), + ): CompletableFuture = + list(fineTuningJobId, params, RequestOptions.none()) /** @see [list] */ fun list( @@ -26,6 +41,17 @@ interface CheckpointServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [list] */ + fun list(params: CheckpointListParams): CompletableFuture = + list(params, RequestOptions.none()) + + /** @see [list] */ + fun list( + fineTuningJobId: String, + requestOptions: RequestOptions, + ): CompletableFuture = + list(fineTuningJobId, CheckpointListParams.none(), requestOptions) + /** * A view of [CheckpointServiceAsync] that provides access to raw HTTP responses for each * method. @@ -38,9 +64,26 @@ interface CheckpointServiceAsync { */ @MustBeClosed fun list( - params: CheckpointListParams + fineTuningJobId: String ): CompletableFuture> = - list(params, RequestOptions.none()) + list(fineTuningJobId, CheckpointListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + fineTuningJobId: String, + params: CheckpointListParams = CheckpointListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + list(params.toBuilder().fineTuningJobId(fineTuningJobId).build(), requestOptions) + + /** @see [list] */ + @MustBeClosed + fun list( + fineTuningJobId: String, + params: CheckpointListParams = CheckpointListParams.none(), + ): CompletableFuture> = + list(fineTuningJobId, params, RequestOptions.none()) /** @see [list] */ @MustBeClosed @@ -48,5 +91,20 @@ interface CheckpointServiceAsync { params: CheckpointListParams, requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + + /** @see [list] */ + @MustBeClosed + fun list( + params: CheckpointListParams + ): CompletableFuture> = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + fineTuningJobId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + list(fineTuningJobId, CheckpointListParams.none(), requestOptions) } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/jobs/CheckpointServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/jobs/CheckpointServiceAsyncImpl.kt index 61014509..e4f74235 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/jobs/CheckpointServiceAsyncImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/jobs/CheckpointServiceAsyncImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.async.finetuning.jobs import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -18,6 +19,7 @@ import com.openai.models.finetuning.jobs.checkpoints.CheckpointListPageAsync import com.openai.models.finetuning.jobs.checkpoints.CheckpointListPageResponse import com.openai.models.finetuning.jobs.checkpoints.CheckpointListParams import java.util.concurrent.CompletableFuture +import kotlin.jvm.optionals.getOrNull class CheckpointServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : CheckpointServiceAsync { @@ -48,6 +50,9 @@ class CheckpointServiceAsyncImpl internal constructor(private val clientOptions: params: CheckpointListParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("fineTuningJobId", params.fineTuningJobId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -69,6 +74,7 @@ class CheckpointServiceAsyncImpl internal constructor(private val clientOptions: .let { CheckpointListPageAsync.builder() .service(CheckpointServiceAsyncImpl(clientOptions)) + .streamHandlerExecutor(clientOptions.streamHandlerExecutor) .params(params) .response(it) .build() diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/graders/GraderModelServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/graders/GraderModelServiceAsync.kt new file mode 100644 index 00000000..e1d62600 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/graders/GraderModelServiceAsync.kt @@ -0,0 +1,17 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.services.async.graders + +interface GraderModelServiceAsync { + + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + + /** + * A view of [GraderModelServiceAsync] that provides access to raw HTTP responses for each + * method. + */ + interface WithRawResponse +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/graders/GraderModelServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/graders/GraderModelServiceAsyncImpl.kt new file mode 100644 index 00000000..8132d3b8 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/graders/GraderModelServiceAsyncImpl.kt @@ -0,0 +1,18 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.services.async.graders + +import com.openai.core.ClientOptions + +class GraderModelServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + GraderModelServiceAsync { + + private val withRawResponse: GraderModelServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): GraderModelServiceAsync.WithRawResponse = withRawResponse + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + GraderModelServiceAsync.WithRawResponse +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/responses/InputItemServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/responses/InputItemServiceAsync.kt index c0c1abfd..11b92dbf 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/responses/InputItemServiceAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/responses/InputItemServiceAsync.kt @@ -17,8 +17,22 @@ interface InputItemServiceAsync { fun withRawResponse(): WithRawResponse /** Returns a list of input items for a given response. */ - fun list(params: InputItemListParams): CompletableFuture = - list(params, RequestOptions.none()) + fun list(responseId: String): CompletableFuture = + list(responseId, InputItemListParams.none()) + + /** @see [list] */ + fun list( + responseId: String, + params: InputItemListParams = InputItemListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + list(params.toBuilder().responseId(responseId).build(), requestOptions) + + /** @see [list] */ + fun list( + responseId: String, + params: InputItemListParams = InputItemListParams.none(), + ): CompletableFuture = list(responseId, params, RequestOptions.none()) /** @see [list] */ fun list( @@ -26,6 +40,17 @@ interface InputItemServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [list] */ + fun list(params: InputItemListParams): CompletableFuture = + list(params, RequestOptions.none()) + + /** @see [list] */ + fun list( + responseId: String, + requestOptions: RequestOptions, + ): CompletableFuture = + list(responseId, InputItemListParams.none(), requestOptions) + /** * A view of [InputItemServiceAsync] that provides access to raw HTTP responses for each method. */ @@ -36,10 +61,25 @@ interface InputItemServiceAsync { * otherwise the same as [InputItemServiceAsync.list]. */ @MustBeClosed + fun list(responseId: String): CompletableFuture> = + list(responseId, InputItemListParams.none()) + + /** @see [list] */ + @MustBeClosed fun list( - params: InputItemListParams + responseId: String, + params: InputItemListParams = InputItemListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> = - list(params, RequestOptions.none()) + list(params.toBuilder().responseId(responseId).build(), requestOptions) + + /** @see [list] */ + @MustBeClosed + fun list( + responseId: String, + params: InputItemListParams = InputItemListParams.none(), + ): CompletableFuture> = + list(responseId, params, RequestOptions.none()) /** @see [list] */ @MustBeClosed @@ -47,5 +87,20 @@ interface InputItemServiceAsync { params: InputItemListParams, requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + + /** @see [list] */ + @MustBeClosed + fun list( + params: InputItemListParams + ): CompletableFuture> = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + responseId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + list(responseId, InputItemListParams.none(), requestOptions) } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/responses/InputItemServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/responses/InputItemServiceAsyncImpl.kt index 32f8112e..0dbd0e04 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/responses/InputItemServiceAsyncImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/responses/InputItemServiceAsyncImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.async.responses import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -18,6 +19,7 @@ import com.openai.models.responses.inputitems.InputItemListPageAsync import com.openai.models.responses.inputitems.InputItemListParams import com.openai.models.responses.inputitems.ResponseItemList import java.util.concurrent.CompletableFuture +import kotlin.jvm.optionals.getOrNull class InputItemServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : InputItemServiceAsync { @@ -47,6 +49,9 @@ class InputItemServiceAsyncImpl internal constructor(private val clientOptions: params: InputItemListParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("responseId", params.responseId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -68,6 +73,7 @@ class InputItemServiceAsyncImpl internal constructor(private val clientOptions: .let { InputItemListPageAsync.builder() .service(InputItemServiceAsyncImpl(clientOptions)) + .streamHandlerExecutor(clientOptions.streamHandlerExecutor) .params(params) .response(it) .build() diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/uploads/PartServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/uploads/PartServiceAsync.kt index 2fd89686..7961d9b6 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/uploads/PartServiceAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/uploads/PartServiceAsync.kt @@ -28,6 +28,18 @@ interface PartServiceAsync { * Parts when you * [complete the Upload](https://platform.openai.com/docs/api-reference/uploads/complete). */ + fun create(uploadId: String, params: PartCreateParams): CompletableFuture = + create(uploadId, params, RequestOptions.none()) + + /** @see [create] */ + fun create( + uploadId: String, + params: PartCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + create(params.toBuilder().uploadId(uploadId).build(), requestOptions) + + /** @see [create] */ fun create(params: PartCreateParams): CompletableFuture = create(params, RequestOptions.none()) @@ -45,6 +57,23 @@ interface PartServiceAsync { * same as [PartServiceAsync.create]. */ @MustBeClosed + fun create( + uploadId: String, + params: PartCreateParams, + ): CompletableFuture> = + create(uploadId, params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + uploadId: String, + params: PartCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + create(params.toBuilder().uploadId(uploadId).build(), requestOptions) + + /** @see [create] */ + @MustBeClosed fun create(params: PartCreateParams): CompletableFuture> = create(params, RequestOptions.none()) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/uploads/PartServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/uploads/PartServiceAsyncImpl.kt index 6fddaa5a..381fb5fb 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/uploads/PartServiceAsyncImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/uploads/PartServiceAsyncImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.async.uploads import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -18,6 +19,7 @@ import com.openai.models.ErrorObject import com.openai.models.uploads.parts.PartCreateParams import com.openai.models.uploads.parts.UploadPart import java.util.concurrent.CompletableFuture +import kotlin.jvm.optionals.getOrNull class PartServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : PartServiceAsync { @@ -47,6 +49,9 @@ class PartServiceAsyncImpl internal constructor(private val clientOptions: Clien params: PartCreateParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("uploadId", params.uploadId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/vectorstores/FileBatchServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/vectorstores/FileBatchServiceAsync.kt index 9eb12653..df0a4a2d 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/vectorstores/FileBatchServiceAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/vectorstores/FileBatchServiceAsync.kt @@ -21,6 +21,21 @@ interface FileBatchServiceAsync { fun withRawResponse(): WithRawResponse /** Create a vector store file batch. */ + fun create( + vectorStoreId: String, + params: FileBatchCreateParams, + ): CompletableFuture = + create(vectorStoreId, params, RequestOptions.none()) + + /** @see [create] */ + fun create( + vectorStoreId: String, + params: FileBatchCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + create(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) + + /** @see [create] */ fun create(params: FileBatchCreateParams): CompletableFuture = create(params, RequestOptions.none()) @@ -31,6 +46,20 @@ interface FileBatchServiceAsync { ): CompletableFuture /** Retrieves a vector store file batch. */ + fun retrieve( + batchId: String, + params: FileBatchRetrieveParams, + ): CompletableFuture = retrieve(batchId, params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve( + batchId: String, + params: FileBatchRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + retrieve(params.toBuilder().batchId(batchId).build(), requestOptions) + + /** @see [retrieve] */ fun retrieve(params: FileBatchRetrieveParams): CompletableFuture = retrieve(params, RequestOptions.none()) @@ -44,6 +73,20 @@ interface FileBatchServiceAsync { * Cancel a vector store file batch. This attempts to cancel the processing of files in this * batch as soon as possible. */ + fun cancel( + batchId: String, + params: FileBatchCancelParams, + ): CompletableFuture = cancel(batchId, params, RequestOptions.none()) + + /** @see [cancel] */ + fun cancel( + batchId: String, + params: FileBatchCancelParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + cancel(params.toBuilder().batchId(batchId).build(), requestOptions) + + /** @see [cancel] */ fun cancel(params: FileBatchCancelParams): CompletableFuture = cancel(params, RequestOptions.none()) @@ -54,6 +97,21 @@ interface FileBatchServiceAsync { ): CompletableFuture /** Returns a list of vector store files in a batch. */ + fun listFiles( + batchId: String, + params: FileBatchListFilesParams, + ): CompletableFuture = + listFiles(batchId, params, RequestOptions.none()) + + /** @see [listFiles] */ + fun listFiles( + batchId: String, + params: FileBatchListFilesParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + listFiles(params.toBuilder().batchId(batchId).build(), requestOptions) + + /** @see [listFiles] */ fun listFiles( params: FileBatchListFilesParams ): CompletableFuture = listFiles(params, RequestOptions.none()) @@ -74,6 +132,23 @@ interface FileBatchServiceAsync { * is otherwise the same as [FileBatchServiceAsync.create]. */ @MustBeClosed + fun create( + vectorStoreId: String, + params: FileBatchCreateParams, + ): CompletableFuture> = + create(vectorStoreId, params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + vectorStoreId: String, + params: FileBatchCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + create(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) + + /** @see [create] */ + @MustBeClosed fun create( params: FileBatchCreateParams ): CompletableFuture> = @@ -92,6 +167,23 @@ interface FileBatchServiceAsync { * [FileBatchServiceAsync.retrieve]. */ @MustBeClosed + fun retrieve( + batchId: String, + params: FileBatchRetrieveParams, + ): CompletableFuture> = + retrieve(batchId, params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + batchId: String, + params: FileBatchRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + retrieve(params.toBuilder().batchId(batchId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed fun retrieve( params: FileBatchRetrieveParams ): CompletableFuture> = @@ -110,6 +202,23 @@ interface FileBatchServiceAsync { * same as [FileBatchServiceAsync.cancel]. */ @MustBeClosed + fun cancel( + batchId: String, + params: FileBatchCancelParams, + ): CompletableFuture> = + cancel(batchId, params, RequestOptions.none()) + + /** @see [cancel] */ + @MustBeClosed + fun cancel( + batchId: String, + params: FileBatchCancelParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + cancel(params.toBuilder().batchId(batchId).build(), requestOptions) + + /** @see [cancel] */ + @MustBeClosed fun cancel( params: FileBatchCancelParams ): CompletableFuture> = @@ -128,6 +237,23 @@ interface FileBatchServiceAsync { * same as [FileBatchServiceAsync.listFiles]. */ @MustBeClosed + fun listFiles( + batchId: String, + params: FileBatchListFilesParams, + ): CompletableFuture> = + listFiles(batchId, params, RequestOptions.none()) + + /** @see [listFiles] */ + @MustBeClosed + fun listFiles( + batchId: String, + params: FileBatchListFilesParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + listFiles(params.toBuilder().batchId(batchId).build(), requestOptions) + + /** @see [listFiles] */ + @MustBeClosed fun listFiles( params: FileBatchListFilesParams ): CompletableFuture> = diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/vectorstores/FileBatchServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/vectorstores/FileBatchServiceAsyncImpl.kt index e9d7625a..1d8d8086 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/vectorstores/FileBatchServiceAsyncImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/vectorstores/FileBatchServiceAsyncImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.async.vectorstores import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -24,6 +25,7 @@ import com.openai.models.vectorstores.filebatches.FileBatchListFilesParams import com.openai.models.vectorstores.filebatches.FileBatchRetrieveParams import com.openai.models.vectorstores.filebatches.VectorStoreFileBatch import java.util.concurrent.CompletableFuture +import kotlin.jvm.optionals.getOrNull class FileBatchServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : FileBatchServiceAsync { @@ -80,6 +82,9 @@ class FileBatchServiceAsyncImpl internal constructor(private val clientOptions: params: FileBatchCreateParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("vectorStoreId", params.vectorStoreId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -112,6 +117,9 @@ class FileBatchServiceAsyncImpl internal constructor(private val clientOptions: params: FileBatchRetrieveParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("batchId", params.batchId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -148,6 +156,9 @@ class FileBatchServiceAsyncImpl internal constructor(private val clientOptions: params: FileBatchCancelParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("batchId", params.batchId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -186,6 +197,9 @@ class FileBatchServiceAsyncImpl internal constructor(private val clientOptions: params: FileBatchListFilesParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("batchId", params.batchId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -214,6 +228,7 @@ class FileBatchServiceAsyncImpl internal constructor(private val clientOptions: .let { FileBatchListFilesPageAsync.builder() .service(FileBatchServiceAsyncImpl(clientOptions)) + .streamHandlerExecutor(clientOptions.streamHandlerExecutor) .params(params) .response(it) .build() diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/vectorstores/FileServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/vectorstores/FileServiceAsync.kt index 27a654c3..bc0b1e49 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/vectorstores/FileServiceAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/vectorstores/FileServiceAsync.kt @@ -29,6 +29,20 @@ interface FileServiceAsync { * [File](https://platform.openai.com/docs/api-reference/files) to a * [vector store](https://platform.openai.com/docs/api-reference/vector-stores/object). */ + fun create( + vectorStoreId: String, + params: FileCreateParams, + ): CompletableFuture = create(vectorStoreId, params, RequestOptions.none()) + + /** @see [create] */ + fun create( + vectorStoreId: String, + params: FileCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + create(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) + + /** @see [create] */ fun create(params: FileCreateParams): CompletableFuture = create(params, RequestOptions.none()) @@ -39,6 +53,18 @@ interface FileServiceAsync { ): CompletableFuture /** Retrieves a vector store file. */ + fun retrieve(fileId: String, params: FileRetrieveParams): CompletableFuture = + retrieve(fileId, params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve( + fileId: String, + params: FileRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + retrieve(params.toBuilder().fileId(fileId).build(), requestOptions) + + /** @see [retrieve] */ fun retrieve(params: FileRetrieveParams): CompletableFuture = retrieve(params, RequestOptions.none()) @@ -49,6 +75,18 @@ interface FileServiceAsync { ): CompletableFuture /** Update attributes on a vector store file. */ + fun update(fileId: String, params: FileUpdateParams): CompletableFuture = + update(fileId, params, RequestOptions.none()) + + /** @see [update] */ + fun update( + fileId: String, + params: FileUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + update(params.toBuilder().fileId(fileId).build(), requestOptions) + + /** @see [update] */ fun update(params: FileUpdateParams): CompletableFuture = update(params, RequestOptions.none()) @@ -59,8 +97,22 @@ interface FileServiceAsync { ): CompletableFuture /** Returns a list of vector store files. */ - fun list(params: FileListParams): CompletableFuture = - list(params, RequestOptions.none()) + fun list(vectorStoreId: String): CompletableFuture = + list(vectorStoreId, FileListParams.none()) + + /** @see [list] */ + fun list( + vectorStoreId: String, + params: FileListParams = FileListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + list(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) + + /** @see [list] */ + fun list( + vectorStoreId: String, + params: FileListParams = FileListParams.none(), + ): CompletableFuture = list(vectorStoreId, params, RequestOptions.none()) /** @see [list] */ fun list( @@ -68,11 +120,36 @@ interface FileServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [list] */ + fun list(params: FileListParams): CompletableFuture = + list(params, RequestOptions.none()) + + /** @see [list] */ + fun list( + vectorStoreId: String, + requestOptions: RequestOptions, + ): CompletableFuture = + list(vectorStoreId, FileListParams.none(), requestOptions) + /** * Delete a vector store file. This will remove the file from the vector store but the file * itself will not be deleted. To delete the file, use the * [delete file](https://platform.openai.com/docs/api-reference/files/delete) endpoint. */ + fun delete( + fileId: String, + params: FileDeleteParams, + ): CompletableFuture = delete(fileId, params, RequestOptions.none()) + + /** @see [delete] */ + fun delete( + fileId: String, + params: FileDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + delete(params.toBuilder().fileId(fileId).build(), requestOptions) + + /** @see [delete] */ fun delete(params: FileDeleteParams): CompletableFuture = delete(params, RequestOptions.none()) @@ -83,6 +160,20 @@ interface FileServiceAsync { ): CompletableFuture /** Retrieve the parsed contents of a vector store file. */ + fun content( + fileId: String, + params: FileContentParams, + ): CompletableFuture = content(fileId, params, RequestOptions.none()) + + /** @see [content] */ + fun content( + fileId: String, + params: FileContentParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + content(params.toBuilder().fileId(fileId).build(), requestOptions) + + /** @see [content] */ fun content(params: FileContentParams): CompletableFuture = content(params, RequestOptions.none()) @@ -100,6 +191,23 @@ interface FileServiceAsync { * otherwise the same as [FileServiceAsync.create]. */ @MustBeClosed + fun create( + vectorStoreId: String, + params: FileCreateParams, + ): CompletableFuture> = + create(vectorStoreId, params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + vectorStoreId: String, + params: FileCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + create(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) + + /** @see [create] */ + @MustBeClosed fun create(params: FileCreateParams): CompletableFuture> = create(params, RequestOptions.none()) @@ -115,6 +223,23 @@ interface FileServiceAsync { * but is otherwise the same as [FileServiceAsync.retrieve]. */ @MustBeClosed + fun retrieve( + fileId: String, + params: FileRetrieveParams, + ): CompletableFuture> = + retrieve(fileId, params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + fileId: String, + params: FileRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + retrieve(params.toBuilder().fileId(fileId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed fun retrieve( params: FileRetrieveParams ): CompletableFuture> = @@ -132,6 +257,23 @@ interface FileServiceAsync { * but is otherwise the same as [FileServiceAsync.update]. */ @MustBeClosed + fun update( + fileId: String, + params: FileUpdateParams, + ): CompletableFuture> = + update(fileId, params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + fileId: String, + params: FileUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + update(params.toBuilder().fileId(fileId).build(), requestOptions) + + /** @see [update] */ + @MustBeClosed fun update(params: FileUpdateParams): CompletableFuture> = update(params, RequestOptions.none()) @@ -147,8 +289,25 @@ interface FileServiceAsync { * otherwise the same as [FileServiceAsync.list]. */ @MustBeClosed - fun list(params: FileListParams): CompletableFuture> = - list(params, RequestOptions.none()) + fun list(vectorStoreId: String): CompletableFuture> = + list(vectorStoreId, FileListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + vectorStoreId: String, + params: FileListParams = FileListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + list(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) + + /** @see [list] */ + @MustBeClosed + fun list( + vectorStoreId: String, + params: FileListParams = FileListParams.none(), + ): CompletableFuture> = + list(vectorStoreId, params, RequestOptions.none()) /** @see [list] */ @MustBeClosed @@ -157,12 +316,42 @@ interface FileServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** @see [list] */ + @MustBeClosed + fun list(params: FileListParams): CompletableFuture> = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + vectorStoreId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + list(vectorStoreId, FileListParams.none(), requestOptions) + /** * Returns a raw HTTP response for `delete * /vector_stores/{vector_store_id}/files/{file_id}`, but is otherwise the same as * [FileServiceAsync.delete]. */ @MustBeClosed + fun delete( + fileId: String, + params: FileDeleteParams, + ): CompletableFuture> = + delete(fileId, params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + fileId: String, + params: FileDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + delete(params.toBuilder().fileId(fileId).build(), requestOptions) + + /** @see [delete] */ + @MustBeClosed fun delete( params: FileDeleteParams ): CompletableFuture> = @@ -181,6 +370,23 @@ interface FileServiceAsync { * [FileServiceAsync.content]. */ @MustBeClosed + fun content( + fileId: String, + params: FileContentParams, + ): CompletableFuture> = + content(fileId, params, RequestOptions.none()) + + /** @see [content] */ + @MustBeClosed + fun content( + fileId: String, + params: FileContentParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + content(params.toBuilder().fileId(fileId).build(), requestOptions) + + /** @see [content] */ + @MustBeClosed fun content( params: FileContentParams ): CompletableFuture> = diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/vectorstores/FileServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/vectorstores/FileServiceAsyncImpl.kt index a03202c6..9780e9b6 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/vectorstores/FileServiceAsyncImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/vectorstores/FileServiceAsyncImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.async.vectorstores import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -29,6 +30,7 @@ import com.openai.models.vectorstores.files.FileUpdateParams import com.openai.models.vectorstores.files.VectorStoreFile import com.openai.models.vectorstores.files.VectorStoreFileDeleted import java.util.concurrent.CompletableFuture +import kotlin.jvm.optionals.getOrNull class FileServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : FileServiceAsync { @@ -98,6 +100,9 @@ class FileServiceAsyncImpl internal constructor(private val clientOptions: Clien params: FileCreateParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("vectorStoreId", params.vectorStoreId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -129,6 +134,9 @@ class FileServiceAsyncImpl internal constructor(private val clientOptions: Clien params: FileRetrieveParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("fileId", params.fileId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -164,6 +172,9 @@ class FileServiceAsyncImpl internal constructor(private val clientOptions: Clien params: FileUpdateParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("fileId", params.fileId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -201,6 +212,9 @@ class FileServiceAsyncImpl internal constructor(private val clientOptions: Clien params: FileListParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("vectorStoreId", params.vectorStoreId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -223,6 +237,7 @@ class FileServiceAsyncImpl internal constructor(private val clientOptions: Clien .let { FileListPageAsync.builder() .service(FileServiceAsyncImpl(clientOptions)) + .streamHandlerExecutor(clientOptions.streamHandlerExecutor) .params(params) .response(it) .build() @@ -239,6 +254,9 @@ class FileServiceAsyncImpl internal constructor(private val clientOptions: Clien params: FileDeleteParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("fileId", params.fileId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.DELETE) @@ -276,6 +294,9 @@ class FileServiceAsyncImpl internal constructor(private val clientOptions: Clien params: FileContentParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("fileId", params.fileId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -304,6 +325,7 @@ class FileServiceAsyncImpl internal constructor(private val clientOptions: Clien .let { FileContentPageAsync.builder() .service(FileServiceAsyncImpl(clientOptions)) + .streamHandlerExecutor(clientOptions.streamHandlerExecutor) .params(params) .response(it) .build() diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/BatchService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/BatchService.kt index 6c66bb58..778efa58 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/BatchService.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/BatchService.kt @@ -29,7 +29,18 @@ interface BatchService { ): Batch /** Retrieves a batch. */ - fun retrieve(params: BatchRetrieveParams): Batch = retrieve(params, RequestOptions.none()) + fun retrieve(batchId: String): Batch = retrieve(batchId, BatchRetrieveParams.none()) + + /** @see [retrieve] */ + fun retrieve( + batchId: String, + params: BatchRetrieveParams = BatchRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): Batch = retrieve(params.toBuilder().batchId(batchId).build(), requestOptions) + + /** @see [retrieve] */ + fun retrieve(batchId: String, params: BatchRetrieveParams = BatchRetrieveParams.none()): Batch = + retrieve(batchId, params, RequestOptions.none()) /** @see [retrieve] */ fun retrieve( @@ -37,6 +48,13 @@ interface BatchService { requestOptions: RequestOptions = RequestOptions.none(), ): Batch + /** @see [retrieve] */ + fun retrieve(params: BatchRetrieveParams): Batch = retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve(batchId: String, requestOptions: RequestOptions): Batch = + retrieve(batchId, BatchRetrieveParams.none(), requestOptions) + /** List your organization's batches. */ fun list(): BatchListPage = list(BatchListParams.none()) @@ -59,7 +77,18 @@ interface BatchService { * before changing to `cancelled`, where it will have partial results (if any) available in the * output file. */ - fun cancel(params: BatchCancelParams): Batch = cancel(params, RequestOptions.none()) + fun cancel(batchId: String): Batch = cancel(batchId, BatchCancelParams.none()) + + /** @see [cancel] */ + fun cancel( + batchId: String, + params: BatchCancelParams = BatchCancelParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): Batch = cancel(params.toBuilder().batchId(batchId).build(), requestOptions) + + /** @see [cancel] */ + fun cancel(batchId: String, params: BatchCancelParams = BatchCancelParams.none()): Batch = + cancel(batchId, params, RequestOptions.none()) /** @see [cancel] */ fun cancel( @@ -67,6 +96,13 @@ interface BatchService { requestOptions: RequestOptions = RequestOptions.none(), ): Batch + /** @see [cancel] */ + fun cancel(params: BatchCancelParams): Batch = cancel(params, RequestOptions.none()) + + /** @see [cancel] */ + fun cancel(batchId: String, requestOptions: RequestOptions): Batch = + cancel(batchId, BatchCancelParams.none(), requestOptions) + /** A view of [BatchService] that provides access to raw HTTP responses for each method. */ interface WithRawResponse { @@ -90,8 +126,24 @@ interface BatchService { * [BatchService.retrieve]. */ @MustBeClosed - fun retrieve(params: BatchRetrieveParams): HttpResponseFor = - retrieve(params, RequestOptions.none()) + fun retrieve(batchId: String): HttpResponseFor = + retrieve(batchId, BatchRetrieveParams.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + batchId: String, + params: BatchRetrieveParams = BatchRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + retrieve(params.toBuilder().batchId(batchId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + batchId: String, + params: BatchRetrieveParams = BatchRetrieveParams.none(), + ): HttpResponseFor = retrieve(batchId, params, RequestOptions.none()) /** @see [retrieve] */ @MustBeClosed @@ -100,6 +152,16 @@ interface BatchService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** @see [retrieve] */ + @MustBeClosed + fun retrieve(params: BatchRetrieveParams): HttpResponseFor = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve(batchId: String, requestOptions: RequestOptions): HttpResponseFor = + retrieve(batchId, BatchRetrieveParams.none(), requestOptions) + /** * Returns a raw HTTP response for `get /batches`, but is otherwise the same as * [BatchService.list]. @@ -128,8 +190,24 @@ interface BatchService { * same as [BatchService.cancel]. */ @MustBeClosed - fun cancel(params: BatchCancelParams): HttpResponseFor = - cancel(params, RequestOptions.none()) + fun cancel(batchId: String): HttpResponseFor = + cancel(batchId, BatchCancelParams.none()) + + /** @see [cancel] */ + @MustBeClosed + fun cancel( + batchId: String, + params: BatchCancelParams = BatchCancelParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + cancel(params.toBuilder().batchId(batchId).build(), requestOptions) + + /** @see [cancel] */ + @MustBeClosed + fun cancel( + batchId: String, + params: BatchCancelParams = BatchCancelParams.none(), + ): HttpResponseFor = cancel(batchId, params, RequestOptions.none()) /** @see [cancel] */ @MustBeClosed @@ -137,5 +215,15 @@ interface BatchService { params: BatchCancelParams, requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + + /** @see [cancel] */ + @MustBeClosed + fun cancel(params: BatchCancelParams): HttpResponseFor = + cancel(params, RequestOptions.none()) + + /** @see [cancel] */ + @MustBeClosed + fun cancel(batchId: String, requestOptions: RequestOptions): HttpResponseFor = + cancel(batchId, BatchCancelParams.none(), requestOptions) } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/BatchServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/BatchServiceImpl.kt index 7a1a929c..51717e40 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/BatchServiceImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/BatchServiceImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.blocking import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -22,6 +23,7 @@ import com.openai.models.batches.BatchListPage import com.openai.models.batches.BatchListPageResponse import com.openai.models.batches.BatchListParams import com.openai.models.batches.BatchRetrieveParams +import kotlin.jvm.optionals.getOrNull class BatchServiceImpl internal constructor(private val clientOptions: ClientOptions) : BatchService { @@ -87,6 +89,9 @@ class BatchServiceImpl internal constructor(private val clientOptions: ClientOpt params: BatchRetrieveParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("batchId", params.batchId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -147,6 +152,9 @@ class BatchServiceImpl internal constructor(private val clientOptions: ClientOpt params: BatchCancelParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("batchId", params.batchId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/EvalService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/EvalService.kt index 594a1ffc..f1af3c4c 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/EvalService.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/EvalService.kt @@ -42,8 +42,20 @@ interface EvalService { ): EvalCreateResponse /** Get an evaluation by ID. */ - fun retrieve(params: EvalRetrieveParams): EvalRetrieveResponse = - retrieve(params, RequestOptions.none()) + fun retrieve(evalId: String): EvalRetrieveResponse = retrieve(evalId, EvalRetrieveParams.none()) + + /** @see [retrieve] */ + fun retrieve( + evalId: String, + params: EvalRetrieveParams = EvalRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): EvalRetrieveResponse = retrieve(params.toBuilder().evalId(evalId).build(), requestOptions) + + /** @see [retrieve] */ + fun retrieve( + evalId: String, + params: EvalRetrieveParams = EvalRetrieveParams.none(), + ): EvalRetrieveResponse = retrieve(evalId, params, RequestOptions.none()) /** @see [retrieve] */ fun retrieve( @@ -51,8 +63,29 @@ interface EvalService { requestOptions: RequestOptions = RequestOptions.none(), ): EvalRetrieveResponse + /** @see [retrieve] */ + fun retrieve(params: EvalRetrieveParams): EvalRetrieveResponse = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve(evalId: String, requestOptions: RequestOptions): EvalRetrieveResponse = + retrieve(evalId, EvalRetrieveParams.none(), requestOptions) + /** Update certain properties of an evaluation. */ - fun update(params: EvalUpdateParams): EvalUpdateResponse = update(params, RequestOptions.none()) + fun update(evalId: String): EvalUpdateResponse = update(evalId, EvalUpdateParams.none()) + + /** @see [update] */ + fun update( + evalId: String, + params: EvalUpdateParams = EvalUpdateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): EvalUpdateResponse = update(params.toBuilder().evalId(evalId).build(), requestOptions) + + /** @see [update] */ + fun update( + evalId: String, + params: EvalUpdateParams = EvalUpdateParams.none(), + ): EvalUpdateResponse = update(evalId, params, RequestOptions.none()) /** @see [update] */ fun update( @@ -60,6 +93,13 @@ interface EvalService { requestOptions: RequestOptions = RequestOptions.none(), ): EvalUpdateResponse + /** @see [update] */ + fun update(params: EvalUpdateParams): EvalUpdateResponse = update(params, RequestOptions.none()) + + /** @see [update] */ + fun update(evalId: String, requestOptions: RequestOptions): EvalUpdateResponse = + update(evalId, EvalUpdateParams.none(), requestOptions) + /** List evaluations for a project. */ fun list(): EvalListPage = list(EvalListParams.none()) @@ -78,7 +118,20 @@ interface EvalService { list(EvalListParams.none(), requestOptions) /** Delete an evaluation. */ - fun delete(params: EvalDeleteParams): EvalDeleteResponse = delete(params, RequestOptions.none()) + fun delete(evalId: String): EvalDeleteResponse = delete(evalId, EvalDeleteParams.none()) + + /** @see [delete] */ + fun delete( + evalId: String, + params: EvalDeleteParams = EvalDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): EvalDeleteResponse = delete(params.toBuilder().evalId(evalId).build(), requestOptions) + + /** @see [delete] */ + fun delete( + evalId: String, + params: EvalDeleteParams = EvalDeleteParams.none(), + ): EvalDeleteResponse = delete(evalId, params, RequestOptions.none()) /** @see [delete] */ fun delete( @@ -86,6 +139,13 @@ interface EvalService { requestOptions: RequestOptions = RequestOptions.none(), ): EvalDeleteResponse + /** @see [delete] */ + fun delete(params: EvalDeleteParams): EvalDeleteResponse = delete(params, RequestOptions.none()) + + /** @see [delete] */ + fun delete(evalId: String, requestOptions: RequestOptions): EvalDeleteResponse = + delete(evalId, EvalDeleteParams.none(), requestOptions) + /** A view of [EvalService] that provides access to raw HTTP responses for each method. */ interface WithRawResponse { @@ -111,8 +171,24 @@ interface EvalService { * [EvalService.retrieve]. */ @MustBeClosed - fun retrieve(params: EvalRetrieveParams): HttpResponseFor = - retrieve(params, RequestOptions.none()) + fun retrieve(evalId: String): HttpResponseFor = + retrieve(evalId, EvalRetrieveParams.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + evalId: String, + params: EvalRetrieveParams = EvalRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + retrieve(params.toBuilder().evalId(evalId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + evalId: String, + params: EvalRetrieveParams = EvalRetrieveParams.none(), + ): HttpResponseFor = retrieve(evalId, params, RequestOptions.none()) /** @see [retrieve] */ @MustBeClosed @@ -121,13 +197,42 @@ interface EvalService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** @see [retrieve] */ + @MustBeClosed + fun retrieve(params: EvalRetrieveParams): HttpResponseFor = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + evalId: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + retrieve(evalId, EvalRetrieveParams.none(), requestOptions) + /** * Returns a raw HTTP response for `post /evals/{eval_id}`, but is otherwise the same as * [EvalService.update]. */ @MustBeClosed - fun update(params: EvalUpdateParams): HttpResponseFor = - update(params, RequestOptions.none()) + fun update(evalId: String): HttpResponseFor = + update(evalId, EvalUpdateParams.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + evalId: String, + params: EvalUpdateParams = EvalUpdateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + update(params.toBuilder().evalId(evalId).build(), requestOptions) + + /** @see [update] */ + @MustBeClosed + fun update( + evalId: String, + params: EvalUpdateParams = EvalUpdateParams.none(), + ): HttpResponseFor = update(evalId, params, RequestOptions.none()) /** @see [update] */ @MustBeClosed @@ -136,6 +241,19 @@ interface EvalService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** @see [update] */ + @MustBeClosed + fun update(params: EvalUpdateParams): HttpResponseFor = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + evalId: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + update(evalId, EvalUpdateParams.none(), requestOptions) + /** * Returns a raw HTTP response for `get /evals`, but is otherwise the same as * [EvalService.list]. @@ -164,8 +282,24 @@ interface EvalService { * [EvalService.delete]. */ @MustBeClosed - fun delete(params: EvalDeleteParams): HttpResponseFor = - delete(params, RequestOptions.none()) + fun delete(evalId: String): HttpResponseFor = + delete(evalId, EvalDeleteParams.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + evalId: String, + params: EvalDeleteParams = EvalDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + delete(params.toBuilder().evalId(evalId).build(), requestOptions) + + /** @see [delete] */ + @MustBeClosed + fun delete( + evalId: String, + params: EvalDeleteParams = EvalDeleteParams.none(), + ): HttpResponseFor = delete(evalId, params, RequestOptions.none()) /** @see [delete] */ @MustBeClosed @@ -173,5 +307,18 @@ interface EvalService { params: EvalDeleteParams, requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + + /** @see [delete] */ + @MustBeClosed + fun delete(params: EvalDeleteParams): HttpResponseFor = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + evalId: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + delete(evalId, EvalDeleteParams.none(), requestOptions) } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/EvalServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/EvalServiceImpl.kt index faa4cc5f..9fda99b9 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/EvalServiceImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/EvalServiceImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.blocking import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -28,6 +29,7 @@ import com.openai.models.evals.EvalUpdateParams import com.openai.models.evals.EvalUpdateResponse import com.openai.services.blocking.evals.RunService import com.openai.services.blocking.evals.RunServiceImpl +import kotlin.jvm.optionals.getOrNull class EvalServiceImpl internal constructor(private val clientOptions: ClientOptions) : EvalService { @@ -119,6 +121,9 @@ class EvalServiceImpl internal constructor(private val clientOptions: ClientOpti params: EvalRetrieveParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("evalId", params.evalId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -145,6 +150,9 @@ class EvalServiceImpl internal constructor(private val clientOptions: ClientOpti params: EvalUpdateParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("evalId", params.evalId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -206,6 +214,9 @@ class EvalServiceImpl internal constructor(private val clientOptions: ClientOpti params: EvalDeleteParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("evalId", params.evalId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.DELETE) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/FileService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/FileService.kt index c952d6af..3f4934c3 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/FileService.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/FileService.kt @@ -50,7 +50,20 @@ interface FileService { ): FileObject /** Returns information about a specific file. */ - fun retrieve(params: FileRetrieveParams): FileObject = retrieve(params, RequestOptions.none()) + fun retrieve(fileId: String): FileObject = retrieve(fileId, FileRetrieveParams.none()) + + /** @see [retrieve] */ + fun retrieve( + fileId: String, + params: FileRetrieveParams = FileRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): FileObject = retrieve(params.toBuilder().fileId(fileId).build(), requestOptions) + + /** @see [retrieve] */ + fun retrieve( + fileId: String, + params: FileRetrieveParams = FileRetrieveParams.none(), + ): FileObject = retrieve(fileId, params, RequestOptions.none()) /** @see [retrieve] */ fun retrieve( @@ -58,6 +71,13 @@ interface FileService { requestOptions: RequestOptions = RequestOptions.none(), ): FileObject + /** @see [retrieve] */ + fun retrieve(params: FileRetrieveParams): FileObject = retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve(fileId: String, requestOptions: RequestOptions): FileObject = + retrieve(fileId, FileRetrieveParams.none(), requestOptions) + /** Returns a list of files. */ fun list(): FileListPage = list(FileListParams.none()) @@ -76,7 +96,18 @@ interface FileService { list(FileListParams.none(), requestOptions) /** Delete a file. */ - fun delete(params: FileDeleteParams): FileDeleted = delete(params, RequestOptions.none()) + fun delete(fileId: String): FileDeleted = delete(fileId, FileDeleteParams.none()) + + /** @see [delete] */ + fun delete( + fileId: String, + params: FileDeleteParams = FileDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): FileDeleted = delete(params.toBuilder().fileId(fileId).build(), requestOptions) + + /** @see [delete] */ + fun delete(fileId: String, params: FileDeleteParams = FileDeleteParams.none()): FileDeleted = + delete(fileId, params, RequestOptions.none()) /** @see [delete] */ fun delete( @@ -84,9 +115,31 @@ interface FileService { requestOptions: RequestOptions = RequestOptions.none(), ): FileDeleted + /** @see [delete] */ + fun delete(params: FileDeleteParams): FileDeleted = delete(params, RequestOptions.none()) + + /** @see [delete] */ + fun delete(fileId: String, requestOptions: RequestOptions): FileDeleted = + delete(fileId, FileDeleteParams.none(), requestOptions) + /** Returns the contents of the specified file. */ @MustBeClosed - fun content(params: FileContentParams): HttpResponse = content(params, RequestOptions.none()) + fun content(fileId: String): HttpResponse = content(fileId, FileContentParams.none()) + + /** @see [content] */ + @MustBeClosed + fun content( + fileId: String, + params: FileContentParams = FileContentParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponse = content(params.toBuilder().fileId(fileId).build(), requestOptions) + + /** @see [content] */ + @MustBeClosed + fun content( + fileId: String, + params: FileContentParams = FileContentParams.none(), + ): HttpResponse = content(fileId, params, RequestOptions.none()) /** @see [content] */ @MustBeClosed @@ -95,6 +148,15 @@ interface FileService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponse + /** @see [content] */ + @MustBeClosed + fun content(params: FileContentParams): HttpResponse = content(params, RequestOptions.none()) + + /** @see [content] */ + @MustBeClosed + fun content(fileId: String, requestOptions: RequestOptions): HttpResponse = + content(fileId, FileContentParams.none(), requestOptions) + /** A view of [FileService] that provides access to raw HTTP responses for each method. */ interface WithRawResponse { @@ -118,8 +180,24 @@ interface FileService { * [FileService.retrieve]. */ @MustBeClosed - fun retrieve(params: FileRetrieveParams): HttpResponseFor = - retrieve(params, RequestOptions.none()) + fun retrieve(fileId: String): HttpResponseFor = + retrieve(fileId, FileRetrieveParams.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + fileId: String, + params: FileRetrieveParams = FileRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + retrieve(params.toBuilder().fileId(fileId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + fileId: String, + params: FileRetrieveParams = FileRetrieveParams.none(), + ): HttpResponseFor = retrieve(fileId, params, RequestOptions.none()) /** @see [retrieve] */ @MustBeClosed @@ -128,6 +206,16 @@ interface FileService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** @see [retrieve] */ + @MustBeClosed + fun retrieve(params: FileRetrieveParams): HttpResponseFor = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve(fileId: String, requestOptions: RequestOptions): HttpResponseFor = + retrieve(fileId, FileRetrieveParams.none(), requestOptions) + /** * Returns a raw HTTP response for `get /files`, but is otherwise the same as * [FileService.list]. @@ -156,8 +244,24 @@ interface FileService { * [FileService.delete]. */ @MustBeClosed - fun delete(params: FileDeleteParams): HttpResponseFor = - delete(params, RequestOptions.none()) + fun delete(fileId: String): HttpResponseFor = + delete(fileId, FileDeleteParams.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + fileId: String, + params: FileDeleteParams = FileDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + delete(params.toBuilder().fileId(fileId).build(), requestOptions) + + /** @see [delete] */ + @MustBeClosed + fun delete( + fileId: String, + params: FileDeleteParams = FileDeleteParams.none(), + ): HttpResponseFor = delete(fileId, params, RequestOptions.none()) /** @see [delete] */ @MustBeClosed @@ -166,13 +270,37 @@ interface FileService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** @see [delete] */ + @MustBeClosed + fun delete(params: FileDeleteParams): HttpResponseFor = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete(fileId: String, requestOptions: RequestOptions): HttpResponseFor = + delete(fileId, FileDeleteParams.none(), requestOptions) + /** * Returns a raw HTTP response for `get /files/{file_id}/content`, but is otherwise the same * as [FileService.content]. */ @MustBeClosed - fun content(params: FileContentParams): HttpResponse = - content(params, RequestOptions.none()) + fun content(fileId: String): HttpResponse = content(fileId, FileContentParams.none()) + + /** @see [content] */ + @MustBeClosed + fun content( + fileId: String, + params: FileContentParams = FileContentParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponse = content(params.toBuilder().fileId(fileId).build(), requestOptions) + + /** @see [content] */ + @MustBeClosed + fun content( + fileId: String, + params: FileContentParams = FileContentParams.none(), + ): HttpResponse = content(fileId, params, RequestOptions.none()) /** @see [content] */ @MustBeClosed @@ -180,5 +308,15 @@ interface FileService { params: FileContentParams, requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponse + + /** @see [content] */ + @MustBeClosed + fun content(params: FileContentParams): HttpResponse = + content(params, RequestOptions.none()) + + /** @see [content] */ + @MustBeClosed + fun content(fileId: String, requestOptions: RequestOptions): HttpResponse = + content(fileId, FileContentParams.none(), requestOptions) } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/FileServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/FileServiceImpl.kt index c9b1f1f7..0f997029 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/FileServiceImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/FileServiceImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.blocking import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -26,6 +27,7 @@ import com.openai.models.files.FileListPageResponse import com.openai.models.files.FileListParams import com.openai.models.files.FileObject import com.openai.models.files.FileRetrieveParams +import kotlin.jvm.optionals.getOrNull class FileServiceImpl internal constructor(private val clientOptions: ClientOptions) : FileService { @@ -94,6 +96,9 @@ class FileServiceImpl internal constructor(private val clientOptions: ClientOpti params: FileRetrieveParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("fileId", params.fileId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -154,6 +159,9 @@ class FileServiceImpl internal constructor(private val clientOptions: ClientOpti params: FileDeleteParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("fileId", params.fileId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.DELETE) @@ -178,6 +186,9 @@ class FileServiceImpl internal constructor(private val clientOptions: ClientOpti params: FileContentParams, requestOptions: RequestOptions, ): HttpResponse { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("fileId", params.fileId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/FineTuningService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/FineTuningService.kt index b6380655..77f45a35 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/FineTuningService.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/FineTuningService.kt @@ -2,8 +2,10 @@ package com.openai.services.blocking +import com.openai.services.blocking.finetuning.AlphaService import com.openai.services.blocking.finetuning.CheckpointService import com.openai.services.blocking.finetuning.JobService +import com.openai.services.blocking.finetuning.MethodService interface FineTuningService { @@ -12,15 +14,23 @@ interface FineTuningService { */ fun withRawResponse(): WithRawResponse + fun methods(): MethodService + fun jobs(): JobService fun checkpoints(): CheckpointService + fun alpha(): AlphaService + /** A view of [FineTuningService] that provides access to raw HTTP responses for each method. */ interface WithRawResponse { + fun methods(): MethodService.WithRawResponse + fun jobs(): JobService.WithRawResponse fun checkpoints(): CheckpointService.WithRawResponse + + fun alpha(): AlphaService.WithRawResponse } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/FineTuningServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/FineTuningServiceImpl.kt index afe68acc..0f8b31d3 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/FineTuningServiceImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/FineTuningServiceImpl.kt @@ -3,10 +3,14 @@ package com.openai.services.blocking import com.openai.core.ClientOptions +import com.openai.services.blocking.finetuning.AlphaService +import com.openai.services.blocking.finetuning.AlphaServiceImpl import com.openai.services.blocking.finetuning.CheckpointService import com.openai.services.blocking.finetuning.CheckpointServiceImpl import com.openai.services.blocking.finetuning.JobService import com.openai.services.blocking.finetuning.JobServiceImpl +import com.openai.services.blocking.finetuning.MethodService +import com.openai.services.blocking.finetuning.MethodServiceImpl class FineTuningServiceImpl internal constructor(private val clientOptions: ClientOptions) : FineTuningService { @@ -15,19 +19,31 @@ class FineTuningServiceImpl internal constructor(private val clientOptions: Clie WithRawResponseImpl(clientOptions) } + private val methods: MethodService by lazy { MethodServiceImpl(clientOptions) } + private val jobs: JobService by lazy { JobServiceImpl(clientOptions) } private val checkpoints: CheckpointService by lazy { CheckpointServiceImpl(clientOptions) } + private val alpha: AlphaService by lazy { AlphaServiceImpl(clientOptions) } + override fun withRawResponse(): FineTuningService.WithRawResponse = withRawResponse + override fun methods(): MethodService = methods + override fun jobs(): JobService = jobs override fun checkpoints(): CheckpointService = checkpoints + override fun alpha(): AlphaService = alpha + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : FineTuningService.WithRawResponse { + private val methods: MethodService.WithRawResponse by lazy { + MethodServiceImpl.WithRawResponseImpl(clientOptions) + } + private val jobs: JobService.WithRawResponse by lazy { JobServiceImpl.WithRawResponseImpl(clientOptions) } @@ -36,8 +52,16 @@ class FineTuningServiceImpl internal constructor(private val clientOptions: Clie CheckpointServiceImpl.WithRawResponseImpl(clientOptions) } + private val alpha: AlphaService.WithRawResponse by lazy { + AlphaServiceImpl.WithRawResponseImpl(clientOptions) + } + + override fun methods(): MethodService.WithRawResponse = methods + override fun jobs(): JobService.WithRawResponse = jobs override fun checkpoints(): CheckpointService.WithRawResponse = checkpoints + + override fun alpha(): AlphaService.WithRawResponse = alpha } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/GraderService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/GraderService.kt new file mode 100644 index 00000000..2c9433a2 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/GraderService.kt @@ -0,0 +1,21 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.services.blocking + +import com.openai.services.blocking.graders.GraderModelService + +interface GraderService { + + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + + fun graderModels(): GraderModelService + + /** A view of [GraderService] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + fun graderModels(): GraderModelService.WithRawResponse + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/GraderServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/GraderServiceImpl.kt new file mode 100644 index 00000000..d6d74305 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/GraderServiceImpl.kt @@ -0,0 +1,31 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.services.blocking + +import com.openai.core.ClientOptions +import com.openai.services.blocking.graders.GraderModelService +import com.openai.services.blocking.graders.GraderModelServiceImpl + +class GraderServiceImpl internal constructor(private val clientOptions: ClientOptions) : + GraderService { + + private val withRawResponse: GraderService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + private val graderModels: GraderModelService by lazy { GraderModelServiceImpl(clientOptions) } + + override fun withRawResponse(): GraderService.WithRawResponse = withRawResponse + + override fun graderModels(): GraderModelService = graderModels + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + GraderService.WithRawResponse { + + private val graderModels: GraderModelService.WithRawResponse by lazy { + GraderModelServiceImpl.WithRawResponseImpl(clientOptions) + } + + override fun graderModels(): GraderModelService.WithRawResponse = graderModels + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/ModelService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/ModelService.kt index 7b34885a..d6550622 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/ModelService.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/ModelService.kt @@ -23,7 +23,18 @@ interface ModelService { * Retrieves a model instance, providing basic information about the model such as the owner and * permissioning. */ - fun retrieve(params: ModelRetrieveParams): Model = retrieve(params, RequestOptions.none()) + fun retrieve(model: String): Model = retrieve(model, ModelRetrieveParams.none()) + + /** @see [retrieve] */ + fun retrieve( + model: String, + params: ModelRetrieveParams = ModelRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): Model = retrieve(params.toBuilder().model(model).build(), requestOptions) + + /** @see [retrieve] */ + fun retrieve(model: String, params: ModelRetrieveParams = ModelRetrieveParams.none()): Model = + retrieve(model, params, RequestOptions.none()) /** @see [retrieve] */ fun retrieve( @@ -31,6 +42,13 @@ interface ModelService { requestOptions: RequestOptions = RequestOptions.none(), ): Model + /** @see [retrieve] */ + fun retrieve(params: ModelRetrieveParams): Model = retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve(model: String, requestOptions: RequestOptions): Model = + retrieve(model, ModelRetrieveParams.none(), requestOptions) + /** * Lists the currently available models, and provides basic information about each one such as * the owner and availability. @@ -55,7 +73,18 @@ interface ModelService { * Delete a fine-tuned model. You must have the Owner role in your organization to delete a * model. */ - fun delete(params: ModelDeleteParams): ModelDeleted = delete(params, RequestOptions.none()) + fun delete(model: String): ModelDeleted = delete(model, ModelDeleteParams.none()) + + /** @see [delete] */ + fun delete( + model: String, + params: ModelDeleteParams = ModelDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): ModelDeleted = delete(params.toBuilder().model(model).build(), requestOptions) + + /** @see [delete] */ + fun delete(model: String, params: ModelDeleteParams = ModelDeleteParams.none()): ModelDeleted = + delete(model, params, RequestOptions.none()) /** @see [delete] */ fun delete( @@ -63,6 +92,13 @@ interface ModelService { requestOptions: RequestOptions = RequestOptions.none(), ): ModelDeleted + /** @see [delete] */ + fun delete(params: ModelDeleteParams): ModelDeleted = delete(params, RequestOptions.none()) + + /** @see [delete] */ + fun delete(model: String, requestOptions: RequestOptions): ModelDeleted = + delete(model, ModelDeleteParams.none(), requestOptions) + /** A view of [ModelService] that provides access to raw HTTP responses for each method. */ interface WithRawResponse { @@ -71,8 +107,24 @@ interface ModelService { * [ModelService.retrieve]. */ @MustBeClosed - fun retrieve(params: ModelRetrieveParams): HttpResponseFor = - retrieve(params, RequestOptions.none()) + fun retrieve(model: String): HttpResponseFor = + retrieve(model, ModelRetrieveParams.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + model: String, + params: ModelRetrieveParams = ModelRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + retrieve(params.toBuilder().model(model).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + model: String, + params: ModelRetrieveParams = ModelRetrieveParams.none(), + ): HttpResponseFor = retrieve(model, params, RequestOptions.none()) /** @see [retrieve] */ @MustBeClosed @@ -81,6 +133,16 @@ interface ModelService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** @see [retrieve] */ + @MustBeClosed + fun retrieve(params: ModelRetrieveParams): HttpResponseFor = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve(model: String, requestOptions: RequestOptions): HttpResponseFor = + retrieve(model, ModelRetrieveParams.none(), requestOptions) + /** * Returns a raw HTTP response for `get /models`, but is otherwise the same as * [ModelService.list]. @@ -109,8 +171,24 @@ interface ModelService { * [ModelService.delete]. */ @MustBeClosed - fun delete(params: ModelDeleteParams): HttpResponseFor = - delete(params, RequestOptions.none()) + fun delete(model: String): HttpResponseFor = + delete(model, ModelDeleteParams.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + model: String, + params: ModelDeleteParams = ModelDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + delete(params.toBuilder().model(model).build(), requestOptions) + + /** @see [delete] */ + @MustBeClosed + fun delete( + model: String, + params: ModelDeleteParams = ModelDeleteParams.none(), + ): HttpResponseFor = delete(model, params, RequestOptions.none()) /** @see [delete] */ @MustBeClosed @@ -118,5 +196,15 @@ interface ModelService { params: ModelDeleteParams, requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + + /** @see [delete] */ + @MustBeClosed + fun delete(params: ModelDeleteParams): HttpResponseFor = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete(model: String, requestOptions: RequestOptions): HttpResponseFor = + delete(model, ModelDeleteParams.none(), requestOptions) } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/ModelServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/ModelServiceImpl.kt index 6e7a023e..7104c2ed 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/ModelServiceImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/ModelServiceImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.blocking import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -22,6 +23,7 @@ import com.openai.models.models.ModelListPage import com.openai.models.models.ModelListPageResponse import com.openai.models.models.ModelListParams import com.openai.models.models.ModelRetrieveParams +import kotlin.jvm.optionals.getOrNull class ModelServiceImpl internal constructor(private val clientOptions: ClientOptions) : ModelService { @@ -56,12 +58,15 @@ class ModelServiceImpl internal constructor(private val clientOptions: ClientOpt params: ModelRetrieveParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("model", params.model().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) .addPathSegments("models", params._pathParam(0)) .build() - .prepare(clientOptions, params, params.model()) + .prepare(clientOptions, params, params.model().get()) val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) val response = clientOptions.httpClient.execute(request, requestOptions) return response.parseable { @@ -116,13 +121,16 @@ class ModelServiceImpl internal constructor(private val clientOptions: ClientOpt params: ModelDeleteParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("model", params.model().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.DELETE) .addPathSegments("models", params._pathParam(0)) .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } .build() - .prepare(clientOptions, params, params.model()) + .prepare(clientOptions, params, params.model().get()) val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) val response = clientOptions.httpClient.execute(request, requestOptions) return response.parseable { diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/ResponseService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/ResponseService.kt index acced25c..b6e1f962 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/ResponseService.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/ResponseService.kt @@ -65,7 +65,20 @@ interface ResponseService { ): StreamResponse /** Retrieves a model response with the given ID. */ - fun retrieve(params: ResponseRetrieveParams): Response = retrieve(params, RequestOptions.none()) + fun retrieve(responseId: String): Response = retrieve(responseId, ResponseRetrieveParams.none()) + + /** @see [retrieve] */ + fun retrieve( + responseId: String, + params: ResponseRetrieveParams = ResponseRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): Response = retrieve(params.toBuilder().responseId(responseId).build(), requestOptions) + + /** @see [retrieve] */ + fun retrieve( + responseId: String, + params: ResponseRetrieveParams = ResponseRetrieveParams.none(), + ): Response = retrieve(responseId, params, RequestOptions.none()) /** @see [retrieve] */ fun retrieve( @@ -73,12 +86,37 @@ interface ResponseService { requestOptions: RequestOptions = RequestOptions.none(), ): Response + /** @see [retrieve] */ + fun retrieve(params: ResponseRetrieveParams): Response = retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve(responseId: String, requestOptions: RequestOptions): Response = + retrieve(responseId, ResponseRetrieveParams.none(), requestOptions) + /** Deletes a model response with the given ID. */ - fun delete(params: ResponseDeleteParams) = delete(params, RequestOptions.none()) + fun delete(responseId: String) = delete(responseId, ResponseDeleteParams.none()) + + /** @see [delete] */ + fun delete( + responseId: String, + params: ResponseDeleteParams = ResponseDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ) = delete(params.toBuilder().responseId(responseId).build(), requestOptions) + + /** @see [delete] */ + fun delete(responseId: String, params: ResponseDeleteParams = ResponseDeleteParams.none()) = + delete(responseId, params, RequestOptions.none()) /** @see [delete] */ fun delete(params: ResponseDeleteParams, requestOptions: RequestOptions = RequestOptions.none()) + /** @see [delete] */ + fun delete(params: ResponseDeleteParams) = delete(params, RequestOptions.none()) + + /** @see [delete] */ + fun delete(responseId: String, requestOptions: RequestOptions) = + delete(responseId, ResponseDeleteParams.none(), requestOptions) + /** A view of [ResponseService] that provides access to raw HTTP responses for each method. */ interface WithRawResponse { @@ -121,8 +159,24 @@ interface ResponseService { * as [ResponseService.retrieve]. */ @MustBeClosed - fun retrieve(params: ResponseRetrieveParams): HttpResponseFor = - retrieve(params, RequestOptions.none()) + fun retrieve(responseId: String): HttpResponseFor = + retrieve(responseId, ResponseRetrieveParams.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + responseId: String, + params: ResponseRetrieveParams = ResponseRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + retrieve(params.toBuilder().responseId(responseId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + responseId: String, + params: ResponseRetrieveParams = ResponseRetrieveParams.none(), + ): HttpResponseFor = retrieve(responseId, params, RequestOptions.none()) /** @see [retrieve] */ @MustBeClosed @@ -131,13 +185,41 @@ interface ResponseService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** @see [retrieve] */ + @MustBeClosed + fun retrieve(params: ResponseRetrieveParams): HttpResponseFor = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + responseId: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + retrieve(responseId, ResponseRetrieveParams.none(), requestOptions) + /** * Returns a raw HTTP response for `delete /responses/{response_id}`, but is otherwise the * same as [ResponseService.delete]. */ @MustBeClosed - fun delete(params: ResponseDeleteParams): HttpResponse = - delete(params, RequestOptions.none()) + fun delete(responseId: String): HttpResponse = + delete(responseId, ResponseDeleteParams.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + responseId: String, + params: ResponseDeleteParams = ResponseDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponse = delete(params.toBuilder().responseId(responseId).build(), requestOptions) + + /** @see [delete] */ + @MustBeClosed + fun delete( + responseId: String, + params: ResponseDeleteParams = ResponseDeleteParams.none(), + ): HttpResponse = delete(responseId, params, RequestOptions.none()) /** @see [delete] */ @MustBeClosed @@ -145,5 +227,15 @@ interface ResponseService { params: ResponseDeleteParams, requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponse + + /** @see [delete] */ + @MustBeClosed + fun delete(params: ResponseDeleteParams): HttpResponse = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete(responseId: String, requestOptions: RequestOptions): HttpResponse = + delete(responseId, ResponseDeleteParams.none(), requestOptions) } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/ResponseServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/ResponseServiceImpl.kt index b683a7d6..de7f11be 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/ResponseServiceImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/ResponseServiceImpl.kt @@ -5,6 +5,7 @@ package com.openai.services.blocking import com.openai.core.ClientOptions import com.openai.core.JsonValue import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.emptyHandler import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler @@ -29,6 +30,7 @@ import com.openai.models.responses.ResponseRetrieveParams import com.openai.models.responses.ResponseStreamEvent import com.openai.services.blocking.responses.InputItemService import com.openai.services.blocking.responses.InputItemServiceImpl +import kotlin.jvm.optionals.getOrNull class ResponseServiceImpl internal constructor(private val clientOptions: ClientOptions) : ResponseService { @@ -151,6 +153,9 @@ class ResponseServiceImpl internal constructor(private val clientOptions: Client params: ResponseRetrieveParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("responseId", params.responseId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -176,6 +181,9 @@ class ResponseServiceImpl internal constructor(private val clientOptions: Client params: ResponseDeleteParams, requestOptions: RequestOptions, ): HttpResponse { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("responseId", params.responseId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.DELETE) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/UploadService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/UploadService.kt index 47938c0e..17bc71b0 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/UploadService.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/UploadService.kt @@ -49,7 +49,18 @@ interface UploadService { ): Upload /** Cancels the Upload. No Parts may be added after an Upload is cancelled. */ - fun cancel(params: UploadCancelParams): Upload = cancel(params, RequestOptions.none()) + fun cancel(uploadId: String): Upload = cancel(uploadId, UploadCancelParams.none()) + + /** @see [cancel] */ + fun cancel( + uploadId: String, + params: UploadCancelParams = UploadCancelParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): Upload = cancel(params.toBuilder().uploadId(uploadId).build(), requestOptions) + + /** @see [cancel] */ + fun cancel(uploadId: String, params: UploadCancelParams = UploadCancelParams.none()): Upload = + cancel(uploadId, params, RequestOptions.none()) /** @see [cancel] */ fun cancel( @@ -57,6 +68,13 @@ interface UploadService { requestOptions: RequestOptions = RequestOptions.none(), ): Upload + /** @see [cancel] */ + fun cancel(params: UploadCancelParams): Upload = cancel(params, RequestOptions.none()) + + /** @see [cancel] */ + fun cancel(uploadId: String, requestOptions: RequestOptions): Upload = + cancel(uploadId, UploadCancelParams.none(), requestOptions) + /** * Completes the [Upload](https://platform.openai.com/docs/api-reference/uploads/object). * @@ -70,6 +88,17 @@ interface UploadService { * specified when creating the Upload object. No Parts may be added after an Upload is * completed. */ + fun complete(uploadId: String, params: UploadCompleteParams): Upload = + complete(uploadId, params, RequestOptions.none()) + + /** @see [complete] */ + fun complete( + uploadId: String, + params: UploadCompleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): Upload = complete(params.toBuilder().uploadId(uploadId).build(), requestOptions) + + /** @see [complete] */ fun complete(params: UploadCompleteParams): Upload = complete(params, RequestOptions.none()) /** @see [complete] */ @@ -103,8 +132,24 @@ interface UploadService { * same as [UploadService.cancel]. */ @MustBeClosed - fun cancel(params: UploadCancelParams): HttpResponseFor = - cancel(params, RequestOptions.none()) + fun cancel(uploadId: String): HttpResponseFor = + cancel(uploadId, UploadCancelParams.none()) + + /** @see [cancel] */ + @MustBeClosed + fun cancel( + uploadId: String, + params: UploadCancelParams = UploadCancelParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + cancel(params.toBuilder().uploadId(uploadId).build(), requestOptions) + + /** @see [cancel] */ + @MustBeClosed + fun cancel( + uploadId: String, + params: UploadCancelParams = UploadCancelParams.none(), + ): HttpResponseFor = cancel(uploadId, params, RequestOptions.none()) /** @see [cancel] */ @MustBeClosed @@ -113,11 +158,35 @@ interface UploadService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** @see [cancel] */ + @MustBeClosed + fun cancel(params: UploadCancelParams): HttpResponseFor = + cancel(params, RequestOptions.none()) + + /** @see [cancel] */ + @MustBeClosed + fun cancel(uploadId: String, requestOptions: RequestOptions): HttpResponseFor = + cancel(uploadId, UploadCancelParams.none(), requestOptions) + /** * Returns a raw HTTP response for `post /uploads/{upload_id}/complete`, but is otherwise * the same as [UploadService.complete]. */ @MustBeClosed + fun complete(uploadId: String, params: UploadCompleteParams): HttpResponseFor = + complete(uploadId, params, RequestOptions.none()) + + /** @see [complete] */ + @MustBeClosed + fun complete( + uploadId: String, + params: UploadCompleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + complete(params.toBuilder().uploadId(uploadId).build(), requestOptions) + + /** @see [complete] */ + @MustBeClosed fun complete(params: UploadCompleteParams): HttpResponseFor = complete(params, RequestOptions.none()) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/UploadServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/UploadServiceImpl.kt index d2841644..6b2d7733 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/UploadServiceImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/UploadServiceImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.blocking import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -21,6 +22,7 @@ import com.openai.models.uploads.UploadCompleteParams import com.openai.models.uploads.UploadCreateParams import com.openai.services.blocking.uploads.PartService import com.openai.services.blocking.uploads.PartServiceImpl +import kotlin.jvm.optionals.getOrNull class UploadServiceImpl internal constructor(private val clientOptions: ClientOptions) : UploadService { @@ -92,6 +94,9 @@ class UploadServiceImpl internal constructor(private val clientOptions: ClientOp params: UploadCancelParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("uploadId", params.uploadId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -119,6 +124,9 @@ class UploadServiceImpl internal constructor(private val clientOptions: ClientOp params: UploadCompleteParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("uploadId", params.uploadId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/VectorStoreService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/VectorStoreService.kt index b61e9ce2..e5256a03 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/VectorStoreService.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/VectorStoreService.kt @@ -47,8 +47,22 @@ interface VectorStoreService { create(VectorStoreCreateParams.none(), requestOptions) /** Retrieves a vector store. */ - fun retrieve(params: VectorStoreRetrieveParams): VectorStore = - retrieve(params, RequestOptions.none()) + fun retrieve(vectorStoreId: String): VectorStore = + retrieve(vectorStoreId, VectorStoreRetrieveParams.none()) + + /** @see [retrieve] */ + fun retrieve( + vectorStoreId: String, + params: VectorStoreRetrieveParams = VectorStoreRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): VectorStore = + retrieve(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) + + /** @see [retrieve] */ + fun retrieve( + vectorStoreId: String, + params: VectorStoreRetrieveParams = VectorStoreRetrieveParams.none(), + ): VectorStore = retrieve(vectorStoreId, params, RequestOptions.none()) /** @see [retrieve] */ fun retrieve( @@ -56,8 +70,30 @@ interface VectorStoreService { requestOptions: RequestOptions = RequestOptions.none(), ): VectorStore + /** @see [retrieve] */ + fun retrieve(params: VectorStoreRetrieveParams): VectorStore = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve(vectorStoreId: String, requestOptions: RequestOptions): VectorStore = + retrieve(vectorStoreId, VectorStoreRetrieveParams.none(), requestOptions) + /** Modifies a vector store. */ - fun update(params: VectorStoreUpdateParams): VectorStore = update(params, RequestOptions.none()) + fun update(vectorStoreId: String): VectorStore = + update(vectorStoreId, VectorStoreUpdateParams.none()) + + /** @see [update] */ + fun update( + vectorStoreId: String, + params: VectorStoreUpdateParams = VectorStoreUpdateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): VectorStore = update(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) + + /** @see [update] */ + fun update( + vectorStoreId: String, + params: VectorStoreUpdateParams = VectorStoreUpdateParams.none(), + ): VectorStore = update(vectorStoreId, params, RequestOptions.none()) /** @see [update] */ fun update( @@ -65,6 +101,13 @@ interface VectorStoreService { requestOptions: RequestOptions = RequestOptions.none(), ): VectorStore + /** @see [update] */ + fun update(params: VectorStoreUpdateParams): VectorStore = update(params, RequestOptions.none()) + + /** @see [update] */ + fun update(vectorStoreId: String, requestOptions: RequestOptions): VectorStore = + update(vectorStoreId, VectorStoreUpdateParams.none(), requestOptions) + /** Returns a list of vector stores. */ fun list(): VectorStoreListPage = list(VectorStoreListParams.none()) @@ -83,8 +126,22 @@ interface VectorStoreService { list(VectorStoreListParams.none(), requestOptions) /** Delete a vector store. */ - fun delete(params: VectorStoreDeleteParams): VectorStoreDeleted = - delete(params, RequestOptions.none()) + fun delete(vectorStoreId: String): VectorStoreDeleted = + delete(vectorStoreId, VectorStoreDeleteParams.none()) + + /** @see [delete] */ + fun delete( + vectorStoreId: String, + params: VectorStoreDeleteParams = VectorStoreDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): VectorStoreDeleted = + delete(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) + + /** @see [delete] */ + fun delete( + vectorStoreId: String, + params: VectorStoreDeleteParams = VectorStoreDeleteParams.none(), + ): VectorStoreDeleted = delete(vectorStoreId, params, RequestOptions.none()) /** @see [delete] */ fun delete( @@ -92,7 +149,27 @@ interface VectorStoreService { requestOptions: RequestOptions = RequestOptions.none(), ): VectorStoreDeleted + /** @see [delete] */ + fun delete(params: VectorStoreDeleteParams): VectorStoreDeleted = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + fun delete(vectorStoreId: String, requestOptions: RequestOptions): VectorStoreDeleted = + delete(vectorStoreId, VectorStoreDeleteParams.none(), requestOptions) + /** Search a vector store for relevant chunks based on a query and file attributes filter. */ + fun search(vectorStoreId: String, params: VectorStoreSearchParams): VectorStoreSearchPage = + search(vectorStoreId, params, RequestOptions.none()) + + /** @see [search] */ + fun search( + vectorStoreId: String, + params: VectorStoreSearchParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): VectorStoreSearchPage = + search(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) + + /** @see [search] */ fun search(params: VectorStoreSearchParams): VectorStoreSearchPage = search(params, RequestOptions.none()) @@ -141,8 +218,24 @@ interface VectorStoreService { * the same as [VectorStoreService.retrieve]. */ @MustBeClosed - fun retrieve(params: VectorStoreRetrieveParams): HttpResponseFor = - retrieve(params, RequestOptions.none()) + fun retrieve(vectorStoreId: String): HttpResponseFor = + retrieve(vectorStoreId, VectorStoreRetrieveParams.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + vectorStoreId: String, + params: VectorStoreRetrieveParams = VectorStoreRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + retrieve(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + vectorStoreId: String, + params: VectorStoreRetrieveParams = VectorStoreRetrieveParams.none(), + ): HttpResponseFor = retrieve(vectorStoreId, params, RequestOptions.none()) /** @see [retrieve] */ @MustBeClosed @@ -151,13 +244,42 @@ interface VectorStoreService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** @see [retrieve] */ + @MustBeClosed + fun retrieve(params: VectorStoreRetrieveParams): HttpResponseFor = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + vectorStoreId: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + retrieve(vectorStoreId, VectorStoreRetrieveParams.none(), requestOptions) + /** * Returns a raw HTTP response for `post /vector_stores/{vector_store_id}`, but is otherwise * the same as [VectorStoreService.update]. */ @MustBeClosed - fun update(params: VectorStoreUpdateParams): HttpResponseFor = - update(params, RequestOptions.none()) + fun update(vectorStoreId: String): HttpResponseFor = + update(vectorStoreId, VectorStoreUpdateParams.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + vectorStoreId: String, + params: VectorStoreUpdateParams = VectorStoreUpdateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + update(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) + + /** @see [update] */ + @MustBeClosed + fun update( + vectorStoreId: String, + params: VectorStoreUpdateParams = VectorStoreUpdateParams.none(), + ): HttpResponseFor = update(vectorStoreId, params, RequestOptions.none()) /** @see [update] */ @MustBeClosed @@ -166,6 +288,19 @@ interface VectorStoreService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** @see [update] */ + @MustBeClosed + fun update(params: VectorStoreUpdateParams): HttpResponseFor = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + vectorStoreId: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + update(vectorStoreId, VectorStoreUpdateParams.none(), requestOptions) + /** * Returns a raw HTTP response for `get /vector_stores`, but is otherwise the same as * [VectorStoreService.list]. @@ -196,8 +331,25 @@ interface VectorStoreService { * otherwise the same as [VectorStoreService.delete]. */ @MustBeClosed - fun delete(params: VectorStoreDeleteParams): HttpResponseFor = - delete(params, RequestOptions.none()) + fun delete(vectorStoreId: String): HttpResponseFor = + delete(vectorStoreId, VectorStoreDeleteParams.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + vectorStoreId: String, + params: VectorStoreDeleteParams = VectorStoreDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + delete(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) + + /** @see [delete] */ + @MustBeClosed + fun delete( + vectorStoreId: String, + params: VectorStoreDeleteParams = VectorStoreDeleteParams.none(), + ): HttpResponseFor = + delete(vectorStoreId, params, RequestOptions.none()) /** @see [delete] */ @MustBeClosed @@ -206,11 +358,41 @@ interface VectorStoreService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** @see [delete] */ + @MustBeClosed + fun delete(params: VectorStoreDeleteParams): HttpResponseFor = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + vectorStoreId: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + delete(vectorStoreId, VectorStoreDeleteParams.none(), requestOptions) + /** * Returns a raw HTTP response for `post /vector_stores/{vector_store_id}/search`, but is * otherwise the same as [VectorStoreService.search]. */ @MustBeClosed + fun search( + vectorStoreId: String, + params: VectorStoreSearchParams, + ): HttpResponseFor = + search(vectorStoreId, params, RequestOptions.none()) + + /** @see [search] */ + @MustBeClosed + fun search( + vectorStoreId: String, + params: VectorStoreSearchParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + search(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) + + /** @see [search] */ + @MustBeClosed fun search(params: VectorStoreSearchParams): HttpResponseFor = search(params, RequestOptions.none()) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/VectorStoreServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/VectorStoreServiceImpl.kt index 5a077091..89327679 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/VectorStoreServiceImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/VectorStoreServiceImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.blocking import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -32,6 +33,7 @@ import com.openai.services.blocking.vectorstores.FileBatchService import com.openai.services.blocking.vectorstores.FileBatchServiceImpl import com.openai.services.blocking.vectorstores.FileService import com.openai.services.blocking.vectorstores.FileServiceImpl +import kotlin.jvm.optionals.getOrNull class VectorStoreServiceImpl internal constructor(private val clientOptions: ClientOptions) : VectorStoreService { @@ -149,6 +151,9 @@ class VectorStoreServiceImpl internal constructor(private val clientOptions: Cli params: VectorStoreRetrieveParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("vectorStoreId", params.vectorStoreId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -176,6 +181,9 @@ class VectorStoreServiceImpl internal constructor(private val clientOptions: Cli params: VectorStoreUpdateParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("vectorStoreId", params.vectorStoreId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -239,6 +247,9 @@ class VectorStoreServiceImpl internal constructor(private val clientOptions: Cli params: VectorStoreDeleteParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("vectorStoreId", params.vectorStoreId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.DELETE) @@ -268,6 +279,9 @@ class VectorStoreServiceImpl internal constructor(private val clientOptions: Cli params: VectorStoreSearchParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("vectorStoreId", params.vectorStoreId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/AssistantService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/AssistantService.kt index 2943bace..98d5e195 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/AssistantService.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/AssistantService.kt @@ -31,8 +31,21 @@ interface AssistantService { ): Assistant /** Retrieves an assistant. */ - fun retrieve(params: AssistantRetrieveParams): Assistant = - retrieve(params, RequestOptions.none()) + fun retrieve(assistantId: String): Assistant = + retrieve(assistantId, AssistantRetrieveParams.none()) + + /** @see [retrieve] */ + fun retrieve( + assistantId: String, + params: AssistantRetrieveParams = AssistantRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): Assistant = retrieve(params.toBuilder().assistantId(assistantId).build(), requestOptions) + + /** @see [retrieve] */ + fun retrieve( + assistantId: String, + params: AssistantRetrieveParams = AssistantRetrieveParams.none(), + ): Assistant = retrieve(assistantId, params, RequestOptions.none()) /** @see [retrieve] */ fun retrieve( @@ -40,8 +53,29 @@ interface AssistantService { requestOptions: RequestOptions = RequestOptions.none(), ): Assistant + /** @see [retrieve] */ + fun retrieve(params: AssistantRetrieveParams): Assistant = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve(assistantId: String, requestOptions: RequestOptions): Assistant = + retrieve(assistantId, AssistantRetrieveParams.none(), requestOptions) + /** Modifies an assistant. */ - fun update(params: AssistantUpdateParams): Assistant = update(params, RequestOptions.none()) + fun update(assistantId: String): Assistant = update(assistantId, AssistantUpdateParams.none()) + + /** @see [update] */ + fun update( + assistantId: String, + params: AssistantUpdateParams = AssistantUpdateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): Assistant = update(params.toBuilder().assistantId(assistantId).build(), requestOptions) + + /** @see [update] */ + fun update( + assistantId: String, + params: AssistantUpdateParams = AssistantUpdateParams.none(), + ): Assistant = update(assistantId, params, RequestOptions.none()) /** @see [update] */ fun update( @@ -49,6 +83,13 @@ interface AssistantService { requestOptions: RequestOptions = RequestOptions.none(), ): Assistant + /** @see [update] */ + fun update(params: AssistantUpdateParams): Assistant = update(params, RequestOptions.none()) + + /** @see [update] */ + fun update(assistantId: String, requestOptions: RequestOptions): Assistant = + update(assistantId, AssistantUpdateParams.none(), requestOptions) + /** Returns a list of assistants. */ fun list(): AssistantListPage = list(AssistantListParams.none()) @@ -67,8 +108,22 @@ interface AssistantService { list(AssistantListParams.none(), requestOptions) /** Delete an assistant. */ - fun delete(params: AssistantDeleteParams): AssistantDeleted = - delete(params, RequestOptions.none()) + fun delete(assistantId: String): AssistantDeleted = + delete(assistantId, AssistantDeleteParams.none()) + + /** @see [delete] */ + fun delete( + assistantId: String, + params: AssistantDeleteParams = AssistantDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): AssistantDeleted = + delete(params.toBuilder().assistantId(assistantId).build(), requestOptions) + + /** @see [delete] */ + fun delete( + assistantId: String, + params: AssistantDeleteParams = AssistantDeleteParams.none(), + ): AssistantDeleted = delete(assistantId, params, RequestOptions.none()) /** @see [delete] */ fun delete( @@ -76,6 +131,14 @@ interface AssistantService { requestOptions: RequestOptions = RequestOptions.none(), ): AssistantDeleted + /** @see [delete] */ + fun delete(params: AssistantDeleteParams): AssistantDeleted = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + fun delete(assistantId: String, requestOptions: RequestOptions): AssistantDeleted = + delete(assistantId, AssistantDeleteParams.none(), requestOptions) + /** A view of [AssistantService] that provides access to raw HTTP responses for each method. */ interface WithRawResponse { @@ -99,8 +162,24 @@ interface AssistantService { * same as [AssistantService.retrieve]. */ @MustBeClosed - fun retrieve(params: AssistantRetrieveParams): HttpResponseFor = - retrieve(params, RequestOptions.none()) + fun retrieve(assistantId: String): HttpResponseFor = + retrieve(assistantId, AssistantRetrieveParams.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + assistantId: String, + params: AssistantRetrieveParams = AssistantRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + retrieve(params.toBuilder().assistantId(assistantId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + assistantId: String, + params: AssistantRetrieveParams = AssistantRetrieveParams.none(), + ): HttpResponseFor = retrieve(assistantId, params, RequestOptions.none()) /** @see [retrieve] */ @MustBeClosed @@ -109,13 +188,42 @@ interface AssistantService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** @see [retrieve] */ + @MustBeClosed + fun retrieve(params: AssistantRetrieveParams): HttpResponseFor = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + assistantId: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + retrieve(assistantId, AssistantRetrieveParams.none(), requestOptions) + /** * Returns a raw HTTP response for `post /assistants/{assistant_id}`, but is otherwise the * same as [AssistantService.update]. */ @MustBeClosed - fun update(params: AssistantUpdateParams): HttpResponseFor = - update(params, RequestOptions.none()) + fun update(assistantId: String): HttpResponseFor = + update(assistantId, AssistantUpdateParams.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + assistantId: String, + params: AssistantUpdateParams = AssistantUpdateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + update(params.toBuilder().assistantId(assistantId).build(), requestOptions) + + /** @see [update] */ + @MustBeClosed + fun update( + assistantId: String, + params: AssistantUpdateParams = AssistantUpdateParams.none(), + ): HttpResponseFor = update(assistantId, params, RequestOptions.none()) /** @see [update] */ @MustBeClosed @@ -124,6 +232,19 @@ interface AssistantService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** @see [update] */ + @MustBeClosed + fun update(params: AssistantUpdateParams): HttpResponseFor = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + assistantId: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + update(assistantId, AssistantUpdateParams.none(), requestOptions) + /** * Returns a raw HTTP response for `get /assistants`, but is otherwise the same as * [AssistantService.list]. @@ -154,8 +275,24 @@ interface AssistantService { * same as [AssistantService.delete]. */ @MustBeClosed - fun delete(params: AssistantDeleteParams): HttpResponseFor = - delete(params, RequestOptions.none()) + fun delete(assistantId: String): HttpResponseFor = + delete(assistantId, AssistantDeleteParams.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + assistantId: String, + params: AssistantDeleteParams = AssistantDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + delete(params.toBuilder().assistantId(assistantId).build(), requestOptions) + + /** @see [delete] */ + @MustBeClosed + fun delete( + assistantId: String, + params: AssistantDeleteParams = AssistantDeleteParams.none(), + ): HttpResponseFor = delete(assistantId, params, RequestOptions.none()) /** @see [delete] */ @MustBeClosed @@ -163,5 +300,18 @@ interface AssistantService { params: AssistantDeleteParams, requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + + /** @see [delete] */ + @MustBeClosed + fun delete(params: AssistantDeleteParams): HttpResponseFor = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + assistantId: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + delete(assistantId, AssistantDeleteParams.none(), requestOptions) } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/AssistantServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/AssistantServiceImpl.kt index 521543aa..30ca6d1b 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/AssistantServiceImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/AssistantServiceImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.blocking.beta import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -25,6 +26,7 @@ import com.openai.models.beta.assistants.AssistantListPageResponse import com.openai.models.beta.assistants.AssistantListParams import com.openai.models.beta.assistants.AssistantRetrieveParams import com.openai.models.beta.assistants.AssistantUpdateParams +import kotlin.jvm.optionals.getOrNull class AssistantServiceImpl internal constructor(private val clientOptions: ClientOptions) : AssistantService { @@ -109,6 +111,9 @@ class AssistantServiceImpl internal constructor(private val clientOptions: Clien params: AssistantRetrieveParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("assistantId", params.assistantId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -136,6 +141,9 @@ class AssistantServiceImpl internal constructor(private val clientOptions: Clien params: AssistantUpdateParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("assistantId", params.assistantId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -203,6 +211,9 @@ class AssistantServiceImpl internal constructor(private val clientOptions: Clien params: AssistantDeleteParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("assistantId", params.assistantId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.DELETE) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/ThreadService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/ThreadService.kt index 8263aa93..a3626111 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/ThreadService.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/ThreadService.kt @@ -47,7 +47,20 @@ interface ThreadService { create(ThreadCreateParams.none(), requestOptions) /** Retrieves a thread. */ - fun retrieve(params: ThreadRetrieveParams): Thread = retrieve(params, RequestOptions.none()) + fun retrieve(threadId: String): Thread = retrieve(threadId, ThreadRetrieveParams.none()) + + /** @see [retrieve] */ + fun retrieve( + threadId: String, + params: ThreadRetrieveParams = ThreadRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): Thread = retrieve(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [retrieve] */ + fun retrieve( + threadId: String, + params: ThreadRetrieveParams = ThreadRetrieveParams.none(), + ): Thread = retrieve(threadId, params, RequestOptions.none()) /** @see [retrieve] */ fun retrieve( @@ -55,8 +68,26 @@ interface ThreadService { requestOptions: RequestOptions = RequestOptions.none(), ): Thread + /** @see [retrieve] */ + fun retrieve(params: ThreadRetrieveParams): Thread = retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve(threadId: String, requestOptions: RequestOptions): Thread = + retrieve(threadId, ThreadRetrieveParams.none(), requestOptions) + /** Modifies a thread. */ - fun update(params: ThreadUpdateParams): Thread = update(params, RequestOptions.none()) + fun update(threadId: String): Thread = update(threadId, ThreadUpdateParams.none()) + + /** @see [update] */ + fun update( + threadId: String, + params: ThreadUpdateParams = ThreadUpdateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): Thread = update(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [update] */ + fun update(threadId: String, params: ThreadUpdateParams = ThreadUpdateParams.none()): Thread = + update(threadId, params, RequestOptions.none()) /** @see [update] */ fun update( @@ -64,8 +95,28 @@ interface ThreadService { requestOptions: RequestOptions = RequestOptions.none(), ): Thread + /** @see [update] */ + fun update(params: ThreadUpdateParams): Thread = update(params, RequestOptions.none()) + + /** @see [update] */ + fun update(threadId: String, requestOptions: RequestOptions): Thread = + update(threadId, ThreadUpdateParams.none(), requestOptions) + /** Delete a thread. */ - fun delete(params: ThreadDeleteParams): ThreadDeleted = delete(params, RequestOptions.none()) + fun delete(threadId: String): ThreadDeleted = delete(threadId, ThreadDeleteParams.none()) + + /** @see [delete] */ + fun delete( + threadId: String, + params: ThreadDeleteParams = ThreadDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): ThreadDeleted = delete(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [delete] */ + fun delete( + threadId: String, + params: ThreadDeleteParams = ThreadDeleteParams.none(), + ): ThreadDeleted = delete(threadId, params, RequestOptions.none()) /** @see [delete] */ fun delete( @@ -73,6 +124,13 @@ interface ThreadService { requestOptions: RequestOptions = RequestOptions.none(), ): ThreadDeleted + /** @see [delete] */ + fun delete(params: ThreadDeleteParams): ThreadDeleted = delete(params, RequestOptions.none()) + + /** @see [delete] */ + fun delete(threadId: String, requestOptions: RequestOptions): ThreadDeleted = + delete(threadId, ThreadDeleteParams.none(), requestOptions) + /** Create a thread and run it in one request. */ fun createAndRun(params: ThreadCreateAndRunParams): Run = createAndRun(params, RequestOptions.none()) @@ -132,8 +190,24 @@ interface ThreadService { * [ThreadService.retrieve]. */ @MustBeClosed - fun retrieve(params: ThreadRetrieveParams): HttpResponseFor = - retrieve(params, RequestOptions.none()) + fun retrieve(threadId: String): HttpResponseFor = + retrieve(threadId, ThreadRetrieveParams.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + threadId: String, + params: ThreadRetrieveParams = ThreadRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + retrieve(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + threadId: String, + params: ThreadRetrieveParams = ThreadRetrieveParams.none(), + ): HttpResponseFor = retrieve(threadId, params, RequestOptions.none()) /** @see [retrieve] */ @MustBeClosed @@ -142,13 +216,39 @@ interface ThreadService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** @see [retrieve] */ + @MustBeClosed + fun retrieve(params: ThreadRetrieveParams): HttpResponseFor = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve(threadId: String, requestOptions: RequestOptions): HttpResponseFor = + retrieve(threadId, ThreadRetrieveParams.none(), requestOptions) + /** * Returns a raw HTTP response for `post /threads/{thread_id}`, but is otherwise the same as * [ThreadService.update]. */ @MustBeClosed - fun update(params: ThreadUpdateParams): HttpResponseFor = - update(params, RequestOptions.none()) + fun update(threadId: String): HttpResponseFor = + update(threadId, ThreadUpdateParams.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + threadId: String, + params: ThreadUpdateParams = ThreadUpdateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + update(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [update] */ + @MustBeClosed + fun update( + threadId: String, + params: ThreadUpdateParams = ThreadUpdateParams.none(), + ): HttpResponseFor = update(threadId, params, RequestOptions.none()) /** @see [update] */ @MustBeClosed @@ -157,13 +257,39 @@ interface ThreadService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** @see [update] */ + @MustBeClosed + fun update(params: ThreadUpdateParams): HttpResponseFor = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update(threadId: String, requestOptions: RequestOptions): HttpResponseFor = + update(threadId, ThreadUpdateParams.none(), requestOptions) + /** * Returns a raw HTTP response for `delete /threads/{thread_id}`, but is otherwise the same * as [ThreadService.delete]. */ @MustBeClosed - fun delete(params: ThreadDeleteParams): HttpResponseFor = - delete(params, RequestOptions.none()) + fun delete(threadId: String): HttpResponseFor = + delete(threadId, ThreadDeleteParams.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + threadId: String, + params: ThreadDeleteParams = ThreadDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + delete(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [delete] */ + @MustBeClosed + fun delete( + threadId: String, + params: ThreadDeleteParams = ThreadDeleteParams.none(), + ): HttpResponseFor = delete(threadId, params, RequestOptions.none()) /** @see [delete] */ @MustBeClosed @@ -172,6 +298,19 @@ interface ThreadService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** @see [delete] */ + @MustBeClosed + fun delete(params: ThreadDeleteParams): HttpResponseFor = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + threadId: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + delete(threadId, ThreadDeleteParams.none(), requestOptions) + /** * Returns a raw HTTP response for `post /threads/runs`, but is otherwise the same as * [ThreadService.createAndRun]. diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/ThreadServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/ThreadServiceImpl.kt index 5d7ec922..fa03e9bd 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/ThreadServiceImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/ThreadServiceImpl.kt @@ -5,6 +5,7 @@ package com.openai.services.blocking.beta import com.openai.core.ClientOptions import com.openai.core.JsonValue import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.mapJson @@ -34,6 +35,7 @@ import com.openai.services.blocking.beta.threads.MessageService import com.openai.services.blocking.beta.threads.MessageServiceImpl import com.openai.services.blocking.beta.threads.RunService import com.openai.services.blocking.beta.threads.RunServiceImpl +import kotlin.jvm.optionals.getOrNull class ThreadServiceImpl internal constructor(private val clientOptions: ClientOptions) : ThreadService { @@ -139,6 +141,9 @@ class ThreadServiceImpl internal constructor(private val clientOptions: ClientOp params: ThreadRetrieveParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("threadId", params.threadId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -166,6 +171,9 @@ class ThreadServiceImpl internal constructor(private val clientOptions: ClientOp params: ThreadUpdateParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("threadId", params.threadId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -194,6 +202,9 @@ class ThreadServiceImpl internal constructor(private val clientOptions: ClientOp params: ThreadDeleteParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("threadId", params.threadId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.DELETE) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/threads/MessageService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/threads/MessageService.kt index 87184f95..86e7ea88 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/threads/MessageService.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/threads/MessageService.kt @@ -22,6 +22,17 @@ interface MessageService { fun withRawResponse(): WithRawResponse /** Create a message. */ + fun create(threadId: String, params: MessageCreateParams): Message = + create(threadId, params, RequestOptions.none()) + + /** @see [create] */ + fun create( + threadId: String, + params: MessageCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): Message = create(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [create] */ fun create(params: MessageCreateParams): Message = create(params, RequestOptions.none()) /** @see [create] */ @@ -31,6 +42,17 @@ interface MessageService { ): Message /** Retrieve a message. */ + fun retrieve(messageId: String, params: MessageRetrieveParams): Message = + retrieve(messageId, params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve( + messageId: String, + params: MessageRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): Message = retrieve(params.toBuilder().messageId(messageId).build(), requestOptions) + + /** @see [retrieve] */ fun retrieve(params: MessageRetrieveParams): Message = retrieve(params, RequestOptions.none()) /** @see [retrieve] */ @@ -40,6 +62,17 @@ interface MessageService { ): Message /** Modifies a message. */ + fun update(messageId: String, params: MessageUpdateParams): Message = + update(messageId, params, RequestOptions.none()) + + /** @see [update] */ + fun update( + messageId: String, + params: MessageUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): Message = update(params.toBuilder().messageId(messageId).build(), requestOptions) + + /** @see [update] */ fun update(params: MessageUpdateParams): Message = update(params, RequestOptions.none()) /** @see [update] */ @@ -49,7 +82,20 @@ interface MessageService { ): Message /** Returns a list of messages for a given thread. */ - fun list(params: MessageListParams): MessageListPage = list(params, RequestOptions.none()) + fun list(threadId: String): MessageListPage = list(threadId, MessageListParams.none()) + + /** @see [list] */ + fun list( + threadId: String, + params: MessageListParams = MessageListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): MessageListPage = list(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [list] */ + fun list( + threadId: String, + params: MessageListParams = MessageListParams.none(), + ): MessageListPage = list(threadId, params, RequestOptions.none()) /** @see [list] */ fun list( @@ -57,7 +103,25 @@ interface MessageService { requestOptions: RequestOptions = RequestOptions.none(), ): MessageListPage + /** @see [list] */ + fun list(params: MessageListParams): MessageListPage = list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(threadId: String, requestOptions: RequestOptions): MessageListPage = + list(threadId, MessageListParams.none(), requestOptions) + /** Deletes a message. */ + fun delete(messageId: String, params: MessageDeleteParams): MessageDeleted = + delete(messageId, params, RequestOptions.none()) + + /** @see [delete] */ + fun delete( + messageId: String, + params: MessageDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): MessageDeleted = delete(params.toBuilder().messageId(messageId).build(), requestOptions) + + /** @see [delete] */ fun delete(params: MessageDeleteParams): MessageDeleted = delete(params, RequestOptions.none()) /** @see [delete] */ @@ -74,6 +138,20 @@ interface MessageService { * the same as [MessageService.create]. */ @MustBeClosed + fun create(threadId: String, params: MessageCreateParams): HttpResponseFor = + create(threadId, params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + threadId: String, + params: MessageCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + create(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [create] */ + @MustBeClosed fun create(params: MessageCreateParams): HttpResponseFor = create(params, RequestOptions.none()) @@ -89,6 +167,20 @@ interface MessageService { * otherwise the same as [MessageService.retrieve]. */ @MustBeClosed + fun retrieve(messageId: String, params: MessageRetrieveParams): HttpResponseFor = + retrieve(messageId, params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + messageId: String, + params: MessageRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + retrieve(params.toBuilder().messageId(messageId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed fun retrieve(params: MessageRetrieveParams): HttpResponseFor = retrieve(params, RequestOptions.none()) @@ -104,6 +196,20 @@ interface MessageService { * otherwise the same as [MessageService.update]. */ @MustBeClosed + fun update(messageId: String, params: MessageUpdateParams): HttpResponseFor = + update(messageId, params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + messageId: String, + params: MessageUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + update(params.toBuilder().messageId(messageId).build(), requestOptions) + + /** @see [update] */ + @MustBeClosed fun update(params: MessageUpdateParams): HttpResponseFor = update(params, RequestOptions.none()) @@ -119,8 +225,24 @@ interface MessageService { * same as [MessageService.list]. */ @MustBeClosed - fun list(params: MessageListParams): HttpResponseFor = - list(params, RequestOptions.none()) + fun list(threadId: String): HttpResponseFor = + list(threadId, MessageListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + threadId: String, + params: MessageListParams = MessageListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + list(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [list] */ + @MustBeClosed + fun list( + threadId: String, + params: MessageListParams = MessageListParams.none(), + ): HttpResponseFor = list(threadId, params, RequestOptions.none()) /** @see [list] */ @MustBeClosed @@ -129,11 +251,40 @@ interface MessageService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** @see [list] */ + @MustBeClosed + fun list(params: MessageListParams): HttpResponseFor = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + threadId: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + list(threadId, MessageListParams.none(), requestOptions) + /** * Returns a raw HTTP response for `delete /threads/{thread_id}/messages/{message_id}`, but * is otherwise the same as [MessageService.delete]. */ @MustBeClosed + fun delete( + messageId: String, + params: MessageDeleteParams, + ): HttpResponseFor = delete(messageId, params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + messageId: String, + params: MessageDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + delete(params.toBuilder().messageId(messageId).build(), requestOptions) + + /** @see [delete] */ + @MustBeClosed fun delete(params: MessageDeleteParams): HttpResponseFor = delete(params, RequestOptions.none()) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/threads/MessageServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/threads/MessageServiceImpl.kt index fddd1451..83e8bc6c 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/threads/MessageServiceImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/threads/MessageServiceImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.blocking.beta.threads import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -25,6 +26,7 @@ import com.openai.models.beta.threads.messages.MessageListPageResponse import com.openai.models.beta.threads.messages.MessageListParams import com.openai.models.beta.threads.messages.MessageRetrieveParams import com.openai.models.beta.threads.messages.MessageUpdateParams +import kotlin.jvm.optionals.getOrNull class MessageServiceImpl internal constructor(private val clientOptions: ClientOptions) : MessageService { @@ -75,6 +77,9 @@ class MessageServiceImpl internal constructor(private val clientOptions: ClientO params: MessageCreateParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("threadId", params.threadId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -103,6 +108,9 @@ class MessageServiceImpl internal constructor(private val clientOptions: ClientO params: MessageRetrieveParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("messageId", params.messageId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -135,6 +143,9 @@ class MessageServiceImpl internal constructor(private val clientOptions: ClientO params: MessageUpdateParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("messageId", params.messageId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -169,6 +180,9 @@ class MessageServiceImpl internal constructor(private val clientOptions: ClientO params: MessageListParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("threadId", params.threadId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -203,6 +217,9 @@ class MessageServiceImpl internal constructor(private val clientOptions: ClientO params: MessageDeleteParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("messageId", params.messageId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.DELETE) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/threads/RunService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/threads/RunService.kt index 02562d7e..0708353b 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/threads/RunService.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/threads/RunService.kt @@ -27,6 +27,17 @@ interface RunService { fun steps(): StepService /** Create a run. */ + fun create(threadId: String, params: RunCreateParams): Run = + create(threadId, params, RequestOptions.none()) + + /** @see [create] */ + fun create( + threadId: String, + params: RunCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): Run = create(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [create] */ fun create(params: RunCreateParams): Run = create(params, RequestOptions.none()) /** @see [create] */ @@ -34,6 +45,23 @@ interface RunService { /** Create a run. */ @MustBeClosed + fun createStreaming( + threadId: String, + params: RunCreateParams, + ): StreamResponse = + createStreaming(threadId, params, RequestOptions.none()) + + /** @see [createStreaming] */ + @MustBeClosed + fun createStreaming( + threadId: String, + params: RunCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): StreamResponse = + createStreaming(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [createStreaming] */ + @MustBeClosed fun createStreaming(params: RunCreateParams): StreamResponse = createStreaming(params, RequestOptions.none()) @@ -45,6 +73,17 @@ interface RunService { ): StreamResponse /** Retrieves a run. */ + fun retrieve(runId: String, params: RunRetrieveParams): Run = + retrieve(runId, params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve( + runId: String, + params: RunRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): Run = retrieve(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [retrieve] */ fun retrieve(params: RunRetrieveParams): Run = retrieve(params, RequestOptions.none()) /** @see [retrieve] */ @@ -54,13 +93,35 @@ interface RunService { ): Run /** Modifies a run. */ + fun update(runId: String, params: RunUpdateParams): Run = + update(runId, params, RequestOptions.none()) + + /** @see [update] */ + fun update( + runId: String, + params: RunUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): Run = update(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [update] */ fun update(params: RunUpdateParams): Run = update(params, RequestOptions.none()) /** @see [update] */ fun update(params: RunUpdateParams, requestOptions: RequestOptions = RequestOptions.none()): Run /** Returns a list of runs belonging to a thread. */ - fun list(params: RunListParams): RunListPage = list(params, RequestOptions.none()) + fun list(threadId: String): RunListPage = list(threadId, RunListParams.none()) + + /** @see [list] */ + fun list( + threadId: String, + params: RunListParams = RunListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): RunListPage = list(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [list] */ + fun list(threadId: String, params: RunListParams = RunListParams.none()): RunListPage = + list(threadId, params, RequestOptions.none()) /** @see [list] */ fun list( @@ -68,7 +129,25 @@ interface RunService { requestOptions: RequestOptions = RequestOptions.none(), ): RunListPage + /** @see [list] */ + fun list(params: RunListParams): RunListPage = list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(threadId: String, requestOptions: RequestOptions): RunListPage = + list(threadId, RunListParams.none(), requestOptions) + /** Cancels a run that is `in_progress`. */ + fun cancel(runId: String, params: RunCancelParams): Run = + cancel(runId, params, RequestOptions.none()) + + /** @see [cancel] */ + fun cancel( + runId: String, + params: RunCancelParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): Run = cancel(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [cancel] */ fun cancel(params: RunCancelParams): Run = cancel(params, RequestOptions.none()) /** @see [cancel] */ @@ -79,6 +158,17 @@ interface RunService { * `submit_tool_outputs`, this endpoint can be used to submit the outputs from the tool calls * once they're all completed. All outputs must be submitted in a single request. */ + fun submitToolOutputs(runId: String, params: RunSubmitToolOutputsParams): Run = + submitToolOutputs(runId, params, RequestOptions.none()) + + /** @see [submitToolOutputs] */ + fun submitToolOutputs( + runId: String, + params: RunSubmitToolOutputsParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): Run = submitToolOutputs(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [submitToolOutputs] */ fun submitToolOutputs(params: RunSubmitToolOutputsParams): Run = submitToolOutputs(params, RequestOptions.none()) @@ -94,6 +184,23 @@ interface RunService { * once they're all completed. All outputs must be submitted in a single request. */ @MustBeClosed + fun submitToolOutputsStreaming( + runId: String, + params: RunSubmitToolOutputsParams, + ): StreamResponse = + submitToolOutputsStreaming(runId, params, RequestOptions.none()) + + /** @see [submitToolOutputsStreaming] */ + @MustBeClosed + fun submitToolOutputsStreaming( + runId: String, + params: RunSubmitToolOutputsParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): StreamResponse = + submitToolOutputsStreaming(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [submitToolOutputsStreaming] */ + @MustBeClosed fun submitToolOutputsStreaming( params: RunSubmitToolOutputsParams ): StreamResponse = @@ -116,6 +223,20 @@ interface RunService { * same as [RunService.create]. */ @MustBeClosed + fun create(threadId: String, params: RunCreateParams): HttpResponseFor = + create(threadId, params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + threadId: String, + params: RunCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + create(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [create] */ + @MustBeClosed fun create(params: RunCreateParams): HttpResponseFor = create(params, RequestOptions.none()) @@ -131,6 +252,23 @@ interface RunService { * same as [RunService.createStreaming]. */ @MustBeClosed + fun createStreaming( + threadId: String, + params: RunCreateParams, + ): HttpResponseFor> = + createStreaming(threadId, params, RequestOptions.none()) + + /** @see [createStreaming] */ + @MustBeClosed + fun createStreaming( + threadId: String, + params: RunCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor> = + createStreaming(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [createStreaming] */ + @MustBeClosed fun createStreaming( params: RunCreateParams ): HttpResponseFor> = @@ -148,6 +286,19 @@ interface RunService { * otherwise the same as [RunService.retrieve]. */ @MustBeClosed + fun retrieve(runId: String, params: RunRetrieveParams): HttpResponseFor = + retrieve(runId, params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + runId: String, + params: RunRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = retrieve(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed fun retrieve(params: RunRetrieveParams): HttpResponseFor = retrieve(params, RequestOptions.none()) @@ -163,6 +314,19 @@ interface RunService { * otherwise the same as [RunService.update]. */ @MustBeClosed + fun update(runId: String, params: RunUpdateParams): HttpResponseFor = + update(runId, params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + runId: String, + params: RunUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = update(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [update] */ + @MustBeClosed fun update(params: RunUpdateParams): HttpResponseFor = update(params, RequestOptions.none()) @@ -178,8 +342,24 @@ interface RunService { * same as [RunService.list]. */ @MustBeClosed - fun list(params: RunListParams): HttpResponseFor = - list(params, RequestOptions.none()) + fun list(threadId: String): HttpResponseFor = + list(threadId, RunListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + threadId: String, + params: RunListParams = RunListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + list(params.toBuilder().threadId(threadId).build(), requestOptions) + + /** @see [list] */ + @MustBeClosed + fun list( + threadId: String, + params: RunListParams = RunListParams.none(), + ): HttpResponseFor = list(threadId, params, RequestOptions.none()) /** @see [list] */ @MustBeClosed @@ -188,11 +368,34 @@ interface RunService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** @see [list] */ + @MustBeClosed + fun list(params: RunListParams): HttpResponseFor = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list(threadId: String, requestOptions: RequestOptions): HttpResponseFor = + list(threadId, RunListParams.none(), requestOptions) + /** * Returns a raw HTTP response for `post /threads/{thread_id}/runs/{run_id}/cancel`, but is * otherwise the same as [RunService.cancel]. */ @MustBeClosed + fun cancel(runId: String, params: RunCancelParams): HttpResponseFor = + cancel(runId, params, RequestOptions.none()) + + /** @see [cancel] */ + @MustBeClosed + fun cancel( + runId: String, + params: RunCancelParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = cancel(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [cancel] */ + @MustBeClosed fun cancel(params: RunCancelParams): HttpResponseFor = cancel(params, RequestOptions.none()) @@ -209,6 +412,22 @@ interface RunService { * [RunService.submitToolOutputs]. */ @MustBeClosed + fun submitToolOutputs( + runId: String, + params: RunSubmitToolOutputsParams, + ): HttpResponseFor = submitToolOutputs(runId, params, RequestOptions.none()) + + /** @see [submitToolOutputs] */ + @MustBeClosed + fun submitToolOutputs( + runId: String, + params: RunSubmitToolOutputsParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + submitToolOutputs(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [submitToolOutputs] */ + @MustBeClosed fun submitToolOutputs(params: RunSubmitToolOutputsParams): HttpResponseFor = submitToolOutputs(params, RequestOptions.none()) @@ -225,6 +444,23 @@ interface RunService { * [RunService.submitToolOutputsStreaming]. */ @MustBeClosed + fun submitToolOutputsStreaming( + runId: String, + params: RunSubmitToolOutputsParams, + ): HttpResponseFor> = + submitToolOutputsStreaming(runId, params, RequestOptions.none()) + + /** @see [submitToolOutputsStreaming] */ + @MustBeClosed + fun submitToolOutputsStreaming( + runId: String, + params: RunSubmitToolOutputsParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor> = + submitToolOutputsStreaming(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [submitToolOutputsStreaming] */ + @MustBeClosed fun submitToolOutputsStreaming( params: RunSubmitToolOutputsParams ): HttpResponseFor> = diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/threads/RunServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/threads/RunServiceImpl.kt index 0d7f999d..0f7f56e8 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/threads/RunServiceImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/threads/RunServiceImpl.kt @@ -5,6 +5,7 @@ package com.openai.services.blocking.beta.threads import com.openai.core.ClientOptions import com.openai.core.JsonValue import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.mapJson @@ -33,6 +34,7 @@ import com.openai.models.beta.threads.runs.RunSubmitToolOutputsParams import com.openai.models.beta.threads.runs.RunUpdateParams import com.openai.services.blocking.beta.threads.runs.StepService import com.openai.services.blocking.beta.threads.runs.StepServiceImpl +import kotlin.jvm.optionals.getOrNull class RunServiceImpl internal constructor(private val clientOptions: ClientOptions) : RunService { @@ -110,6 +112,9 @@ class RunServiceImpl internal constructor(private val clientOptions: ClientOptio params: RunCreateParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("threadId", params.threadId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -144,6 +149,9 @@ class RunServiceImpl internal constructor(private val clientOptions: ClientOptio params: RunCreateParams, requestOptions: RequestOptions, ): HttpResponseFor> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("threadId", params.threadId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -187,6 +195,9 @@ class RunServiceImpl internal constructor(private val clientOptions: ClientOptio params: RunRetrieveParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("runId", params.runId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -214,6 +225,9 @@ class RunServiceImpl internal constructor(private val clientOptions: ClientOptio params: RunUpdateParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("runId", params.runId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -243,6 +257,9 @@ class RunServiceImpl internal constructor(private val clientOptions: ClientOptio params: RunListParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("threadId", params.threadId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -277,6 +294,9 @@ class RunServiceImpl internal constructor(private val clientOptions: ClientOptio params: RunCancelParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("runId", params.runId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -311,6 +331,9 @@ class RunServiceImpl internal constructor(private val clientOptions: ClientOptio params: RunSubmitToolOutputsParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("runId", params.runId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -348,6 +371,9 @@ class RunServiceImpl internal constructor(private val clientOptions: ClientOptio params: RunSubmitToolOutputsParams, requestOptions: RequestOptions, ): HttpResponseFor> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("runId", params.runId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/threads/runs/StepService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/threads/runs/StepService.kt index 5b4bf471..6e5270de 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/threads/runs/StepService.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/threads/runs/StepService.kt @@ -18,6 +18,17 @@ interface StepService { fun withRawResponse(): WithRawResponse /** Retrieves a run step. */ + fun retrieve(stepId: String, params: StepRetrieveParams): RunStep = + retrieve(stepId, params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve( + stepId: String, + params: StepRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): RunStep = retrieve(params.toBuilder().stepId(stepId).build(), requestOptions) + + /** @see [retrieve] */ fun retrieve(params: StepRetrieveParams): RunStep = retrieve(params, RequestOptions.none()) /** @see [retrieve] */ @@ -27,6 +38,17 @@ interface StepService { ): RunStep /** Returns a list of run steps belonging to a run. */ + fun list(runId: String, params: StepListParams): StepListPage = + list(runId, params, RequestOptions.none()) + + /** @see [list] */ + fun list( + runId: String, + params: StepListParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): StepListPage = list(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [list] */ fun list(params: StepListParams): StepListPage = list(params, RequestOptions.none()) /** @see [list] */ @@ -43,6 +65,20 @@ interface StepService { * but is otherwise the same as [StepService.retrieve]. */ @MustBeClosed + fun retrieve(stepId: String, params: StepRetrieveParams): HttpResponseFor = + retrieve(stepId, params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + stepId: String, + params: StepRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + retrieve(params.toBuilder().stepId(stepId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed fun retrieve(params: StepRetrieveParams): HttpResponseFor = retrieve(params, RequestOptions.none()) @@ -58,6 +94,20 @@ interface StepService { * otherwise the same as [StepService.list]. */ @MustBeClosed + fun list(runId: String, params: StepListParams): HttpResponseFor = + list(runId, params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + runId: String, + params: StepListParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + list(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [list] */ + @MustBeClosed fun list(params: StepListParams): HttpResponseFor = list(params, RequestOptions.none()) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/threads/runs/StepServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/threads/runs/StepServiceImpl.kt index e4d41faf..bc2477b0 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/threads/runs/StepServiceImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/threads/runs/StepServiceImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.blocking.beta.threads.runs import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -20,6 +21,7 @@ import com.openai.models.beta.threads.runs.steps.StepListPage import com.openai.models.beta.threads.runs.steps.StepListPageResponse import com.openai.models.beta.threads.runs.steps.StepListParams import com.openai.models.beta.threads.runs.steps.StepRetrieveParams +import kotlin.jvm.optionals.getOrNull class StepServiceImpl internal constructor(private val clientOptions: ClientOptions) : StepService { @@ -54,6 +56,9 @@ class StepServiceImpl internal constructor(private val clientOptions: ClientOpti params: StepRetrieveParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("stepId", params.stepId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -89,6 +94,9 @@ class StepServiceImpl internal constructor(private val clientOptions: ClientOpti params: StepListParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("runId", params.runId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/chat/ChatCompletionService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/chat/ChatCompletionService.kt index 3f46a970..8febcf12 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/chat/ChatCompletionService.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/chat/ChatCompletionService.kt @@ -86,8 +86,22 @@ interface ChatCompletionService { * Get a stored chat completion. Only Chat Completions that have been created with the `store` * parameter set to `true` will be returned. */ - fun retrieve(params: ChatCompletionRetrieveParams): ChatCompletion = - retrieve(params, RequestOptions.none()) + fun retrieve(completionId: String): ChatCompletion = + retrieve(completionId, ChatCompletionRetrieveParams.none()) + + /** @see [retrieve] */ + fun retrieve( + completionId: String, + params: ChatCompletionRetrieveParams = ChatCompletionRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): ChatCompletion = + retrieve(params.toBuilder().completionId(completionId).build(), requestOptions) + + /** @see [retrieve] */ + fun retrieve( + completionId: String, + params: ChatCompletionRetrieveParams = ChatCompletionRetrieveParams.none(), + ): ChatCompletion = retrieve(completionId, params, RequestOptions.none()) /** @see [retrieve] */ fun retrieve( @@ -95,11 +109,31 @@ interface ChatCompletionService { requestOptions: RequestOptions = RequestOptions.none(), ): ChatCompletion + /** @see [retrieve] */ + fun retrieve(params: ChatCompletionRetrieveParams): ChatCompletion = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve(completionId: String, requestOptions: RequestOptions): ChatCompletion = + retrieve(completionId, ChatCompletionRetrieveParams.none(), requestOptions) + /** * Modify a stored chat completion. Only Chat Completions that have been created with the * `store` parameter set to `true` can be modified. Currently, the only supported modification * is to update the `metadata` field. */ + fun update(completionId: String, params: ChatCompletionUpdateParams): ChatCompletion = + update(completionId, params, RequestOptions.none()) + + /** @see [update] */ + fun update( + completionId: String, + params: ChatCompletionUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): ChatCompletion = + update(params.toBuilder().completionId(completionId).build(), requestOptions) + + /** @see [update] */ fun update(params: ChatCompletionUpdateParams): ChatCompletion = update(params, RequestOptions.none()) @@ -134,8 +168,22 @@ interface ChatCompletionService { * Delete a stored chat completion. Only Chat Completions that have been created with the * `store` parameter set to `true` can be deleted. */ - fun delete(params: ChatCompletionDeleteParams): ChatCompletionDeleted = - delete(params, RequestOptions.none()) + fun delete(completionId: String): ChatCompletionDeleted = + delete(completionId, ChatCompletionDeleteParams.none()) + + /** @see [delete] */ + fun delete( + completionId: String, + params: ChatCompletionDeleteParams = ChatCompletionDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): ChatCompletionDeleted = + delete(params.toBuilder().completionId(completionId).build(), requestOptions) + + /** @see [delete] */ + fun delete( + completionId: String, + params: ChatCompletionDeleteParams = ChatCompletionDeleteParams.none(), + ): ChatCompletionDeleted = delete(completionId, params, RequestOptions.none()) /** @see [delete] */ fun delete( @@ -143,6 +191,14 @@ interface ChatCompletionService { requestOptions: RequestOptions = RequestOptions.none(), ): ChatCompletionDeleted + /** @see [delete] */ + fun delete(params: ChatCompletionDeleteParams): ChatCompletionDeleted = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + fun delete(completionId: String, requestOptions: RequestOptions): ChatCompletionDeleted = + delete(completionId, ChatCompletionDeleteParams.none(), requestOptions) + /** * A view of [ChatCompletionService] that provides access to raw HTTP responses for each method. */ @@ -187,8 +243,24 @@ interface ChatCompletionService { * the same as [ChatCompletionService.retrieve]. */ @MustBeClosed - fun retrieve(params: ChatCompletionRetrieveParams): HttpResponseFor = - retrieve(params, RequestOptions.none()) + fun retrieve(completionId: String): HttpResponseFor = + retrieve(completionId, ChatCompletionRetrieveParams.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + completionId: String, + params: ChatCompletionRetrieveParams = ChatCompletionRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + retrieve(params.toBuilder().completionId(completionId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + completionId: String, + params: ChatCompletionRetrieveParams = ChatCompletionRetrieveParams.none(), + ): HttpResponseFor = retrieve(completionId, params, RequestOptions.none()) /** @see [retrieve] */ @MustBeClosed @@ -197,11 +269,40 @@ interface ChatCompletionService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** @see [retrieve] */ + @MustBeClosed + fun retrieve(params: ChatCompletionRetrieveParams): HttpResponseFor = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + completionId: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + retrieve(completionId, ChatCompletionRetrieveParams.none(), requestOptions) + /** * Returns a raw HTTP response for `post /chat/completions/{completion_id}`, but is * otherwise the same as [ChatCompletionService.update]. */ @MustBeClosed + fun update( + completionId: String, + params: ChatCompletionUpdateParams, + ): HttpResponseFor = update(completionId, params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + completionId: String, + params: ChatCompletionUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + update(params.toBuilder().completionId(completionId).build(), requestOptions) + + /** @see [update] */ + @MustBeClosed fun update(params: ChatCompletionUpdateParams): HttpResponseFor = update(params, RequestOptions.none()) @@ -242,8 +343,25 @@ interface ChatCompletionService { * otherwise the same as [ChatCompletionService.delete]. */ @MustBeClosed - fun delete(params: ChatCompletionDeleteParams): HttpResponseFor = - delete(params, RequestOptions.none()) + fun delete(completionId: String): HttpResponseFor = + delete(completionId, ChatCompletionDeleteParams.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + completionId: String, + params: ChatCompletionDeleteParams = ChatCompletionDeleteParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + delete(params.toBuilder().completionId(completionId).build(), requestOptions) + + /** @see [delete] */ + @MustBeClosed + fun delete( + completionId: String, + params: ChatCompletionDeleteParams = ChatCompletionDeleteParams.none(), + ): HttpResponseFor = + delete(completionId, params, RequestOptions.none()) /** @see [delete] */ @MustBeClosed @@ -251,5 +369,18 @@ interface ChatCompletionService { params: ChatCompletionDeleteParams, requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + + /** @see [delete] */ + @MustBeClosed + fun delete(params: ChatCompletionDeleteParams): HttpResponseFor = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + completionId: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + delete(completionId, ChatCompletionDeleteParams.none(), requestOptions) } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/chat/ChatCompletionServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/chat/ChatCompletionServiceImpl.kt index 0bffd8df..b07c2c6c 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/chat/ChatCompletionServiceImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/chat/ChatCompletionServiceImpl.kt @@ -5,6 +5,7 @@ package com.openai.services.blocking.chat import com.openai.core.ClientOptions import com.openai.core.JsonValue import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.mapJson @@ -174,6 +175,9 @@ class ChatCompletionServiceImpl internal constructor(private val clientOptions: params: ChatCompletionRetrieveParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("completionId", params.completionId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -200,6 +204,9 @@ class ChatCompletionServiceImpl internal constructor(private val clientOptions: params: ChatCompletionUpdateParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("completionId", params.completionId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -266,6 +273,9 @@ class ChatCompletionServiceImpl internal constructor(private val clientOptions: params: ChatCompletionDeleteParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("completionId", params.completionId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.DELETE) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/chat/completions/MessageService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/chat/completions/MessageService.kt index b1161981..d4fc968c 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/chat/completions/MessageService.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/chat/completions/MessageService.kt @@ -19,7 +19,20 @@ interface MessageService { * Get the messages in a stored chat completion. Only Chat Completions that have been created * with the `store` parameter set to `true` will be returned. */ - fun list(params: MessageListParams): MessageListPage = list(params, RequestOptions.none()) + fun list(completionId: String): MessageListPage = list(completionId, MessageListParams.none()) + + /** @see [list] */ + fun list( + completionId: String, + params: MessageListParams = MessageListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): MessageListPage = list(params.toBuilder().completionId(completionId).build(), requestOptions) + + /** @see [list] */ + fun list( + completionId: String, + params: MessageListParams = MessageListParams.none(), + ): MessageListPage = list(completionId, params, RequestOptions.none()) /** @see [list] */ fun list( @@ -27,6 +40,13 @@ interface MessageService { requestOptions: RequestOptions = RequestOptions.none(), ): MessageListPage + /** @see [list] */ + fun list(params: MessageListParams): MessageListPage = list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(completionId: String, requestOptions: RequestOptions): MessageListPage = + list(completionId, MessageListParams.none(), requestOptions) + /** A view of [MessageService] that provides access to raw HTTP responses for each method. */ interface WithRawResponse { @@ -35,8 +55,24 @@ interface MessageService { * otherwise the same as [MessageService.list]. */ @MustBeClosed - fun list(params: MessageListParams): HttpResponseFor = - list(params, RequestOptions.none()) + fun list(completionId: String): HttpResponseFor = + list(completionId, MessageListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + completionId: String, + params: MessageListParams = MessageListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + list(params.toBuilder().completionId(completionId).build(), requestOptions) + + /** @see [list] */ + @MustBeClosed + fun list( + completionId: String, + params: MessageListParams = MessageListParams.none(), + ): HttpResponseFor = list(completionId, params, RequestOptions.none()) /** @see [list] */ @MustBeClosed @@ -44,5 +80,18 @@ interface MessageService { params: MessageListParams, requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + + /** @see [list] */ + @MustBeClosed + fun list(params: MessageListParams): HttpResponseFor = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + completionId: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + list(completionId, MessageListParams.none(), requestOptions) } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/chat/completions/MessageServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/chat/completions/MessageServiceImpl.kt index c87f53ee..52b267d3 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/chat/completions/MessageServiceImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/chat/completions/MessageServiceImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.blocking.chat.completions import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -17,6 +18,7 @@ import com.openai.models.ErrorObject import com.openai.models.chat.completions.messages.MessageListPage import com.openai.models.chat.completions.messages.MessageListPageResponse import com.openai.models.chat.completions.messages.MessageListParams +import kotlin.jvm.optionals.getOrNull class MessageServiceImpl internal constructor(private val clientOptions: ClientOptions) : MessageService { @@ -44,6 +46,9 @@ class MessageServiceImpl internal constructor(private val clientOptions: ClientO params: MessageListParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("completionId", params.completionId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/evals/RunService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/evals/RunService.kt index c604c6c2..fff6cf21 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/evals/RunService.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/evals/RunService.kt @@ -27,6 +27,17 @@ interface RunService { fun outputItems(): OutputItemService /** Create a new evaluation run. This is the endpoint that will kick off grading. */ + fun create(evalId: String, params: RunCreateParams): RunCreateResponse = + create(evalId, params, RequestOptions.none()) + + /** @see [create] */ + fun create( + evalId: String, + params: RunCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): RunCreateResponse = create(params.toBuilder().evalId(evalId).build(), requestOptions) + + /** @see [create] */ fun create(params: RunCreateParams): RunCreateResponse = create(params, RequestOptions.none()) /** @see [create] */ @@ -36,6 +47,17 @@ interface RunService { ): RunCreateResponse /** Get an evaluation run by ID. */ + fun retrieve(runId: String, params: RunRetrieveParams): RunRetrieveResponse = + retrieve(runId, params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve( + runId: String, + params: RunRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): RunRetrieveResponse = retrieve(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [retrieve] */ fun retrieve(params: RunRetrieveParams): RunRetrieveResponse = retrieve(params, RequestOptions.none()) @@ -46,7 +68,18 @@ interface RunService { ): RunRetrieveResponse /** Get a list of runs for an evaluation. */ - fun list(params: RunListParams): RunListPage = list(params, RequestOptions.none()) + fun list(evalId: String): RunListPage = list(evalId, RunListParams.none()) + + /** @see [list] */ + fun list( + evalId: String, + params: RunListParams = RunListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): RunListPage = list(params.toBuilder().evalId(evalId).build(), requestOptions) + + /** @see [list] */ + fun list(evalId: String, params: RunListParams = RunListParams.none()): RunListPage = + list(evalId, params, RequestOptions.none()) /** @see [list] */ fun list( @@ -54,7 +87,25 @@ interface RunService { requestOptions: RequestOptions = RequestOptions.none(), ): RunListPage + /** @see [list] */ + fun list(params: RunListParams): RunListPage = list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(evalId: String, requestOptions: RequestOptions): RunListPage = + list(evalId, RunListParams.none(), requestOptions) + /** Delete an eval run. */ + fun delete(runId: String, params: RunDeleteParams): RunDeleteResponse = + delete(runId, params, RequestOptions.none()) + + /** @see [delete] */ + fun delete( + runId: String, + params: RunDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): RunDeleteResponse = delete(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [delete] */ fun delete(params: RunDeleteParams): RunDeleteResponse = delete(params, RequestOptions.none()) /** @see [delete] */ @@ -64,6 +115,17 @@ interface RunService { ): RunDeleteResponse /** Cancel an ongoing evaluation run. */ + fun cancel(runId: String, params: RunCancelParams): RunCancelResponse = + cancel(runId, params, RequestOptions.none()) + + /** @see [cancel] */ + fun cancel( + runId: String, + params: RunCancelParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): RunCancelResponse = cancel(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [cancel] */ fun cancel(params: RunCancelParams): RunCancelResponse = cancel(params, RequestOptions.none()) /** @see [cancel] */ @@ -82,6 +144,20 @@ interface RunService { * as [RunService.create]. */ @MustBeClosed + fun create(evalId: String, params: RunCreateParams): HttpResponseFor = + create(evalId, params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + evalId: String, + params: RunCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + create(params.toBuilder().evalId(evalId).build(), requestOptions) + + /** @see [create] */ + @MustBeClosed fun create(params: RunCreateParams): HttpResponseFor = create(params, RequestOptions.none()) @@ -97,6 +173,22 @@ interface RunService { * the same as [RunService.retrieve]. */ @MustBeClosed + fun retrieve( + runId: String, + params: RunRetrieveParams, + ): HttpResponseFor = retrieve(runId, params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + runId: String, + params: RunRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + retrieve(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed fun retrieve(params: RunRetrieveParams): HttpResponseFor = retrieve(params, RequestOptions.none()) @@ -112,8 +204,23 @@ interface RunService { * [RunService.list]. */ @MustBeClosed - fun list(params: RunListParams): HttpResponseFor = - list(params, RequestOptions.none()) + fun list(evalId: String): HttpResponseFor = list(evalId, RunListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + evalId: String, + params: RunListParams = RunListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + list(params.toBuilder().evalId(evalId).build(), requestOptions) + + /** @see [list] */ + @MustBeClosed + fun list( + evalId: String, + params: RunListParams = RunListParams.none(), + ): HttpResponseFor = list(evalId, params, RequestOptions.none()) /** @see [list] */ @MustBeClosed @@ -122,11 +229,35 @@ interface RunService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** @see [list] */ + @MustBeClosed + fun list(params: RunListParams): HttpResponseFor = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list(evalId: String, requestOptions: RequestOptions): HttpResponseFor = + list(evalId, RunListParams.none(), requestOptions) + /** * Returns a raw HTTP response for `delete /evals/{eval_id}/runs/{run_id}`, but is otherwise * the same as [RunService.delete]. */ @MustBeClosed + fun delete(runId: String, params: RunDeleteParams): HttpResponseFor = + delete(runId, params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + runId: String, + params: RunDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + delete(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [delete] */ + @MustBeClosed fun delete(params: RunDeleteParams): HttpResponseFor = delete(params, RequestOptions.none()) @@ -142,6 +273,20 @@ interface RunService { * the same as [RunService.cancel]. */ @MustBeClosed + fun cancel(runId: String, params: RunCancelParams): HttpResponseFor = + cancel(runId, params, RequestOptions.none()) + + /** @see [cancel] */ + @MustBeClosed + fun cancel( + runId: String, + params: RunCancelParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + cancel(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [cancel] */ + @MustBeClosed fun cancel(params: RunCancelParams): HttpResponseFor = cancel(params, RequestOptions.none()) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/evals/RunServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/evals/RunServiceImpl.kt index aa985644..ee64dae6 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/evals/RunServiceImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/evals/RunServiceImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.blocking.evals import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -28,6 +29,7 @@ import com.openai.models.evals.runs.RunRetrieveParams import com.openai.models.evals.runs.RunRetrieveResponse import com.openai.services.blocking.evals.runs.OutputItemService import com.openai.services.blocking.evals.runs.OutputItemServiceImpl +import kotlin.jvm.optionals.getOrNull class RunServiceImpl internal constructor(private val clientOptions: ClientOptions) : RunService { @@ -91,6 +93,9 @@ class RunServiceImpl internal constructor(private val clientOptions: ClientOptio params: RunCreateParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("evalId", params.evalId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -119,6 +124,9 @@ class RunServiceImpl internal constructor(private val clientOptions: ClientOptio params: RunRetrieveParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("runId", params.runId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -146,6 +154,9 @@ class RunServiceImpl internal constructor(private val clientOptions: ClientOptio params: RunListParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("evalId", params.evalId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -179,6 +190,9 @@ class RunServiceImpl internal constructor(private val clientOptions: ClientOptio params: RunDeleteParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("runId", params.runId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.DELETE) @@ -206,6 +220,9 @@ class RunServiceImpl internal constructor(private val clientOptions: ClientOptio params: RunCancelParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("runId", params.runId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/evals/runs/OutputItemService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/evals/runs/OutputItemService.kt index 5a1750da..59468f9e 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/evals/runs/OutputItemService.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/evals/runs/OutputItemService.kt @@ -18,6 +18,20 @@ interface OutputItemService { fun withRawResponse(): WithRawResponse /** Get an evaluation run output item by ID. */ + fun retrieve( + outputItemId: String, + params: OutputItemRetrieveParams, + ): OutputItemRetrieveResponse = retrieve(outputItemId, params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve( + outputItemId: String, + params: OutputItemRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): OutputItemRetrieveResponse = + retrieve(params.toBuilder().outputItemId(outputItemId).build(), requestOptions) + + /** @see [retrieve] */ fun retrieve(params: OutputItemRetrieveParams): OutputItemRetrieveResponse = retrieve(params, RequestOptions.none()) @@ -28,6 +42,17 @@ interface OutputItemService { ): OutputItemRetrieveResponse /** Get a list of output items for an evaluation run. */ + fun list(runId: String, params: OutputItemListParams): OutputItemListPage = + list(runId, params, RequestOptions.none()) + + /** @see [list] */ + fun list( + runId: String, + params: OutputItemListParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): OutputItemListPage = list(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [list] */ fun list(params: OutputItemListParams): OutputItemListPage = list(params, RequestOptions.none()) /** @see [list] */ @@ -45,6 +70,23 @@ interface OutputItemService { * as [OutputItemService.retrieve]. */ @MustBeClosed + fun retrieve( + outputItemId: String, + params: OutputItemRetrieveParams, + ): HttpResponseFor = + retrieve(outputItemId, params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + outputItemId: String, + params: OutputItemRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + retrieve(params.toBuilder().outputItemId(outputItemId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed fun retrieve( params: OutputItemRetrieveParams ): HttpResponseFor = retrieve(params, RequestOptions.none()) @@ -61,6 +103,20 @@ interface OutputItemService { * otherwise the same as [OutputItemService.list]. */ @MustBeClosed + fun list(runId: String, params: OutputItemListParams): HttpResponseFor = + list(runId, params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + runId: String, + params: OutputItemListParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + list(params.toBuilder().runId(runId).build(), requestOptions) + + /** @see [list] */ + @MustBeClosed fun list(params: OutputItemListParams): HttpResponseFor = list(params, RequestOptions.none()) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/evals/runs/OutputItemServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/evals/runs/OutputItemServiceImpl.kt index cce944dd..de2cfba3 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/evals/runs/OutputItemServiceImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/evals/runs/OutputItemServiceImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.blocking.evals.runs import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -19,6 +20,7 @@ import com.openai.models.evals.runs.outputitems.OutputItemListPageResponse import com.openai.models.evals.runs.outputitems.OutputItemListParams import com.openai.models.evals.runs.outputitems.OutputItemRetrieveParams import com.openai.models.evals.runs.outputitems.OutputItemRetrieveResponse +import kotlin.jvm.optionals.getOrNull class OutputItemServiceImpl internal constructor(private val clientOptions: ClientOptions) : OutputItemService { @@ -56,6 +58,9 @@ class OutputItemServiceImpl internal constructor(private val clientOptions: Clie params: OutputItemRetrieveParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("outputItemId", params.outputItemId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -90,6 +95,9 @@ class OutputItemServiceImpl internal constructor(private val clientOptions: Clie params: OutputItemListParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("runId", params.runId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/AlphaService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/AlphaService.kt new file mode 100644 index 00000000..6f892364 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/AlphaService.kt @@ -0,0 +1,21 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.services.blocking.finetuning + +import com.openai.services.blocking.finetuning.alpha.GraderService + +interface AlphaService { + + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + + fun graders(): GraderService + + /** A view of [AlphaService] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + fun graders(): GraderService.WithRawResponse + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/AlphaServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/AlphaServiceImpl.kt new file mode 100644 index 00000000..372892c0 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/AlphaServiceImpl.kt @@ -0,0 +1,31 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.services.blocking.finetuning + +import com.openai.core.ClientOptions +import com.openai.services.blocking.finetuning.alpha.GraderService +import com.openai.services.blocking.finetuning.alpha.GraderServiceImpl + +class AlphaServiceImpl internal constructor(private val clientOptions: ClientOptions) : + AlphaService { + + private val withRawResponse: AlphaService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + private val graders: GraderService by lazy { GraderServiceImpl(clientOptions) } + + override fun withRawResponse(): AlphaService.WithRawResponse = withRawResponse + + override fun graders(): GraderService = graders + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + AlphaService.WithRawResponse { + + private val graders: GraderService.WithRawResponse by lazy { + GraderServiceImpl.WithRawResponseImpl(clientOptions) + } + + override fun graders(): GraderService.WithRawResponse = graders + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/JobService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/JobService.kt index 1985fe05..785543c0 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/JobService.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/JobService.kt @@ -12,6 +12,8 @@ import com.openai.models.finetuning.jobs.JobListEventsPage import com.openai.models.finetuning.jobs.JobListEventsParams import com.openai.models.finetuning.jobs.JobListPage import com.openai.models.finetuning.jobs.JobListParams +import com.openai.models.finetuning.jobs.JobPauseParams +import com.openai.models.finetuning.jobs.JobResumeParams import com.openai.models.finetuning.jobs.JobRetrieveParams import com.openai.services.blocking.finetuning.jobs.CheckpointService @@ -46,7 +48,22 @@ interface JobService { * * [Learn more about fine-tuning](https://platform.openai.com/docs/guides/fine-tuning) */ - fun retrieve(params: JobRetrieveParams): FineTuningJob = retrieve(params, RequestOptions.none()) + fun retrieve(fineTuningJobId: String): FineTuningJob = + retrieve(fineTuningJobId, JobRetrieveParams.none()) + + /** @see [retrieve] */ + fun retrieve( + fineTuningJobId: String, + params: JobRetrieveParams = JobRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): FineTuningJob = + retrieve(params.toBuilder().fineTuningJobId(fineTuningJobId).build(), requestOptions) + + /** @see [retrieve] */ + fun retrieve( + fineTuningJobId: String, + params: JobRetrieveParams = JobRetrieveParams.none(), + ): FineTuningJob = retrieve(fineTuningJobId, params, RequestOptions.none()) /** @see [retrieve] */ fun retrieve( @@ -54,6 +71,13 @@ interface JobService { requestOptions: RequestOptions = RequestOptions.none(), ): FineTuningJob + /** @see [retrieve] */ + fun retrieve(params: JobRetrieveParams): FineTuningJob = retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve(fineTuningJobId: String, requestOptions: RequestOptions): FineTuningJob = + retrieve(fineTuningJobId, JobRetrieveParams.none(), requestOptions) + /** List your organization's fine-tuning jobs */ fun list(): JobListPage = list(JobListParams.none()) @@ -72,7 +96,22 @@ interface JobService { list(JobListParams.none(), requestOptions) /** Immediately cancel a fine-tune job. */ - fun cancel(params: JobCancelParams): FineTuningJob = cancel(params, RequestOptions.none()) + fun cancel(fineTuningJobId: String): FineTuningJob = + cancel(fineTuningJobId, JobCancelParams.none()) + + /** @see [cancel] */ + fun cancel( + fineTuningJobId: String, + params: JobCancelParams = JobCancelParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): FineTuningJob = + cancel(params.toBuilder().fineTuningJobId(fineTuningJobId).build(), requestOptions) + + /** @see [cancel] */ + fun cancel( + fineTuningJobId: String, + params: JobCancelParams = JobCancelParams.none(), + ): FineTuningJob = cancel(fineTuningJobId, params, RequestOptions.none()) /** @see [cancel] */ fun cancel( @@ -80,9 +119,30 @@ interface JobService { requestOptions: RequestOptions = RequestOptions.none(), ): FineTuningJob + /** @see [cancel] */ + fun cancel(params: JobCancelParams): FineTuningJob = cancel(params, RequestOptions.none()) + + /** @see [cancel] */ + fun cancel(fineTuningJobId: String, requestOptions: RequestOptions): FineTuningJob = + cancel(fineTuningJobId, JobCancelParams.none(), requestOptions) + /** Get status updates for a fine-tuning job. */ - fun listEvents(params: JobListEventsParams): JobListEventsPage = - listEvents(params, RequestOptions.none()) + fun listEvents(fineTuningJobId: String): JobListEventsPage = + listEvents(fineTuningJobId, JobListEventsParams.none()) + + /** @see [listEvents] */ + fun listEvents( + fineTuningJobId: String, + params: JobListEventsParams = JobListEventsParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): JobListEventsPage = + listEvents(params.toBuilder().fineTuningJobId(fineTuningJobId).build(), requestOptions) + + /** @see [listEvents] */ + fun listEvents( + fineTuningJobId: String, + params: JobListEventsParams = JobListEventsParams.none(), + ): JobListEventsPage = listEvents(fineTuningJobId, params, RequestOptions.none()) /** @see [listEvents] */ fun listEvents( @@ -90,6 +150,76 @@ interface JobService { requestOptions: RequestOptions = RequestOptions.none(), ): JobListEventsPage + /** @see [listEvents] */ + fun listEvents(params: JobListEventsParams): JobListEventsPage = + listEvents(params, RequestOptions.none()) + + /** @see [listEvents] */ + fun listEvents(fineTuningJobId: String, requestOptions: RequestOptions): JobListEventsPage = + listEvents(fineTuningJobId, JobListEventsParams.none(), requestOptions) + + /** Pause a fine-tune job. */ + fun pause(fineTuningJobId: String): FineTuningJob = + pause(fineTuningJobId, JobPauseParams.none()) + + /** @see [pause] */ + fun pause( + fineTuningJobId: String, + params: JobPauseParams = JobPauseParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): FineTuningJob = + pause(params.toBuilder().fineTuningJobId(fineTuningJobId).build(), requestOptions) + + /** @see [pause] */ + fun pause( + fineTuningJobId: String, + params: JobPauseParams = JobPauseParams.none(), + ): FineTuningJob = pause(fineTuningJobId, params, RequestOptions.none()) + + /** @see [pause] */ + fun pause( + params: JobPauseParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): FineTuningJob + + /** @see [pause] */ + fun pause(params: JobPauseParams): FineTuningJob = pause(params, RequestOptions.none()) + + /** @see [pause] */ + fun pause(fineTuningJobId: String, requestOptions: RequestOptions): FineTuningJob = + pause(fineTuningJobId, JobPauseParams.none(), requestOptions) + + /** Resume a fine-tune job. */ + fun resume(fineTuningJobId: String): FineTuningJob = + resume(fineTuningJobId, JobResumeParams.none()) + + /** @see [resume] */ + fun resume( + fineTuningJobId: String, + params: JobResumeParams = JobResumeParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): FineTuningJob = + resume(params.toBuilder().fineTuningJobId(fineTuningJobId).build(), requestOptions) + + /** @see [resume] */ + fun resume( + fineTuningJobId: String, + params: JobResumeParams = JobResumeParams.none(), + ): FineTuningJob = resume(fineTuningJobId, params, RequestOptions.none()) + + /** @see [resume] */ + fun resume( + params: JobResumeParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): FineTuningJob + + /** @see [resume] */ + fun resume(params: JobResumeParams): FineTuningJob = resume(params, RequestOptions.none()) + + /** @see [resume] */ + fun resume(fineTuningJobId: String, requestOptions: RequestOptions): FineTuningJob = + resume(fineTuningJobId, JobResumeParams.none(), requestOptions) + /** A view of [JobService] that provides access to raw HTTP responses for each method. */ interface WithRawResponse { @@ -115,8 +245,24 @@ interface JobService { * otherwise the same as [JobService.retrieve]. */ @MustBeClosed - fun retrieve(params: JobRetrieveParams): HttpResponseFor = - retrieve(params, RequestOptions.none()) + fun retrieve(fineTuningJobId: String): HttpResponseFor = + retrieve(fineTuningJobId, JobRetrieveParams.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + fineTuningJobId: String, + params: JobRetrieveParams = JobRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + retrieve(params.toBuilder().fineTuningJobId(fineTuningJobId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + fineTuningJobId: String, + params: JobRetrieveParams = JobRetrieveParams.none(), + ): HttpResponseFor = retrieve(fineTuningJobId, params, RequestOptions.none()) /** @see [retrieve] */ @MustBeClosed @@ -125,6 +271,19 @@ interface JobService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** @see [retrieve] */ + @MustBeClosed + fun retrieve(params: JobRetrieveParams): HttpResponseFor = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + fineTuningJobId: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + retrieve(fineTuningJobId, JobRetrieveParams.none(), requestOptions) + /** * Returns a raw HTTP response for `get /fine_tuning/jobs`, but is otherwise the same as * [JobService.list]. @@ -153,8 +312,24 @@ interface JobService { * is otherwise the same as [JobService.cancel]. */ @MustBeClosed - fun cancel(params: JobCancelParams): HttpResponseFor = - cancel(params, RequestOptions.none()) + fun cancel(fineTuningJobId: String): HttpResponseFor = + cancel(fineTuningJobId, JobCancelParams.none()) + + /** @see [cancel] */ + @MustBeClosed + fun cancel( + fineTuningJobId: String, + params: JobCancelParams = JobCancelParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + cancel(params.toBuilder().fineTuningJobId(fineTuningJobId).build(), requestOptions) + + /** @see [cancel] */ + @MustBeClosed + fun cancel( + fineTuningJobId: String, + params: JobCancelParams = JobCancelParams.none(), + ): HttpResponseFor = cancel(fineTuningJobId, params, RequestOptions.none()) /** @see [cancel] */ @MustBeClosed @@ -163,13 +338,43 @@ interface JobService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** @see [cancel] */ + @MustBeClosed + fun cancel(params: JobCancelParams): HttpResponseFor = + cancel(params, RequestOptions.none()) + + /** @see [cancel] */ + @MustBeClosed + fun cancel( + fineTuningJobId: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + cancel(fineTuningJobId, JobCancelParams.none(), requestOptions) + /** * Returns a raw HTTP response for `get /fine_tuning/jobs/{fine_tuning_job_id}/events`, but * is otherwise the same as [JobService.listEvents]. */ @MustBeClosed - fun listEvents(params: JobListEventsParams): HttpResponseFor = - listEvents(params, RequestOptions.none()) + fun listEvents(fineTuningJobId: String): HttpResponseFor = + listEvents(fineTuningJobId, JobListEventsParams.none()) + + /** @see [listEvents] */ + @MustBeClosed + fun listEvents( + fineTuningJobId: String, + params: JobListEventsParams = JobListEventsParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + listEvents(params.toBuilder().fineTuningJobId(fineTuningJobId).build(), requestOptions) + + /** @see [listEvents] */ + @MustBeClosed + fun listEvents( + fineTuningJobId: String, + params: JobListEventsParams = JobListEventsParams.none(), + ): HttpResponseFor = + listEvents(fineTuningJobId, params, RequestOptions.none()) /** @see [listEvents] */ @MustBeClosed @@ -177,5 +382,106 @@ interface JobService { params: JobListEventsParams, requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + + /** @see [listEvents] */ + @MustBeClosed + fun listEvents(params: JobListEventsParams): HttpResponseFor = + listEvents(params, RequestOptions.none()) + + /** @see [listEvents] */ + @MustBeClosed + fun listEvents( + fineTuningJobId: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + listEvents(fineTuningJobId, JobListEventsParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `post /fine_tuning/jobs/{fine_tuning_job_id}/pause`, but + * is otherwise the same as [JobService.pause]. + */ + @MustBeClosed + fun pause(fineTuningJobId: String): HttpResponseFor = + pause(fineTuningJobId, JobPauseParams.none()) + + /** @see [pause] */ + @MustBeClosed + fun pause( + fineTuningJobId: String, + params: JobPauseParams = JobPauseParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + pause(params.toBuilder().fineTuningJobId(fineTuningJobId).build(), requestOptions) + + /** @see [pause] */ + @MustBeClosed + fun pause( + fineTuningJobId: String, + params: JobPauseParams = JobPauseParams.none(), + ): HttpResponseFor = pause(fineTuningJobId, params, RequestOptions.none()) + + /** @see [pause] */ + @MustBeClosed + fun pause( + params: JobPauseParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see [pause] */ + @MustBeClosed + fun pause(params: JobPauseParams): HttpResponseFor = + pause(params, RequestOptions.none()) + + /** @see [pause] */ + @MustBeClosed + fun pause( + fineTuningJobId: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + pause(fineTuningJobId, JobPauseParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `post /fine_tuning/jobs/{fine_tuning_job_id}/resume`, but + * is otherwise the same as [JobService.resume]. + */ + @MustBeClosed + fun resume(fineTuningJobId: String): HttpResponseFor = + resume(fineTuningJobId, JobResumeParams.none()) + + /** @see [resume] */ + @MustBeClosed + fun resume( + fineTuningJobId: String, + params: JobResumeParams = JobResumeParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + resume(params.toBuilder().fineTuningJobId(fineTuningJobId).build(), requestOptions) + + /** @see [resume] */ + @MustBeClosed + fun resume( + fineTuningJobId: String, + params: JobResumeParams = JobResumeParams.none(), + ): HttpResponseFor = resume(fineTuningJobId, params, RequestOptions.none()) + + /** @see [resume] */ + @MustBeClosed + fun resume( + params: JobResumeParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see [resume] */ + @MustBeClosed + fun resume(params: JobResumeParams): HttpResponseFor = + resume(params, RequestOptions.none()) + + /** @see [resume] */ + @MustBeClosed + fun resume( + fineTuningJobId: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + resume(fineTuningJobId, JobResumeParams.none(), requestOptions) } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/JobServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/JobServiceImpl.kt index 64319c98..ba95b5d3 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/JobServiceImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/JobServiceImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.blocking.finetuning import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -24,9 +25,12 @@ import com.openai.models.finetuning.jobs.JobListEventsParams import com.openai.models.finetuning.jobs.JobListPage import com.openai.models.finetuning.jobs.JobListPageResponse import com.openai.models.finetuning.jobs.JobListParams +import com.openai.models.finetuning.jobs.JobPauseParams +import com.openai.models.finetuning.jobs.JobResumeParams import com.openai.models.finetuning.jobs.JobRetrieveParams import com.openai.services.blocking.finetuning.jobs.CheckpointService import com.openai.services.blocking.finetuning.jobs.CheckpointServiceImpl +import kotlin.jvm.optionals.getOrNull class JobServiceImpl internal constructor(private val clientOptions: ClientOptions) : JobService { @@ -66,6 +70,14 @@ class JobServiceImpl internal constructor(private val clientOptions: ClientOptio // get /fine_tuning/jobs/{fine_tuning_job_id}/events withRawResponse().listEvents(params, requestOptions).parse() + override fun pause(params: JobPauseParams, requestOptions: RequestOptions): FineTuningJob = + // post /fine_tuning/jobs/{fine_tuning_job_id}/pause + withRawResponse().pause(params, requestOptions).parse() + + override fun resume(params: JobResumeParams, requestOptions: RequestOptions): FineTuningJob = + // post /fine_tuning/jobs/{fine_tuning_job_id}/resume + withRawResponse().resume(params, requestOptions).parse() + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : JobService.WithRawResponse { @@ -111,6 +123,9 @@ class JobServiceImpl internal constructor(private val clientOptions: ClientOptio params: JobRetrieveParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("fineTuningJobId", params.fineTuningJobId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -171,6 +186,9 @@ class JobServiceImpl internal constructor(private val clientOptions: ClientOptio params: JobCancelParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("fineTuningJobId", params.fineTuningJobId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -199,6 +217,9 @@ class JobServiceImpl internal constructor(private val clientOptions: ClientOptio params: JobListEventsParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("fineTuningJobId", params.fineTuningJobId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -224,5 +245,65 @@ class JobServiceImpl internal constructor(private val clientOptions: ClientOptio } } } + + private val pauseHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun pause( + params: JobPauseParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("fineTuningJobId", params.fineTuningJobId().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("fine_tuning", "jobs", params._pathParam(0), "pause") + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepare(clientOptions, params, deploymentModel = null) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { pauseHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + + private val resumeHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun resume( + params: JobResumeParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("fineTuningJobId", params.fineTuningJobId().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("fine_tuning", "jobs", params._pathParam(0), "resume") + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepare(clientOptions, params, deploymentModel = null) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { resumeHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/MethodService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/MethodService.kt new file mode 100644 index 00000000..7d829c06 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/MethodService.kt @@ -0,0 +1,14 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.services.blocking.finetuning + +interface MethodService { + + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + + /** A view of [MethodService] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/MethodServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/MethodServiceImpl.kt new file mode 100644 index 00000000..a7750b2c --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/MethodServiceImpl.kt @@ -0,0 +1,18 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.services.blocking.finetuning + +import com.openai.core.ClientOptions + +class MethodServiceImpl internal constructor(private val clientOptions: ClientOptions) : + MethodService { + + private val withRawResponse: MethodService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): MethodService.WithRawResponse = withRawResponse + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + MethodService.WithRawResponse +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/alpha/GraderService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/alpha/GraderService.kt new file mode 100644 index 00000000..f6e4fe7c --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/alpha/GraderService.kt @@ -0,0 +1,72 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.services.blocking.finetuning.alpha + +import com.google.errorprone.annotations.MustBeClosed +import com.openai.core.RequestOptions +import com.openai.core.http.HttpResponseFor +import com.openai.models.finetuning.alpha.graders.GraderRunParams +import com.openai.models.finetuning.alpha.graders.GraderRunResponse +import com.openai.models.finetuning.alpha.graders.GraderValidateParams +import com.openai.models.finetuning.alpha.graders.GraderValidateResponse + +interface GraderService { + + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + + /** Run a grader. */ + fun run(params: GraderRunParams): GraderRunResponse = run(params, RequestOptions.none()) + + /** @see [run] */ + fun run( + params: GraderRunParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): GraderRunResponse + + /** Validate a grader. */ + fun validate(params: GraderValidateParams): GraderValidateResponse = + validate(params, RequestOptions.none()) + + /** @see [validate] */ + fun validate( + params: GraderValidateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): GraderValidateResponse + + /** A view of [GraderService] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /fine_tuning/alpha/graders/run`, but is otherwise + * the same as [GraderService.run]. + */ + @MustBeClosed + fun run(params: GraderRunParams): HttpResponseFor = + run(params, RequestOptions.none()) + + /** @see [run] */ + @MustBeClosed + fun run( + params: GraderRunParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `post /fine_tuning/alpha/graders/validate`, but is + * otherwise the same as [GraderService.validate]. + */ + @MustBeClosed + fun validate(params: GraderValidateParams): HttpResponseFor = + validate(params, RequestOptions.none()) + + /** @see [validate] */ + @MustBeClosed + fun validate( + params: GraderValidateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/alpha/GraderServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/alpha/GraderServiceImpl.kt new file mode 100644 index 00000000..4a9e21fc --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/alpha/GraderServiceImpl.kt @@ -0,0 +1,103 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.services.blocking.finetuning.alpha + +import com.openai.core.ClientOptions +import com.openai.core.RequestOptions +import com.openai.core.handlers.errorHandler +import com.openai.core.handlers.jsonHandler +import com.openai.core.handlers.withErrorHandler +import com.openai.core.http.HttpMethod +import com.openai.core.http.HttpRequest +import com.openai.core.http.HttpResponse.Handler +import com.openai.core.http.HttpResponseFor +import com.openai.core.http.json +import com.openai.core.http.parseable +import com.openai.core.prepare +import com.openai.models.ErrorObject +import com.openai.models.finetuning.alpha.graders.GraderRunParams +import com.openai.models.finetuning.alpha.graders.GraderRunResponse +import com.openai.models.finetuning.alpha.graders.GraderValidateParams +import com.openai.models.finetuning.alpha.graders.GraderValidateResponse + +class GraderServiceImpl internal constructor(private val clientOptions: ClientOptions) : + GraderService { + + private val withRawResponse: GraderService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): GraderService.WithRawResponse = withRawResponse + + override fun run(params: GraderRunParams, requestOptions: RequestOptions): GraderRunResponse = + // post /fine_tuning/alpha/graders/run + withRawResponse().run(params, requestOptions).parse() + + override fun validate( + params: GraderValidateParams, + requestOptions: RequestOptions, + ): GraderValidateResponse = + // post /fine_tuning/alpha/graders/validate + withRawResponse().validate(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + GraderService.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val runHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun run( + params: GraderRunParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("fine_tuning", "alpha", "graders", "run") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params, deploymentModel = null) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { runHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + + private val validateHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) + + override fun validate( + params: GraderValidateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("fine_tuning", "alpha", "graders", "validate") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params, deploymentModel = null) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { validateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/checkpoints/PermissionService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/checkpoints/PermissionService.kt index 3271fff5..547aa265 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/checkpoints/PermissionService.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/checkpoints/PermissionService.kt @@ -25,6 +25,23 @@ interface PermissionService { * This enables organization owners to share fine-tuned models with other projects in their * organization. */ + fun create( + fineTunedModelCheckpoint: String, + params: PermissionCreateParams, + ): PermissionCreatePage = create(fineTunedModelCheckpoint, params, RequestOptions.none()) + + /** @see [create] */ + fun create( + fineTunedModelCheckpoint: String, + params: PermissionCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): PermissionCreatePage = + create( + params.toBuilder().fineTunedModelCheckpoint(fineTunedModelCheckpoint).build(), + requestOptions, + ) + + /** @see [create] */ fun create(params: PermissionCreateParams): PermissionCreatePage = create(params, RequestOptions.none()) @@ -40,8 +57,26 @@ interface PermissionService { * Organization owners can use this endpoint to view all permissions for a fine-tuned model * checkpoint. */ - fun retrieve(params: PermissionRetrieveParams): PermissionRetrieveResponse = - retrieve(params, RequestOptions.none()) + fun retrieve(fineTunedModelCheckpoint: String): PermissionRetrieveResponse = + retrieve(fineTunedModelCheckpoint, PermissionRetrieveParams.none()) + + /** @see [retrieve] */ + fun retrieve( + fineTunedModelCheckpoint: String, + params: PermissionRetrieveParams = PermissionRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): PermissionRetrieveResponse = + retrieve( + params.toBuilder().fineTunedModelCheckpoint(fineTunedModelCheckpoint).build(), + requestOptions, + ) + + /** @see [retrieve] */ + fun retrieve( + fineTunedModelCheckpoint: String, + params: PermissionRetrieveParams = PermissionRetrieveParams.none(), + ): PermissionRetrieveResponse = + retrieve(fineTunedModelCheckpoint, params, RequestOptions.none()) /** @see [retrieve] */ fun retrieve( @@ -49,12 +84,35 @@ interface PermissionService { requestOptions: RequestOptions = RequestOptions.none(), ): PermissionRetrieveResponse + /** @see [retrieve] */ + fun retrieve(params: PermissionRetrieveParams): PermissionRetrieveResponse = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve( + fineTunedModelCheckpoint: String, + requestOptions: RequestOptions, + ): PermissionRetrieveResponse = + retrieve(fineTunedModelCheckpoint, PermissionRetrieveParams.none(), requestOptions) + /** * **NOTE:** This endpoint requires an [admin API key](../admin-api-keys). * * Organization owners can use this endpoint to delete a permission for a fine-tuned model * checkpoint. */ + fun delete(permissionId: String, params: PermissionDeleteParams): PermissionDeleteResponse = + delete(permissionId, params, RequestOptions.none()) + + /** @see [delete] */ + fun delete( + permissionId: String, + params: PermissionDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): PermissionDeleteResponse = + delete(params.toBuilder().permissionId(permissionId).build(), requestOptions) + + /** @see [delete] */ fun delete(params: PermissionDeleteParams): PermissionDeleteResponse = delete(params, RequestOptions.none()) @@ -73,6 +131,26 @@ interface PermissionService { * same as [PermissionService.create]. */ @MustBeClosed + fun create( + fineTunedModelCheckpoint: String, + params: PermissionCreateParams, + ): HttpResponseFor = + create(fineTunedModelCheckpoint, params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + fineTunedModelCheckpoint: String, + params: PermissionCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + create( + params.toBuilder().fineTunedModelCheckpoint(fineTunedModelCheckpoint).build(), + requestOptions, + ) + + /** @see [create] */ + @MustBeClosed fun create(params: PermissionCreateParams): HttpResponseFor = create(params, RequestOptions.none()) @@ -90,8 +168,29 @@ interface PermissionService { */ @MustBeClosed fun retrieve( - params: PermissionRetrieveParams - ): HttpResponseFor = retrieve(params, RequestOptions.none()) + fineTunedModelCheckpoint: String + ): HttpResponseFor = + retrieve(fineTunedModelCheckpoint, PermissionRetrieveParams.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + fineTunedModelCheckpoint: String, + params: PermissionRetrieveParams = PermissionRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + retrieve( + params.toBuilder().fineTunedModelCheckpoint(fineTunedModelCheckpoint).build(), + requestOptions, + ) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + fineTunedModelCheckpoint: String, + params: PermissionRetrieveParams = PermissionRetrieveParams.none(), + ): HttpResponseFor = + retrieve(fineTunedModelCheckpoint, params, RequestOptions.none()) /** @see [retrieve] */ @MustBeClosed @@ -100,12 +199,43 @@ interface PermissionService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: PermissionRetrieveParams + ): HttpResponseFor = retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + fineTunedModelCheckpoint: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + retrieve(fineTunedModelCheckpoint, PermissionRetrieveParams.none(), requestOptions) + /** * Returns a raw HTTP response for `delete * /fine_tuning/checkpoints/{fine_tuned_model_checkpoint}/permissions/{permission_id}`, but * is otherwise the same as [PermissionService.delete]. */ @MustBeClosed + fun delete( + permissionId: String, + params: PermissionDeleteParams, + ): HttpResponseFor = + delete(permissionId, params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + permissionId: String, + params: PermissionDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + delete(params.toBuilder().permissionId(permissionId).build(), requestOptions) + + /** @see [delete] */ + @MustBeClosed fun delete(params: PermissionDeleteParams): HttpResponseFor = delete(params, RequestOptions.none()) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/checkpoints/PermissionServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/checkpoints/PermissionServiceImpl.kt index 7b809268..6ac2f12e 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/checkpoints/PermissionServiceImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/checkpoints/PermissionServiceImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.blocking.finetuning.checkpoints import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -22,6 +23,7 @@ import com.openai.models.finetuning.checkpoints.permissions.PermissionDeletePara import com.openai.models.finetuning.checkpoints.permissions.PermissionDeleteResponse import com.openai.models.finetuning.checkpoints.permissions.PermissionRetrieveParams import com.openai.models.finetuning.checkpoints.permissions.PermissionRetrieveResponse +import kotlin.jvm.optionals.getOrNull class PermissionServiceImpl internal constructor(private val clientOptions: ClientOptions) : PermissionService { @@ -66,6 +68,9 @@ class PermissionServiceImpl internal constructor(private val clientOptions: Clie params: PermissionCreateParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("fineTunedModelCheckpoint", params.fineTunedModelCheckpoint().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -106,6 +111,9 @@ class PermissionServiceImpl internal constructor(private val clientOptions: Clie params: PermissionRetrieveParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("fineTunedModelCheckpoint", params.fineTunedModelCheckpoint().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -138,6 +146,9 @@ class PermissionServiceImpl internal constructor(private val clientOptions: Clie params: PermissionDeleteParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("permissionId", params.permissionId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.DELETE) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/jobs/CheckpointService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/jobs/CheckpointService.kt index 125b06c9..48717773 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/jobs/CheckpointService.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/jobs/CheckpointService.kt @@ -16,7 +16,22 @@ interface CheckpointService { fun withRawResponse(): WithRawResponse /** List checkpoints for a fine-tuning job. */ - fun list(params: CheckpointListParams): CheckpointListPage = list(params, RequestOptions.none()) + fun list(fineTuningJobId: String): CheckpointListPage = + list(fineTuningJobId, CheckpointListParams.none()) + + /** @see [list] */ + fun list( + fineTuningJobId: String, + params: CheckpointListParams = CheckpointListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CheckpointListPage = + list(params.toBuilder().fineTuningJobId(fineTuningJobId).build(), requestOptions) + + /** @see [list] */ + fun list( + fineTuningJobId: String, + params: CheckpointListParams = CheckpointListParams.none(), + ): CheckpointListPage = list(fineTuningJobId, params, RequestOptions.none()) /** @see [list] */ fun list( @@ -24,6 +39,13 @@ interface CheckpointService { requestOptions: RequestOptions = RequestOptions.none(), ): CheckpointListPage + /** @see [list] */ + fun list(params: CheckpointListParams): CheckpointListPage = list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(fineTuningJobId: String, requestOptions: RequestOptions): CheckpointListPage = + list(fineTuningJobId, CheckpointListParams.none(), requestOptions) + /** A view of [CheckpointService] that provides access to raw HTTP responses for each method. */ interface WithRawResponse { @@ -32,8 +54,25 @@ interface CheckpointService { * but is otherwise the same as [CheckpointService.list]. */ @MustBeClosed - fun list(params: CheckpointListParams): HttpResponseFor = - list(params, RequestOptions.none()) + fun list(fineTuningJobId: String): HttpResponseFor = + list(fineTuningJobId, CheckpointListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + fineTuningJobId: String, + params: CheckpointListParams = CheckpointListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + list(params.toBuilder().fineTuningJobId(fineTuningJobId).build(), requestOptions) + + /** @see [list] */ + @MustBeClosed + fun list( + fineTuningJobId: String, + params: CheckpointListParams = CheckpointListParams.none(), + ): HttpResponseFor = + list(fineTuningJobId, params, RequestOptions.none()) /** @see [list] */ @MustBeClosed @@ -41,5 +80,18 @@ interface CheckpointService { params: CheckpointListParams, requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + + /** @see [list] */ + @MustBeClosed + fun list(params: CheckpointListParams): HttpResponseFor = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + fineTuningJobId: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + list(fineTuningJobId, CheckpointListParams.none(), requestOptions) } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/jobs/CheckpointServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/jobs/CheckpointServiceImpl.kt index 34d91dc8..23fe2d2d 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/jobs/CheckpointServiceImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/jobs/CheckpointServiceImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.blocking.finetuning.jobs import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -17,6 +18,7 @@ import com.openai.models.ErrorObject import com.openai.models.finetuning.jobs.checkpoints.CheckpointListPage import com.openai.models.finetuning.jobs.checkpoints.CheckpointListPageResponse import com.openai.models.finetuning.jobs.checkpoints.CheckpointListParams +import kotlin.jvm.optionals.getOrNull class CheckpointServiceImpl internal constructor(private val clientOptions: ClientOptions) : CheckpointService { @@ -47,6 +49,9 @@ class CheckpointServiceImpl internal constructor(private val clientOptions: Clie params: CheckpointListParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("fineTuningJobId", params.fineTuningJobId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/graders/GraderModelService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/graders/GraderModelService.kt new file mode 100644 index 00000000..40f334c4 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/graders/GraderModelService.kt @@ -0,0 +1,16 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.services.blocking.graders + +interface GraderModelService { + + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + + /** + * A view of [GraderModelService] that provides access to raw HTTP responses for each method. + */ + interface WithRawResponse +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/graders/GraderModelServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/graders/GraderModelServiceImpl.kt new file mode 100644 index 00000000..01f3f0d1 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/graders/GraderModelServiceImpl.kt @@ -0,0 +1,18 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.services.blocking.graders + +import com.openai.core.ClientOptions + +class GraderModelServiceImpl internal constructor(private val clientOptions: ClientOptions) : + GraderModelService { + + private val withRawResponse: GraderModelService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): GraderModelService.WithRawResponse = withRawResponse + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + GraderModelService.WithRawResponse +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/responses/InputItemService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/responses/InputItemService.kt index bbfab36e..81690e16 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/responses/InputItemService.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/responses/InputItemService.kt @@ -16,7 +16,20 @@ interface InputItemService { fun withRawResponse(): WithRawResponse /** Returns a list of input items for a given response. */ - fun list(params: InputItemListParams): InputItemListPage = list(params, RequestOptions.none()) + fun list(responseId: String): InputItemListPage = list(responseId, InputItemListParams.none()) + + /** @see [list] */ + fun list( + responseId: String, + params: InputItemListParams = InputItemListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): InputItemListPage = list(params.toBuilder().responseId(responseId).build(), requestOptions) + + /** @see [list] */ + fun list( + responseId: String, + params: InputItemListParams = InputItemListParams.none(), + ): InputItemListPage = list(responseId, params, RequestOptions.none()) /** @see [list] */ fun list( @@ -24,6 +37,13 @@ interface InputItemService { requestOptions: RequestOptions = RequestOptions.none(), ): InputItemListPage + /** @see [list] */ + fun list(params: InputItemListParams): InputItemListPage = list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(responseId: String, requestOptions: RequestOptions): InputItemListPage = + list(responseId, InputItemListParams.none(), requestOptions) + /** A view of [InputItemService] that provides access to raw HTTP responses for each method. */ interface WithRawResponse { @@ -32,8 +52,24 @@ interface InputItemService { * otherwise the same as [InputItemService.list]. */ @MustBeClosed - fun list(params: InputItemListParams): HttpResponseFor = - list(params, RequestOptions.none()) + fun list(responseId: String): HttpResponseFor = + list(responseId, InputItemListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + responseId: String, + params: InputItemListParams = InputItemListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + list(params.toBuilder().responseId(responseId).build(), requestOptions) + + /** @see [list] */ + @MustBeClosed + fun list( + responseId: String, + params: InputItemListParams = InputItemListParams.none(), + ): HttpResponseFor = list(responseId, params, RequestOptions.none()) /** @see [list] */ @MustBeClosed @@ -41,5 +77,18 @@ interface InputItemService { params: InputItemListParams, requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + + /** @see [list] */ + @MustBeClosed + fun list(params: InputItemListParams): HttpResponseFor = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + responseId: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + list(responseId, InputItemListParams.none(), requestOptions) } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/responses/InputItemServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/responses/InputItemServiceImpl.kt index 19e1a397..aa535bbc 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/responses/InputItemServiceImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/responses/InputItemServiceImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.blocking.responses import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -17,6 +18,7 @@ import com.openai.models.ErrorObject import com.openai.models.responses.inputitems.InputItemListPage import com.openai.models.responses.inputitems.InputItemListParams import com.openai.models.responses.inputitems.ResponseItemList +import kotlin.jvm.optionals.getOrNull class InputItemServiceImpl internal constructor(private val clientOptions: ClientOptions) : InputItemService { @@ -46,6 +48,9 @@ class InputItemServiceImpl internal constructor(private val clientOptions: Clien params: InputItemListParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("responseId", params.responseId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/uploads/PartService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/uploads/PartService.kt index 1c157e70..a1990493 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/uploads/PartService.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/uploads/PartService.kt @@ -27,6 +27,17 @@ interface PartService { * Parts when you * [complete the Upload](https://platform.openai.com/docs/api-reference/uploads/complete). */ + fun create(uploadId: String, params: PartCreateParams): UploadPart = + create(uploadId, params, RequestOptions.none()) + + /** @see [create] */ + fun create( + uploadId: String, + params: PartCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): UploadPart = create(params.toBuilder().uploadId(uploadId).build(), requestOptions) + + /** @see [create] */ fun create(params: PartCreateParams): UploadPart = create(params, RequestOptions.none()) /** @see [create] */ @@ -43,6 +54,20 @@ interface PartService { * same as [PartService.create]. */ @MustBeClosed + fun create(uploadId: String, params: PartCreateParams): HttpResponseFor = + create(uploadId, params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + uploadId: String, + params: PartCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + create(params.toBuilder().uploadId(uploadId).build(), requestOptions) + + /** @see [create] */ + @MustBeClosed fun create(params: PartCreateParams): HttpResponseFor = create(params, RequestOptions.none()) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/uploads/PartServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/uploads/PartServiceImpl.kt index 0f616b5d..23bf0b68 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/uploads/PartServiceImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/uploads/PartServiceImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.blocking.uploads import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -17,6 +18,7 @@ import com.openai.core.prepare import com.openai.models.ErrorObject import com.openai.models.uploads.parts.PartCreateParams import com.openai.models.uploads.parts.UploadPart +import kotlin.jvm.optionals.getOrNull class PartServiceImpl internal constructor(private val clientOptions: ClientOptions) : PartService { @@ -42,6 +44,9 @@ class PartServiceImpl internal constructor(private val clientOptions: ClientOpti params: PartCreateParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("uploadId", params.uploadId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/vectorstores/FileBatchService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/vectorstores/FileBatchService.kt index 5bf2fe58..2f9f55f5 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/vectorstores/FileBatchService.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/vectorstores/FileBatchService.kt @@ -20,6 +20,18 @@ interface FileBatchService { fun withRawResponse(): WithRawResponse /** Create a vector store file batch. */ + fun create(vectorStoreId: String, params: FileBatchCreateParams): VectorStoreFileBatch = + create(vectorStoreId, params, RequestOptions.none()) + + /** @see [create] */ + fun create( + vectorStoreId: String, + params: FileBatchCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): VectorStoreFileBatch = + create(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) + + /** @see [create] */ fun create(params: FileBatchCreateParams): VectorStoreFileBatch = create(params, RequestOptions.none()) @@ -30,6 +42,17 @@ interface FileBatchService { ): VectorStoreFileBatch /** Retrieves a vector store file batch. */ + fun retrieve(batchId: String, params: FileBatchRetrieveParams): VectorStoreFileBatch = + retrieve(batchId, params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve( + batchId: String, + params: FileBatchRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): VectorStoreFileBatch = retrieve(params.toBuilder().batchId(batchId).build(), requestOptions) + + /** @see [retrieve] */ fun retrieve(params: FileBatchRetrieveParams): VectorStoreFileBatch = retrieve(params, RequestOptions.none()) @@ -43,6 +66,17 @@ interface FileBatchService { * Cancel a vector store file batch. This attempts to cancel the processing of files in this * batch as soon as possible. */ + fun cancel(batchId: String, params: FileBatchCancelParams): VectorStoreFileBatch = + cancel(batchId, params, RequestOptions.none()) + + /** @see [cancel] */ + fun cancel( + batchId: String, + params: FileBatchCancelParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): VectorStoreFileBatch = cancel(params.toBuilder().batchId(batchId).build(), requestOptions) + + /** @see [cancel] */ fun cancel(params: FileBatchCancelParams): VectorStoreFileBatch = cancel(params, RequestOptions.none()) @@ -53,6 +87,18 @@ interface FileBatchService { ): VectorStoreFileBatch /** Returns a list of vector store files in a batch. */ + fun listFiles(batchId: String, params: FileBatchListFilesParams): FileBatchListFilesPage = + listFiles(batchId, params, RequestOptions.none()) + + /** @see [listFiles] */ + fun listFiles( + batchId: String, + params: FileBatchListFilesParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): FileBatchListFilesPage = + listFiles(params.toBuilder().batchId(batchId).build(), requestOptions) + + /** @see [listFiles] */ fun listFiles(params: FileBatchListFilesParams): FileBatchListFilesPage = listFiles(params, RequestOptions.none()) @@ -70,6 +116,23 @@ interface FileBatchService { * is otherwise the same as [FileBatchService.create]. */ @MustBeClosed + fun create( + vectorStoreId: String, + params: FileBatchCreateParams, + ): HttpResponseFor = + create(vectorStoreId, params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + vectorStoreId: String, + params: FileBatchCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + create(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) + + /** @see [create] */ + @MustBeClosed fun create(params: FileBatchCreateParams): HttpResponseFor = create(params, RequestOptions.none()) @@ -86,6 +149,22 @@ interface FileBatchService { * [FileBatchService.retrieve]. */ @MustBeClosed + fun retrieve( + batchId: String, + params: FileBatchRetrieveParams, + ): HttpResponseFor = retrieve(batchId, params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + batchId: String, + params: FileBatchRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + retrieve(params.toBuilder().batchId(batchId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed fun retrieve(params: FileBatchRetrieveParams): HttpResponseFor = retrieve(params, RequestOptions.none()) @@ -102,6 +181,22 @@ interface FileBatchService { * same as [FileBatchService.cancel]. */ @MustBeClosed + fun cancel( + batchId: String, + params: FileBatchCancelParams, + ): HttpResponseFor = cancel(batchId, params, RequestOptions.none()) + + /** @see [cancel] */ + @MustBeClosed + fun cancel( + batchId: String, + params: FileBatchCancelParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + cancel(params.toBuilder().batchId(batchId).build(), requestOptions) + + /** @see [cancel] */ + @MustBeClosed fun cancel(params: FileBatchCancelParams): HttpResponseFor = cancel(params, RequestOptions.none()) @@ -118,6 +213,23 @@ interface FileBatchService { * same as [FileBatchService.listFiles]. */ @MustBeClosed + fun listFiles( + batchId: String, + params: FileBatchListFilesParams, + ): HttpResponseFor = + listFiles(batchId, params, RequestOptions.none()) + + /** @see [listFiles] */ + @MustBeClosed + fun listFiles( + batchId: String, + params: FileBatchListFilesParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + listFiles(params.toBuilder().batchId(batchId).build(), requestOptions) + + /** @see [listFiles] */ + @MustBeClosed fun listFiles(params: FileBatchListFilesParams): HttpResponseFor = listFiles(params, RequestOptions.none()) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/vectorstores/FileBatchServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/vectorstores/FileBatchServiceImpl.kt index 516848c4..edfa1dd2 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/vectorstores/FileBatchServiceImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/vectorstores/FileBatchServiceImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.blocking.vectorstores import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -23,6 +24,7 @@ import com.openai.models.vectorstores.filebatches.FileBatchListFilesPageResponse import com.openai.models.vectorstores.filebatches.FileBatchListFilesParams import com.openai.models.vectorstores.filebatches.FileBatchRetrieveParams import com.openai.models.vectorstores.filebatches.VectorStoreFileBatch +import kotlin.jvm.optionals.getOrNull class FileBatchServiceImpl internal constructor(private val clientOptions: ClientOptions) : FileBatchService { @@ -79,6 +81,9 @@ class FileBatchServiceImpl internal constructor(private val clientOptions: Clien params: FileBatchCreateParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("vectorStoreId", params.vectorStoreId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -108,6 +113,9 @@ class FileBatchServiceImpl internal constructor(private val clientOptions: Clien params: FileBatchRetrieveParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("batchId", params.batchId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -141,6 +149,9 @@ class FileBatchServiceImpl internal constructor(private val clientOptions: Clien params: FileBatchCancelParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("batchId", params.batchId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -176,6 +187,9 @@ class FileBatchServiceImpl internal constructor(private val clientOptions: Clien params: FileBatchListFilesParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("batchId", params.batchId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/vectorstores/FileService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/vectorstores/FileService.kt index 1d081a12..9cb49b69 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/vectorstores/FileService.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/vectorstores/FileService.kt @@ -28,6 +28,18 @@ interface FileService { * [File](https://platform.openai.com/docs/api-reference/files) to a * [vector store](https://platform.openai.com/docs/api-reference/vector-stores/object). */ + fun create(vectorStoreId: String, params: FileCreateParams): VectorStoreFile = + create(vectorStoreId, params, RequestOptions.none()) + + /** @see [create] */ + fun create( + vectorStoreId: String, + params: FileCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): VectorStoreFile = + create(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) + + /** @see [create] */ fun create(params: FileCreateParams): VectorStoreFile = create(params, RequestOptions.none()) /** @see [create] */ @@ -37,6 +49,17 @@ interface FileService { ): VectorStoreFile /** Retrieves a vector store file. */ + fun retrieve(fileId: String, params: FileRetrieveParams): VectorStoreFile = + retrieve(fileId, params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve( + fileId: String, + params: FileRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): VectorStoreFile = retrieve(params.toBuilder().fileId(fileId).build(), requestOptions) + + /** @see [retrieve] */ fun retrieve(params: FileRetrieveParams): VectorStoreFile = retrieve(params, RequestOptions.none()) @@ -47,6 +70,17 @@ interface FileService { ): VectorStoreFile /** Update attributes on a vector store file. */ + fun update(fileId: String, params: FileUpdateParams): VectorStoreFile = + update(fileId, params, RequestOptions.none()) + + /** @see [update] */ + fun update( + fileId: String, + params: FileUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): VectorStoreFile = update(params.toBuilder().fileId(fileId).build(), requestOptions) + + /** @see [update] */ fun update(params: FileUpdateParams): VectorStoreFile = update(params, RequestOptions.none()) /** @see [update] */ @@ -56,7 +90,18 @@ interface FileService { ): VectorStoreFile /** Returns a list of vector store files. */ - fun list(params: FileListParams): FileListPage = list(params, RequestOptions.none()) + fun list(vectorStoreId: String): FileListPage = list(vectorStoreId, FileListParams.none()) + + /** @see [list] */ + fun list( + vectorStoreId: String, + params: FileListParams = FileListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): FileListPage = list(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) + + /** @see [list] */ + fun list(vectorStoreId: String, params: FileListParams = FileListParams.none()): FileListPage = + list(vectorStoreId, params, RequestOptions.none()) /** @see [list] */ fun list( @@ -64,11 +109,29 @@ interface FileService { requestOptions: RequestOptions = RequestOptions.none(), ): FileListPage + /** @see [list] */ + fun list(params: FileListParams): FileListPage = list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(vectorStoreId: String, requestOptions: RequestOptions): FileListPage = + list(vectorStoreId, FileListParams.none(), requestOptions) + /** * Delete a vector store file. This will remove the file from the vector store but the file * itself will not be deleted. To delete the file, use the * [delete file](https://platform.openai.com/docs/api-reference/files/delete) endpoint. */ + fun delete(fileId: String, params: FileDeleteParams): VectorStoreFileDeleted = + delete(fileId, params, RequestOptions.none()) + + /** @see [delete] */ + fun delete( + fileId: String, + params: FileDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): VectorStoreFileDeleted = delete(params.toBuilder().fileId(fileId).build(), requestOptions) + + /** @see [delete] */ fun delete(params: FileDeleteParams): VectorStoreFileDeleted = delete(params, RequestOptions.none()) @@ -79,6 +142,17 @@ interface FileService { ): VectorStoreFileDeleted /** Retrieve the parsed contents of a vector store file. */ + fun content(fileId: String, params: FileContentParams): FileContentPage = + content(fileId, params, RequestOptions.none()) + + /** @see [content] */ + fun content( + fileId: String, + params: FileContentParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): FileContentPage = content(params.toBuilder().fileId(fileId).build(), requestOptions) + + /** @see [content] */ fun content(params: FileContentParams): FileContentPage = content(params, RequestOptions.none()) /** @see [content] */ @@ -95,6 +169,22 @@ interface FileService { * otherwise the same as [FileService.create]. */ @MustBeClosed + fun create( + vectorStoreId: String, + params: FileCreateParams, + ): HttpResponseFor = create(vectorStoreId, params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + vectorStoreId: String, + params: FileCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + create(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) + + /** @see [create] */ + @MustBeClosed fun create(params: FileCreateParams): HttpResponseFor = create(params, RequestOptions.none()) @@ -110,6 +200,20 @@ interface FileService { * but is otherwise the same as [FileService.retrieve]. */ @MustBeClosed + fun retrieve(fileId: String, params: FileRetrieveParams): HttpResponseFor = + retrieve(fileId, params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + fileId: String, + params: FileRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + retrieve(params.toBuilder().fileId(fileId).build(), requestOptions) + + /** @see [retrieve] */ + @MustBeClosed fun retrieve(params: FileRetrieveParams): HttpResponseFor = retrieve(params, RequestOptions.none()) @@ -125,6 +229,20 @@ interface FileService { * but is otherwise the same as [FileService.update]. */ @MustBeClosed + fun update(fileId: String, params: FileUpdateParams): HttpResponseFor = + update(fileId, params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + fileId: String, + params: FileUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + update(params.toBuilder().fileId(fileId).build(), requestOptions) + + /** @see [update] */ + @MustBeClosed fun update(params: FileUpdateParams): HttpResponseFor = update(params, RequestOptions.none()) @@ -140,8 +258,24 @@ interface FileService { * otherwise the same as [FileService.list]. */ @MustBeClosed - fun list(params: FileListParams): HttpResponseFor = - list(params, RequestOptions.none()) + fun list(vectorStoreId: String): HttpResponseFor = + list(vectorStoreId, FileListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + vectorStoreId: String, + params: FileListParams = FileListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + list(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) + + /** @see [list] */ + @MustBeClosed + fun list( + vectorStoreId: String, + params: FileListParams = FileListParams.none(), + ): HttpResponseFor = list(vectorStoreId, params, RequestOptions.none()) /** @see [list] */ @MustBeClosed @@ -150,12 +284,41 @@ interface FileService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** @see [list] */ + @MustBeClosed + fun list(params: FileListParams): HttpResponseFor = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + vectorStoreId: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + list(vectorStoreId, FileListParams.none(), requestOptions) + /** * Returns a raw HTTP response for `delete * /vector_stores/{vector_store_id}/files/{file_id}`, but is otherwise the same as * [FileService.delete]. */ @MustBeClosed + fun delete( + fileId: String, + params: FileDeleteParams, + ): HttpResponseFor = delete(fileId, params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + fileId: String, + params: FileDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + delete(params.toBuilder().fileId(fileId).build(), requestOptions) + + /** @see [delete] */ + @MustBeClosed fun delete(params: FileDeleteParams): HttpResponseFor = delete(params, RequestOptions.none()) @@ -172,6 +335,20 @@ interface FileService { * [FileService.content]. */ @MustBeClosed + fun content(fileId: String, params: FileContentParams): HttpResponseFor = + content(fileId, params, RequestOptions.none()) + + /** @see [content] */ + @MustBeClosed + fun content( + fileId: String, + params: FileContentParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + content(params.toBuilder().fileId(fileId).build(), requestOptions) + + /** @see [content] */ + @MustBeClosed fun content(params: FileContentParams): HttpResponseFor = content(params, RequestOptions.none()) diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/vectorstores/FileServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/vectorstores/FileServiceImpl.kt index c3e9174a..971cf72e 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/vectorstores/FileServiceImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/vectorstores/FileServiceImpl.kt @@ -4,6 +4,7 @@ package com.openai.services.blocking.vectorstores import com.openai.core.ClientOptions import com.openai.core.RequestOptions +import com.openai.core.checkRequired import com.openai.core.handlers.errorHandler import com.openai.core.handlers.jsonHandler import com.openai.core.handlers.withErrorHandler @@ -28,6 +29,7 @@ import com.openai.models.vectorstores.files.FileRetrieveParams import com.openai.models.vectorstores.files.FileUpdateParams import com.openai.models.vectorstores.files.VectorStoreFile import com.openai.models.vectorstores.files.VectorStoreFileDeleted +import kotlin.jvm.optionals.getOrNull class FileServiceImpl internal constructor(private val clientOptions: ClientOptions) : FileService { @@ -87,6 +89,9 @@ class FileServiceImpl internal constructor(private val clientOptions: ClientOpti params: FileCreateParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("vectorStoreId", params.vectorStoreId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -115,6 +120,9 @@ class FileServiceImpl internal constructor(private val clientOptions: ClientOpti params: FileRetrieveParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("fileId", params.fileId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -147,6 +155,9 @@ class FileServiceImpl internal constructor(private val clientOptions: ClientOpti params: FileUpdateParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("fileId", params.fileId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) @@ -181,6 +192,9 @@ class FileServiceImpl internal constructor(private val clientOptions: ClientOpti params: FileListParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("vectorStoreId", params.vectorStoreId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) @@ -216,6 +230,9 @@ class FileServiceImpl internal constructor(private val clientOptions: ClientOpti params: FileDeleteParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("fileId", params.fileId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.DELETE) @@ -250,6 +267,9 @@ class FileServiceImpl internal constructor(private val clientOptions: ClientOpti params: FileContentParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("fileId", params.fileId().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.GET) diff --git a/openai-java-core/src/test/kotlin/com/openai/core/AutoPagerAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/core/AutoPagerAsyncTest.kt new file mode 100644 index 00000000..e9e9137e --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/core/AutoPagerAsyncTest.kt @@ -0,0 +1,182 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.core + +import com.openai.core.http.AsyncStreamResponse +import java.util.Optional +import java.util.concurrent.CompletableFuture +import java.util.concurrent.Executor +import org.assertj.core.api.Assertions.assertThat +import org.assertj.core.api.Assertions.catchThrowable +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import org.mockito.junit.jupiter.MockitoExtension +import org.mockito.kotlin.any +import org.mockito.kotlin.clearInvocations +import org.mockito.kotlin.doAnswer +import org.mockito.kotlin.inOrder +import org.mockito.kotlin.mock +import org.mockito.kotlin.never +import org.mockito.kotlin.spy +import org.mockito.kotlin.times +import org.mockito.kotlin.verify +import org.mockito.kotlin.whenever + +@ExtendWith(MockitoExtension::class) +internal class AutoPagerAsyncTest { + + companion object { + + private val ERROR = RuntimeException("ERROR!") + } + + private class PageAsyncImpl( + private val items: List, + private val hasNext: Boolean = true, + ) : PageAsync { + + val nextPageFuture: CompletableFuture> = CompletableFuture() + + override fun hasNextPage(): Boolean = hasNext + + override fun nextPage(): CompletableFuture> = nextPageFuture + + override fun items(): List = items + } + + private val executor = + spy { + doAnswer { invocation -> invocation.getArgument(0).run() } + .whenever(it) + .execute(any()) + } + private val handler = mock>() + + @Test + fun subscribe_whenAlreadySubscribed_throws() { + val autoPagerAsync = AutoPagerAsync.from(PageAsyncImpl(emptyList()), executor) + autoPagerAsync.subscribe {} + clearInvocations(executor) + + val throwable = catchThrowable { autoPagerAsync.subscribe {} } + + assertThat(throwable).isInstanceOf(IllegalStateException::class.java) + assertThat(throwable).hasMessage("Cannot subscribe more than once") + verify(executor, never()).execute(any()) + } + + @Test + fun subscribe_whenClosed_throws() { + val autoPagerAsync = AutoPagerAsync.from(PageAsyncImpl(emptyList()), executor) + autoPagerAsync.close() + + val throwable = catchThrowable { autoPagerAsync.subscribe {} } + + assertThat(throwable).isInstanceOf(IllegalStateException::class.java) + assertThat(throwable).hasMessage("Cannot subscribe after the response is closed") + verify(executor, never()).execute(any()) + } + + @Test + fun subscribe_whenFirstPageNonEmpty_runsHandler() { + val page = PageAsyncImpl(listOf("item1", "item2", "item3"), hasNext = false) + val autoPagerAsync = AutoPagerAsync.from(page, executor) + + autoPagerAsync.subscribe(handler) + + inOrder(executor, handler) { + verify(executor, times(1)).execute(any()) + verify(handler, times(1)).onNext("item1") + verify(handler, times(1)).onNext("item2") + verify(handler, times(1)).onNext("item3") + verify(handler, times(1)).onComplete(Optional.empty()) + } + } + + @Test + fun subscribe_whenFutureCompletesAfterClose_doesNothing() { + val page = PageAsyncImpl(listOf("page1")) + val autoPagerAsync = AutoPagerAsync.from(page, executor) + autoPagerAsync.subscribe(handler) + autoPagerAsync.close() + + page.nextPageFuture.complete(PageAsyncImpl(listOf("page2"))) + + verify(handler, times(1)).onNext("page1") + verify(handler, never()).onNext("page2") + verify(handler, times(1)).onComplete(Optional.empty()) + verify(executor, times(1)).execute(any()) + } + + @Test + fun subscribe_whenFutureErrors_callsOnComplete() { + val page = PageAsyncImpl(emptyList()) + val autoPagerAsync = AutoPagerAsync.from(page, executor) + autoPagerAsync.subscribe(handler) + + page.nextPageFuture.completeExceptionally(ERROR) + + verify(executor, times(1)).execute(any()) + verify(handler, never()).onNext(any()) + verify(handler, times(1)).onComplete(Optional.of(ERROR)) + } + + @Test + fun subscribe_whenFutureCompletes_runsHandler() { + val page = PageAsyncImpl(listOf("chunk1", "chunk2")) + val autoPagerAsync = AutoPagerAsync.from(page, executor) + + autoPagerAsync.subscribe(handler) + + verify(handler, never()).onComplete(any()) + inOrder(executor, handler) { + verify(executor, times(1)).execute(any()) + verify(handler, times(1)).onNext("chunk1") + verify(handler, times(1)).onNext("chunk2") + } + clearInvocations(executor, handler) + + page.nextPageFuture.complete(PageAsyncImpl(listOf("chunk3", "chunk4"), hasNext = false)) + + verify(executor, never()).execute(any()) + inOrder(handler) { + verify(handler, times(1)).onNext("chunk3") + verify(handler, times(1)).onNext("chunk4") + verify(handler, times(1)).onComplete(Optional.empty()) + } + } + + @Test + fun onCompleteFuture_whenNextPageFutureNotCompleted_onCompleteFutureNotCompleted() { + val page = PageAsyncImpl(listOf("chunk1", "chunk2")) + val autoPagerAsync = AutoPagerAsync.from(page, executor) + autoPagerAsync.subscribe {} + + val onCompletableFuture = autoPagerAsync.onCompleteFuture() + + assertThat(onCompletableFuture).isNotCompleted + } + + @Test + fun onCompleteFuture_whenNextPageFutureErrors_onCompleteFutureCompletedExceptionally() { + val page = PageAsyncImpl(listOf("chunk1", "chunk2")) + val autoPagerAsync = AutoPagerAsync.from(page, executor) + autoPagerAsync.subscribe {} + page.nextPageFuture.completeExceptionally(ERROR) + + val onCompletableFuture = autoPagerAsync.onCompleteFuture() + + assertThat(onCompletableFuture).isCompletedExceptionally + } + + @Test + fun onCompleteFuture_whenNoNextPage_onCompleteFutureCompleted() { + val page = PageAsyncImpl(listOf("chunk1", "chunk2"), hasNext = false) + val autoPagerAsync = AutoPagerAsync.from(page, executor) + autoPagerAsync.subscribe {} + + val onCompletableFuture = autoPagerAsync.onCompleteFuture() + + assertThat(onCompletableFuture).isCompleted + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/core/AutoPagerTest.kt b/openai-java-core/src/test/kotlin/com/openai/core/AutoPagerTest.kt new file mode 100644 index 00000000..17e58632 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/core/AutoPagerTest.kt @@ -0,0 +1,41 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.core + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class AutoPagerTest { + + private class PageImpl( + private val items: List, + private val nextPage: Page? = null, + ) : Page { + + override fun hasNextPage(): Boolean = nextPage != null + + override fun nextPage(): Page = nextPage!! + + override fun items(): List = items + } + + @Test + fun iterator() { + val firstPage = + PageImpl(listOf("chunk1", "chunk2"), nextPage = PageImpl(listOf("chunk3", "chunk4"))) + + val autoPager = AutoPager.from(firstPage) + + assertThat(autoPager).containsExactly("chunk1", "chunk2", "chunk3", "chunk4") + } + + @Test + fun stream() { + val firstPage = + PageImpl(listOf("chunk1", "chunk2"), nextPage = PageImpl(listOf("chunk3", "chunk4"))) + + val autoPager = AutoPager.from(firstPage) + + assertThat(autoPager.stream()).containsExactly("chunk1", "chunk2", "chunk3", "chunk4") + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/audio/transcriptions/TranscriptionCreateResponseTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/audio/transcriptions/TranscriptionCreateResponseTest.kt index 0a7c3f77..8f64d432 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/audio/transcriptions/TranscriptionCreateResponseTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/audio/transcriptions/TranscriptionCreateResponseTest.kt @@ -66,18 +66,18 @@ internal class TranscriptionCreateResponseTest { .addSegment( TranscriptionSegment.builder() .id(0L) - .avgLogprob(0.0) - .compressionRatio(0.0) - .end(0.0) - .noSpeechProb(0.0) + .avgLogprob(0.0f) + .compressionRatio(0.0f) + .end(0.0f) + .noSpeechProb(0.0f) .seek(0L) - .start(0.0) - .temperature(0.0) + .start(0.0f) + .temperature(0.0f) .text("text") .addToken(0L) .build() ) - .addWord(TranscriptionWord.builder().end(0.0).start(0.0).word("word").build()) + .addWord(TranscriptionWord.builder().end(0.0f).start(0.0f).word("word").build()) .build() val transcriptionCreateResponse = TranscriptionCreateResponse.ofVerbose(verbose) @@ -98,18 +98,18 @@ internal class TranscriptionCreateResponseTest { .addSegment( TranscriptionSegment.builder() .id(0L) - .avgLogprob(0.0) - .compressionRatio(0.0) - .end(0.0) - .noSpeechProb(0.0) + .avgLogprob(0.0f) + .compressionRatio(0.0f) + .end(0.0f) + .noSpeechProb(0.0f) .seek(0L) - .start(0.0) - .temperature(0.0) + .start(0.0f) + .temperature(0.0f) .text("text") .addToken(0L) .build() ) - .addWord(TranscriptionWord.builder().end(0.0).start(0.0).word("word").build()) + .addWord(TranscriptionWord.builder().end(0.0f).start(0.0f).word("word").build()) .build() ) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/audio/transcriptions/TranscriptionSegmentTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/audio/transcriptions/TranscriptionSegmentTest.kt index 127ee6b9..85eef238 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/audio/transcriptions/TranscriptionSegmentTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/audio/transcriptions/TranscriptionSegmentTest.kt @@ -14,25 +14,25 @@ internal class TranscriptionSegmentTest { val transcriptionSegment = TranscriptionSegment.builder() .id(0L) - .avgLogprob(0.0) - .compressionRatio(0.0) - .end(0.0) - .noSpeechProb(0.0) + .avgLogprob(0.0f) + .compressionRatio(0.0f) + .end(0.0f) + .noSpeechProb(0.0f) .seek(0L) - .start(0.0) - .temperature(0.0) + .start(0.0f) + .temperature(0.0f) .text("text") .addToken(0L) .build() assertThat(transcriptionSegment.id()).isEqualTo(0L) - assertThat(transcriptionSegment.avgLogprob()).isEqualTo(0.0) - assertThat(transcriptionSegment.compressionRatio()).isEqualTo(0.0) - assertThat(transcriptionSegment.end()).isEqualTo(0.0) - assertThat(transcriptionSegment.noSpeechProb()).isEqualTo(0.0) + assertThat(transcriptionSegment.avgLogprob()).isEqualTo(0.0f) + assertThat(transcriptionSegment.compressionRatio()).isEqualTo(0.0f) + assertThat(transcriptionSegment.end()).isEqualTo(0.0f) + assertThat(transcriptionSegment.noSpeechProb()).isEqualTo(0.0f) assertThat(transcriptionSegment.seek()).isEqualTo(0L) - assertThat(transcriptionSegment.start()).isEqualTo(0.0) - assertThat(transcriptionSegment.temperature()).isEqualTo(0.0) + assertThat(transcriptionSegment.start()).isEqualTo(0.0f) + assertThat(transcriptionSegment.temperature()).isEqualTo(0.0f) assertThat(transcriptionSegment.text()).isEqualTo("text") assertThat(transcriptionSegment.tokens()).containsExactly(0L) } @@ -43,13 +43,13 @@ internal class TranscriptionSegmentTest { val transcriptionSegment = TranscriptionSegment.builder() .id(0L) - .avgLogprob(0.0) - .compressionRatio(0.0) - .end(0.0) - .noSpeechProb(0.0) + .avgLogprob(0.0f) + .compressionRatio(0.0f) + .end(0.0f) + .noSpeechProb(0.0f) .seek(0L) - .start(0.0) - .temperature(0.0) + .start(0.0f) + .temperature(0.0f) .text("text") .addToken(0L) .build() diff --git a/openai-java-core/src/test/kotlin/com/openai/models/audio/transcriptions/TranscriptionVerboseTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/audio/transcriptions/TranscriptionVerboseTest.kt index 6c3ceef9..8f0a543f 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/audio/transcriptions/TranscriptionVerboseTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/audio/transcriptions/TranscriptionVerboseTest.kt @@ -20,18 +20,18 @@ internal class TranscriptionVerboseTest { .addSegment( TranscriptionSegment.builder() .id(0L) - .avgLogprob(0.0) - .compressionRatio(0.0) - .end(0.0) - .noSpeechProb(0.0) + .avgLogprob(0.0f) + .compressionRatio(0.0f) + .end(0.0f) + .noSpeechProb(0.0f) .seek(0L) - .start(0.0) - .temperature(0.0) + .start(0.0f) + .temperature(0.0f) .text("text") .addToken(0L) .build() ) - .addWord(TranscriptionWord.builder().end(0.0).start(0.0).word("word").build()) + .addWord(TranscriptionWord.builder().end(0.0f).start(0.0f).word("word").build()) .build() assertThat(transcriptionVerbose.duration()).isEqualTo(0.0) @@ -41,19 +41,19 @@ internal class TranscriptionVerboseTest { .containsExactly( TranscriptionSegment.builder() .id(0L) - .avgLogprob(0.0) - .compressionRatio(0.0) - .end(0.0) - .noSpeechProb(0.0) + .avgLogprob(0.0f) + .compressionRatio(0.0f) + .end(0.0f) + .noSpeechProb(0.0f) .seek(0L) - .start(0.0) - .temperature(0.0) + .start(0.0f) + .temperature(0.0f) .text("text") .addToken(0L) .build() ) assertThat(transcriptionVerbose.words().getOrNull()) - .containsExactly(TranscriptionWord.builder().end(0.0).start(0.0).word("word").build()) + .containsExactly(TranscriptionWord.builder().end(0.0f).start(0.0f).word("word").build()) } @Test @@ -67,18 +67,18 @@ internal class TranscriptionVerboseTest { .addSegment( TranscriptionSegment.builder() .id(0L) - .avgLogprob(0.0) - .compressionRatio(0.0) - .end(0.0) - .noSpeechProb(0.0) + .avgLogprob(0.0f) + .compressionRatio(0.0f) + .end(0.0f) + .noSpeechProb(0.0f) .seek(0L) - .start(0.0) - .temperature(0.0) + .start(0.0f) + .temperature(0.0f) .text("text") .addToken(0L) .build() ) - .addWord(TranscriptionWord.builder().end(0.0).start(0.0).word("word").build()) + .addWord(TranscriptionWord.builder().end(0.0f).start(0.0f).word("word").build()) .build() val roundtrippedTranscriptionVerbose = diff --git a/openai-java-core/src/test/kotlin/com/openai/models/audio/transcriptions/TranscriptionWordTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/audio/transcriptions/TranscriptionWordTest.kt index 0bf1311a..518a754e 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/audio/transcriptions/TranscriptionWordTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/audio/transcriptions/TranscriptionWordTest.kt @@ -11,17 +11,19 @@ internal class TranscriptionWordTest { @Test fun create() { - val transcriptionWord = TranscriptionWord.builder().end(0.0).start(0.0).word("word").build() + val transcriptionWord = + TranscriptionWord.builder().end(0.0f).start(0.0f).word("word").build() - assertThat(transcriptionWord.end()).isEqualTo(0.0) - assertThat(transcriptionWord.start()).isEqualTo(0.0) + assertThat(transcriptionWord.end()).isEqualTo(0.0f) + assertThat(transcriptionWord.start()).isEqualTo(0.0f) assertThat(transcriptionWord.word()).isEqualTo("word") } @Test fun roundtrip() { val jsonMapper = jsonMapper() - val transcriptionWord = TranscriptionWord.builder().end(0.0).start(0.0).word("word").build() + val transcriptionWord = + TranscriptionWord.builder().end(0.0f).start(0.0f).word("word").build() val roundtrippedTranscriptionWord = jsonMapper.readValue( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/audio/translations/TranslationCreateResponseTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/audio/translations/TranslationCreateResponseTest.kt index 53fc2b4f..098a9b84 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/audio/translations/TranslationCreateResponseTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/audio/translations/TranslationCreateResponseTest.kt @@ -50,13 +50,13 @@ internal class TranslationCreateResponseTest { .addSegment( TranscriptionSegment.builder() .id(0L) - .avgLogprob(0.0) - .compressionRatio(0.0) - .end(0.0) - .noSpeechProb(0.0) + .avgLogprob(0.0f) + .compressionRatio(0.0f) + .end(0.0f) + .noSpeechProb(0.0f) .seek(0L) - .start(0.0) - .temperature(0.0) + .start(0.0f) + .temperature(0.0f) .text("text") .addToken(0L) .build() @@ -81,13 +81,13 @@ internal class TranslationCreateResponseTest { .addSegment( TranscriptionSegment.builder() .id(0L) - .avgLogprob(0.0) - .compressionRatio(0.0) - .end(0.0) - .noSpeechProb(0.0) + .avgLogprob(0.0f) + .compressionRatio(0.0f) + .end(0.0f) + .noSpeechProb(0.0f) .seek(0L) - .start(0.0) - .temperature(0.0) + .start(0.0f) + .temperature(0.0f) .text("text") .addToken(0L) .build() diff --git a/openai-java-core/src/test/kotlin/com/openai/models/audio/translations/TranslationVerboseTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/audio/translations/TranslationVerboseTest.kt index fc5baf5d..7b318663 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/audio/translations/TranslationVerboseTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/audio/translations/TranslationVerboseTest.kt @@ -21,13 +21,13 @@ internal class TranslationVerboseTest { .addSegment( TranscriptionSegment.builder() .id(0L) - .avgLogprob(0.0) - .compressionRatio(0.0) - .end(0.0) - .noSpeechProb(0.0) + .avgLogprob(0.0f) + .compressionRatio(0.0f) + .end(0.0f) + .noSpeechProb(0.0f) .seek(0L) - .start(0.0) - .temperature(0.0) + .start(0.0f) + .temperature(0.0f) .text("text") .addToken(0L) .build() @@ -41,13 +41,13 @@ internal class TranslationVerboseTest { .containsExactly( TranscriptionSegment.builder() .id(0L) - .avgLogprob(0.0) - .compressionRatio(0.0) - .end(0.0) - .noSpeechProb(0.0) + .avgLogprob(0.0f) + .compressionRatio(0.0f) + .end(0.0f) + .noSpeechProb(0.0f) .seek(0L) - .start(0.0) - .temperature(0.0) + .start(0.0f) + .temperature(0.0f) .text("text") .addToken(0L) .build() @@ -65,13 +65,13 @@ internal class TranslationVerboseTest { .addSegment( TranscriptionSegment.builder() .id(0L) - .avgLogprob(0.0) - .compressionRatio(0.0) - .end(0.0) - .noSpeechProb(0.0) + .avgLogprob(0.0f) + .compressionRatio(0.0f) + .end(0.0f) + .noSpeechProb(0.0f) .seek(0L) - .start(0.0) - .temperature(0.0) + .start(0.0f) + .temperature(0.0f) .text("text") .addToken(0L) .build() diff --git a/openai-java-core/src/test/kotlin/com/openai/models/evals/EvalCreateResponseTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/evals/EvalCreateResponseTest.kt index 8d2a3a39..208c7d65 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/evals/EvalCreateResponseTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/evals/EvalCreateResponseTest.kt @@ -5,6 +5,7 @@ package com.openai.models.evals import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import com.openai.core.JsonValue import com.openai.core.jsonMapper +import com.openai.models.graders.gradermodels.LabelModelGrader import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test @@ -28,12 +29,12 @@ internal class EvalCreateResponseTest { ) .name("Chatbot effectiveness Evaluation") .addTestingCriterion( - EvalLabelModelGrader.builder() + LabelModelGrader.builder() .addInput( - EvalLabelModelGrader.Input.builder() + LabelModelGrader.Input.builder() .content("string") - .role(EvalLabelModelGrader.Input.Role.USER) - .type(EvalLabelModelGrader.Input.Type.MESSAGE) + .role(LabelModelGrader.Input.Role.USER) + .type(LabelModelGrader.Input.Type.MESSAGE) .build() ) .addLabel("string") @@ -67,13 +68,13 @@ internal class EvalCreateResponseTest { assertThat(evalCreateResponse.name()).isEqualTo("Chatbot effectiveness Evaluation") assertThat(evalCreateResponse.testingCriteria()) .containsExactly( - EvalCreateResponse.TestingCriterion.ofLabelModel( - EvalLabelModelGrader.builder() + EvalCreateResponse.TestingCriterion.ofLabelModelGrader( + LabelModelGrader.builder() .addInput( - EvalLabelModelGrader.Input.builder() + LabelModelGrader.Input.builder() .content("string") - .role(EvalLabelModelGrader.Input.Role.USER) - .type(EvalLabelModelGrader.Input.Type.MESSAGE) + .role(LabelModelGrader.Input.Role.USER) + .type(LabelModelGrader.Input.Type.MESSAGE) .build() ) .addLabel("string") @@ -104,12 +105,12 @@ internal class EvalCreateResponseTest { ) .name("Chatbot effectiveness Evaluation") .addTestingCriterion( - EvalLabelModelGrader.builder() + LabelModelGrader.builder() .addInput( - EvalLabelModelGrader.Input.builder() + LabelModelGrader.Input.builder() .content("string") - .role(EvalLabelModelGrader.Input.Role.USER) - .type(EvalLabelModelGrader.Input.Type.MESSAGE) + .role(LabelModelGrader.Input.Role.USER) + .type(LabelModelGrader.Input.Type.MESSAGE) .build() ) .addLabel("string") diff --git a/openai-java-core/src/test/kotlin/com/openai/models/evals/EvalLabelModelGraderTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/evals/EvalLabelModelGraderTest.kt deleted file mode 100644 index 06becabb..00000000 --- a/openai-java-core/src/test/kotlin/com/openai/models/evals/EvalLabelModelGraderTest.kt +++ /dev/null @@ -1,69 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.openai.models.evals - -import com.fasterxml.jackson.module.kotlin.jacksonTypeRef -import com.openai.core.jsonMapper -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -internal class EvalLabelModelGraderTest { - - @Test - fun create() { - val evalLabelModelGrader = - EvalLabelModelGrader.builder() - .addInput( - EvalLabelModelGrader.Input.builder() - .content("string") - .role(EvalLabelModelGrader.Input.Role.USER) - .type(EvalLabelModelGrader.Input.Type.MESSAGE) - .build() - ) - .addLabel("string") - .model("model") - .name("name") - .addPassingLabel("string") - .build() - - assertThat(evalLabelModelGrader.input()) - .containsExactly( - EvalLabelModelGrader.Input.builder() - .content("string") - .role(EvalLabelModelGrader.Input.Role.USER) - .type(EvalLabelModelGrader.Input.Type.MESSAGE) - .build() - ) - assertThat(evalLabelModelGrader.labels()).containsExactly("string") - assertThat(evalLabelModelGrader.model()).isEqualTo("model") - assertThat(evalLabelModelGrader.name()).isEqualTo("name") - assertThat(evalLabelModelGrader.passingLabels()).containsExactly("string") - } - - @Test - fun roundtrip() { - val jsonMapper = jsonMapper() - val evalLabelModelGrader = - EvalLabelModelGrader.builder() - .addInput( - EvalLabelModelGrader.Input.builder() - .content("string") - .role(EvalLabelModelGrader.Input.Role.USER) - .type(EvalLabelModelGrader.Input.Type.MESSAGE) - .build() - ) - .addLabel("string") - .model("model") - .name("name") - .addPassingLabel("string") - .build() - - val roundtrippedEvalLabelModelGrader = - jsonMapper.readValue( - jsonMapper.writeValueAsString(evalLabelModelGrader), - jacksonTypeRef(), - ) - - assertThat(roundtrippedEvalLabelModelGrader).isEqualTo(evalLabelModelGrader) - } -} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/evals/EvalListPageResponseTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/evals/EvalListPageResponseTest.kt index a063219c..10d5eddb 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/evals/EvalListPageResponseTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/evals/EvalListPageResponseTest.kt @@ -5,6 +5,7 @@ package com.openai.models.evals import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import com.openai.core.JsonValue import com.openai.core.jsonMapper +import com.openai.models.graders.gradermodels.LabelModelGrader import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test @@ -30,12 +31,12 @@ internal class EvalListPageResponseTest { ) .name("Chatbot effectiveness Evaluation") .addTestingCriterion( - EvalLabelModelGrader.builder() + LabelModelGrader.builder() .addInput( - EvalLabelModelGrader.Input.builder() + LabelModelGrader.Input.builder() .content("string") - .role(EvalLabelModelGrader.Input.Role.USER) - .type(EvalLabelModelGrader.Input.Type.MESSAGE) + .role(LabelModelGrader.Input.Role.USER) + .type(LabelModelGrader.Input.Type.MESSAGE) .build() ) .addLabel("string") @@ -68,12 +69,12 @@ internal class EvalListPageResponseTest { ) .name("Chatbot effectiveness Evaluation") .addTestingCriterion( - EvalLabelModelGrader.builder() + LabelModelGrader.builder() .addInput( - EvalLabelModelGrader.Input.builder() + LabelModelGrader.Input.builder() .content("string") - .role(EvalLabelModelGrader.Input.Role.USER) - .type(EvalLabelModelGrader.Input.Type.MESSAGE) + .role(LabelModelGrader.Input.Role.USER) + .type(LabelModelGrader.Input.Type.MESSAGE) .build() ) .addLabel("string") @@ -110,12 +111,12 @@ internal class EvalListPageResponseTest { ) .name("Chatbot effectiveness Evaluation") .addTestingCriterion( - EvalLabelModelGrader.builder() + LabelModelGrader.builder() .addInput( - EvalLabelModelGrader.Input.builder() + LabelModelGrader.Input.builder() .content("string") - .role(EvalLabelModelGrader.Input.Role.USER) - .type(EvalLabelModelGrader.Input.Type.MESSAGE) + .role(LabelModelGrader.Input.Role.USER) + .type(LabelModelGrader.Input.Type.MESSAGE) .build() ) .addLabel("string") diff --git a/openai-java-core/src/test/kotlin/com/openai/models/evals/EvalListResponseTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/evals/EvalListResponseTest.kt index a8835011..11f418a8 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/evals/EvalListResponseTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/evals/EvalListResponseTest.kt @@ -5,6 +5,7 @@ package com.openai.models.evals import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import com.openai.core.JsonValue import com.openai.core.jsonMapper +import com.openai.models.graders.gradermodels.LabelModelGrader import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test @@ -28,12 +29,12 @@ internal class EvalListResponseTest { ) .name("Chatbot effectiveness Evaluation") .addTestingCriterion( - EvalLabelModelGrader.builder() + LabelModelGrader.builder() .addInput( - EvalLabelModelGrader.Input.builder() + LabelModelGrader.Input.builder() .content("string") - .role(EvalLabelModelGrader.Input.Role.USER) - .type(EvalLabelModelGrader.Input.Type.MESSAGE) + .role(LabelModelGrader.Input.Role.USER) + .type(LabelModelGrader.Input.Type.MESSAGE) .build() ) .addLabel("string") @@ -67,13 +68,13 @@ internal class EvalListResponseTest { assertThat(evalListResponse.name()).isEqualTo("Chatbot effectiveness Evaluation") assertThat(evalListResponse.testingCriteria()) .containsExactly( - EvalListResponse.TestingCriterion.ofLabelModel( - EvalLabelModelGrader.builder() + EvalListResponse.TestingCriterion.ofLabelModelGrader( + LabelModelGrader.builder() .addInput( - EvalLabelModelGrader.Input.builder() + LabelModelGrader.Input.builder() .content("string") - .role(EvalLabelModelGrader.Input.Role.USER) - .type(EvalLabelModelGrader.Input.Type.MESSAGE) + .role(LabelModelGrader.Input.Role.USER) + .type(LabelModelGrader.Input.Type.MESSAGE) .build() ) .addLabel("string") @@ -104,12 +105,12 @@ internal class EvalListResponseTest { ) .name("Chatbot effectiveness Evaluation") .addTestingCriterion( - EvalLabelModelGrader.builder() + LabelModelGrader.builder() .addInput( - EvalLabelModelGrader.Input.builder() + LabelModelGrader.Input.builder() .content("string") - .role(EvalLabelModelGrader.Input.Role.USER) - .type(EvalLabelModelGrader.Input.Type.MESSAGE) + .role(LabelModelGrader.Input.Role.USER) + .type(LabelModelGrader.Input.Type.MESSAGE) .build() ) .addLabel("string") diff --git a/openai-java-core/src/test/kotlin/com/openai/models/evals/EvalRetrieveResponseTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/evals/EvalRetrieveResponseTest.kt index dcf6e03c..3838a4d0 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/evals/EvalRetrieveResponseTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/evals/EvalRetrieveResponseTest.kt @@ -5,6 +5,7 @@ package com.openai.models.evals import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import com.openai.core.JsonValue import com.openai.core.jsonMapper +import com.openai.models.graders.gradermodels.LabelModelGrader import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test @@ -28,12 +29,12 @@ internal class EvalRetrieveResponseTest { ) .name("Chatbot effectiveness Evaluation") .addTestingCriterion( - EvalLabelModelGrader.builder() + LabelModelGrader.builder() .addInput( - EvalLabelModelGrader.Input.builder() + LabelModelGrader.Input.builder() .content("string") - .role(EvalLabelModelGrader.Input.Role.USER) - .type(EvalLabelModelGrader.Input.Type.MESSAGE) + .role(LabelModelGrader.Input.Role.USER) + .type(LabelModelGrader.Input.Type.MESSAGE) .build() ) .addLabel("string") @@ -67,13 +68,13 @@ internal class EvalRetrieveResponseTest { assertThat(evalRetrieveResponse.name()).isEqualTo("Chatbot effectiveness Evaluation") assertThat(evalRetrieveResponse.testingCriteria()) .containsExactly( - EvalRetrieveResponse.TestingCriterion.ofLabelModel( - EvalLabelModelGrader.builder() + EvalRetrieveResponse.TestingCriterion.ofLabelModelGrader( + LabelModelGrader.builder() .addInput( - EvalLabelModelGrader.Input.builder() + LabelModelGrader.Input.builder() .content("string") - .role(EvalLabelModelGrader.Input.Role.USER) - .type(EvalLabelModelGrader.Input.Type.MESSAGE) + .role(LabelModelGrader.Input.Role.USER) + .type(LabelModelGrader.Input.Type.MESSAGE) .build() ) .addLabel("string") @@ -104,12 +105,12 @@ internal class EvalRetrieveResponseTest { ) .name("Chatbot effectiveness Evaluation") .addTestingCriterion( - EvalLabelModelGrader.builder() + LabelModelGrader.builder() .addInput( - EvalLabelModelGrader.Input.builder() + LabelModelGrader.Input.builder() .content("string") - .role(EvalLabelModelGrader.Input.Role.USER) - .type(EvalLabelModelGrader.Input.Type.MESSAGE) + .role(LabelModelGrader.Input.Role.USER) + .type(LabelModelGrader.Input.Type.MESSAGE) .build() ) .addLabel("string") diff --git a/openai-java-core/src/test/kotlin/com/openai/models/evals/EvalStringCheckGraderTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/evals/EvalStringCheckGraderTest.kt deleted file mode 100644 index d15819ad..00000000 --- a/openai-java-core/src/test/kotlin/com/openai/models/evals/EvalStringCheckGraderTest.kt +++ /dev/null @@ -1,47 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.openai.models.evals - -import com.fasterxml.jackson.module.kotlin.jacksonTypeRef -import com.openai.core.jsonMapper -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -internal class EvalStringCheckGraderTest { - - @Test - fun create() { - val evalStringCheckGrader = - EvalStringCheckGrader.builder() - .input("input") - .name("name") - .operation(EvalStringCheckGrader.Operation.EQ) - .reference("reference") - .build() - - assertThat(evalStringCheckGrader.input()).isEqualTo("input") - assertThat(evalStringCheckGrader.name()).isEqualTo("name") - assertThat(evalStringCheckGrader.operation()).isEqualTo(EvalStringCheckGrader.Operation.EQ) - assertThat(evalStringCheckGrader.reference()).isEqualTo("reference") - } - - @Test - fun roundtrip() { - val jsonMapper = jsonMapper() - val evalStringCheckGrader = - EvalStringCheckGrader.builder() - .input("input") - .name("name") - .operation(EvalStringCheckGrader.Operation.EQ) - .reference("reference") - .build() - - val roundtrippedEvalStringCheckGrader = - jsonMapper.readValue( - jsonMapper.writeValueAsString(evalStringCheckGrader), - jacksonTypeRef(), - ) - - assertThat(roundtrippedEvalStringCheckGrader).isEqualTo(evalStringCheckGrader) - } -} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/evals/EvalTextSimilarityGraderTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/evals/EvalTextSimilarityGraderTest.kt deleted file mode 100644 index f7cc1230..00000000 --- a/openai-java-core/src/test/kotlin/com/openai/models/evals/EvalTextSimilarityGraderTest.kt +++ /dev/null @@ -1,51 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.openai.models.evals - -import com.fasterxml.jackson.module.kotlin.jacksonTypeRef -import com.openai.core.jsonMapper -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -internal class EvalTextSimilarityGraderTest { - - @Test - fun create() { - val evalTextSimilarityGrader = - EvalTextSimilarityGrader.builder() - .evaluationMetric(EvalTextSimilarityGrader.EvaluationMetric.FUZZY_MATCH) - .input("input") - .passThreshold(0.0) - .reference("reference") - .name("name") - .build() - - assertThat(evalTextSimilarityGrader.evaluationMetric()) - .isEqualTo(EvalTextSimilarityGrader.EvaluationMetric.FUZZY_MATCH) - assertThat(evalTextSimilarityGrader.input()).isEqualTo("input") - assertThat(evalTextSimilarityGrader.passThreshold()).isEqualTo(0.0) - assertThat(evalTextSimilarityGrader.reference()).isEqualTo("reference") - assertThat(evalTextSimilarityGrader.name()).contains("name") - } - - @Test - fun roundtrip() { - val jsonMapper = jsonMapper() - val evalTextSimilarityGrader = - EvalTextSimilarityGrader.builder() - .evaluationMetric(EvalTextSimilarityGrader.EvaluationMetric.FUZZY_MATCH) - .input("input") - .passThreshold(0.0) - .reference("reference") - .name("name") - .build() - - val roundtrippedEvalTextSimilarityGrader = - jsonMapper.readValue( - jsonMapper.writeValueAsString(evalTextSimilarityGrader), - jacksonTypeRef(), - ) - - assertThat(roundtrippedEvalTextSimilarityGrader).isEqualTo(evalTextSimilarityGrader) - } -} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/evals/EvalUpdateResponseTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/evals/EvalUpdateResponseTest.kt index 6a7d1e99..e4632e7c 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/evals/EvalUpdateResponseTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/evals/EvalUpdateResponseTest.kt @@ -5,6 +5,7 @@ package com.openai.models.evals import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import com.openai.core.JsonValue import com.openai.core.jsonMapper +import com.openai.models.graders.gradermodels.LabelModelGrader import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test @@ -28,12 +29,12 @@ internal class EvalUpdateResponseTest { ) .name("Chatbot effectiveness Evaluation") .addTestingCriterion( - EvalLabelModelGrader.builder() + LabelModelGrader.builder() .addInput( - EvalLabelModelGrader.Input.builder() + LabelModelGrader.Input.builder() .content("string") - .role(EvalLabelModelGrader.Input.Role.USER) - .type(EvalLabelModelGrader.Input.Type.MESSAGE) + .role(LabelModelGrader.Input.Role.USER) + .type(LabelModelGrader.Input.Type.MESSAGE) .build() ) .addLabel("string") @@ -67,13 +68,13 @@ internal class EvalUpdateResponseTest { assertThat(evalUpdateResponse.name()).isEqualTo("Chatbot effectiveness Evaluation") assertThat(evalUpdateResponse.testingCriteria()) .containsExactly( - EvalUpdateResponse.TestingCriterion.ofLabelModel( - EvalLabelModelGrader.builder() + EvalUpdateResponse.TestingCriterion.ofLabelModelGrader( + LabelModelGrader.builder() .addInput( - EvalLabelModelGrader.Input.builder() + LabelModelGrader.Input.builder() .content("string") - .role(EvalLabelModelGrader.Input.Role.USER) - .type(EvalLabelModelGrader.Input.Type.MESSAGE) + .role(LabelModelGrader.Input.Role.USER) + .type(LabelModelGrader.Input.Type.MESSAGE) .build() ) .addLabel("string") @@ -104,12 +105,12 @@ internal class EvalUpdateResponseTest { ) .name("Chatbot effectiveness Evaluation") .addTestingCriterion( - EvalLabelModelGrader.builder() + LabelModelGrader.builder() .addInput( - EvalLabelModelGrader.Input.builder() + LabelModelGrader.Input.builder() .content("string") - .role(EvalLabelModelGrader.Input.Role.USER) - .type(EvalLabelModelGrader.Input.Type.MESSAGE) + .role(LabelModelGrader.Input.Role.USER) + .type(LabelModelGrader.Input.Type.MESSAGE) .build() ) .addLabel("string") diff --git a/openai-java-core/src/test/kotlin/com/openai/models/finetuning/alpha/graders/GraderRunParamsTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/finetuning/alpha/graders/GraderRunParamsTest.kt new file mode 100644 index 00000000..6054610f --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/finetuning/alpha/graders/GraderRunParamsTest.kt @@ -0,0 +1,60 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.finetuning.alpha.graders + +import com.openai.models.graders.gradermodels.StringCheckGrader +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class GraderRunParamsTest { + + @Test + fun create() { + GraderRunParams.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .modelSample("model_sample") + .referenceAnswer("string") + .build() + } + + @Test + fun body() { + val params = + GraderRunParams.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .modelSample("model_sample") + .referenceAnswer("string") + .build() + + val body = params._body() + + assertThat(body.grader()) + .isEqualTo( + GraderRunParams.Grader.ofStringCheck( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + ) + assertThat(body.modelSample()).isEqualTo("model_sample") + assertThat(body.referenceAnswer()) + .isEqualTo(GraderRunParams.ReferenceAnswer.ofString("string")) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/finetuning/alpha/graders/GraderRunResponseTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/finetuning/alpha/graders/GraderRunResponseTest.kt new file mode 100644 index 00000000..ee806aba --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/finetuning/alpha/graders/GraderRunResponseTest.kt @@ -0,0 +1,172 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.finetuning.alpha.graders + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.JsonValue +import com.openai.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class GraderRunResponseTest { + + @Test + fun create() { + val graderRunResponse = + GraderRunResponse.builder() + .metadata( + GraderRunResponse.Metadata.builder() + .errors( + GraderRunResponse.Metadata.Errors.builder() + .formulaParseError(true) + .invalidVariableError(true) + .modelGraderParseError(true) + .modelGraderRefusalError(true) + .modelGraderServerError(true) + .modelGraderServerErrorDetails("model_grader_server_error_details") + .otherError(true) + .pythonGraderRuntimeError(true) + .pythonGraderRuntimeErrorDetails( + "python_grader_runtime_error_details" + ) + .pythonGraderServerError(true) + .pythonGraderServerErrorType("python_grader_server_error_type") + .sampleParseError(true) + .truncatedObservationError(true) + .unresponsiveRewardError(true) + .build() + ) + .executionTime(0.0) + .name("name") + .sampledModelName("sampled_model_name") + .scores( + GraderRunResponse.Metadata.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .tokenUsage(0L) + .type("type") + .build() + ) + .modelGraderTokenUsagePerModel( + GraderRunResponse.ModelGraderTokenUsagePerModel.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .reward(0.0) + .subRewards( + GraderRunResponse.SubRewards.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .build() + + assertThat(graderRunResponse.metadata()) + .isEqualTo( + GraderRunResponse.Metadata.builder() + .errors( + GraderRunResponse.Metadata.Errors.builder() + .formulaParseError(true) + .invalidVariableError(true) + .modelGraderParseError(true) + .modelGraderRefusalError(true) + .modelGraderServerError(true) + .modelGraderServerErrorDetails("model_grader_server_error_details") + .otherError(true) + .pythonGraderRuntimeError(true) + .pythonGraderRuntimeErrorDetails("python_grader_runtime_error_details") + .pythonGraderServerError(true) + .pythonGraderServerErrorType("python_grader_server_error_type") + .sampleParseError(true) + .truncatedObservationError(true) + .unresponsiveRewardError(true) + .build() + ) + .executionTime(0.0) + .name("name") + .sampledModelName("sampled_model_name") + .scores( + GraderRunResponse.Metadata.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .tokenUsage(0L) + .type("type") + .build() + ) + assertThat(graderRunResponse.modelGraderTokenUsagePerModel()) + .isEqualTo( + GraderRunResponse.ModelGraderTokenUsagePerModel.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + assertThat(graderRunResponse.reward()).isEqualTo(0.0) + assertThat(graderRunResponse.subRewards()) + .isEqualTo( + GraderRunResponse.SubRewards.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val graderRunResponse = + GraderRunResponse.builder() + .metadata( + GraderRunResponse.Metadata.builder() + .errors( + GraderRunResponse.Metadata.Errors.builder() + .formulaParseError(true) + .invalidVariableError(true) + .modelGraderParseError(true) + .modelGraderRefusalError(true) + .modelGraderServerError(true) + .modelGraderServerErrorDetails("model_grader_server_error_details") + .otherError(true) + .pythonGraderRuntimeError(true) + .pythonGraderRuntimeErrorDetails( + "python_grader_runtime_error_details" + ) + .pythonGraderServerError(true) + .pythonGraderServerErrorType("python_grader_server_error_type") + .sampleParseError(true) + .truncatedObservationError(true) + .unresponsiveRewardError(true) + .build() + ) + .executionTime(0.0) + .name("name") + .sampledModelName("sampled_model_name") + .scores( + GraderRunResponse.Metadata.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .tokenUsage(0L) + .type("type") + .build() + ) + .modelGraderTokenUsagePerModel( + GraderRunResponse.ModelGraderTokenUsagePerModel.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .reward(0.0) + .subRewards( + GraderRunResponse.SubRewards.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .build() + + val roundtrippedGraderRunResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(graderRunResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedGraderRunResponse).isEqualTo(graderRunResponse) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/finetuning/alpha/graders/GraderValidateParamsTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/finetuning/alpha/graders/GraderValidateParamsTest.kt new file mode 100644 index 00000000..21477300 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/finetuning/alpha/graders/GraderValidateParamsTest.kt @@ -0,0 +1,53 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.finetuning.alpha.graders + +import com.openai.models.graders.gradermodels.StringCheckGrader +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class GraderValidateParamsTest { + + @Test + fun create() { + GraderValidateParams.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .build() + } + + @Test + fun body() { + val params = + GraderValidateParams.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .build() + + val body = params._body() + + assertThat(body.grader()) + .isEqualTo( + GraderValidateParams.Grader.ofStringCheck( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + ) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/finetuning/alpha/graders/GraderValidateResponseTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/finetuning/alpha/graders/GraderValidateResponseTest.kt new file mode 100644 index 00000000..7fc0a06d --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/finetuning/alpha/graders/GraderValidateResponseTest.kt @@ -0,0 +1,63 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.finetuning.alpha.graders + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import com.openai.models.graders.gradermodels.StringCheckGrader +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class GraderValidateResponseTest { + + @Test + fun create() { + val graderValidateResponse = + GraderValidateResponse.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .build() + + assertThat(graderValidateResponse.grader()) + .contains( + GraderValidateResponse.Grader.ofStringCheck( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + ) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val graderValidateResponse = + GraderValidateResponse.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .build() + + val roundtrippedGraderValidateResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(graderValidateResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedGraderValidateResponse).isEqualTo(graderValidateResponse) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/finetuning/jobs/FineTuningJobTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/finetuning/jobs/FineTuningJobTest.kt index 33c530e6..5d1f8f91 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/finetuning/jobs/FineTuningJobTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/finetuning/jobs/FineTuningJobTest.kt @@ -5,6 +5,13 @@ package com.openai.models.finetuning.jobs import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import com.openai.core.JsonValue import com.openai.core.jsonMapper +import com.openai.models.finetuning.methods.DpoHyperparameters +import com.openai.models.finetuning.methods.DpoMethod +import com.openai.models.finetuning.methods.ReinforcementHyperparameters +import com.openai.models.finetuning.methods.ReinforcementMethod +import com.openai.models.finetuning.methods.SupervisedHyperparameters +import com.openai.models.finetuning.methods.SupervisedMethod +import com.openai.models.graders.gradermodels.StringCheckGrader import kotlin.jvm.optionals.getOrNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test @@ -61,10 +68,11 @@ internal class FineTuningJobTest { ) .method( FineTuningJob.Method.builder() + .type(FineTuningJob.Method.Type.SUPERVISED) .dpo( - FineTuningJob.Method.Dpo.builder() + DpoMethod.builder() .hyperparameters( - FineTuningJob.Method.Dpo.Hyperparameters.builder() + DpoHyperparameters.builder() .batchSizeAuto() .betaAuto() .learningRateMultiplierAuto() @@ -73,10 +81,35 @@ internal class FineTuningJobTest { ) .build() ) + .reinforcement( + ReinforcementMethod.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .hyperparameters( + ReinforcementHyperparameters.builder() + .batchSizeAuto() + .computeMultiplierAuto() + .evalIntervalAuto() + .evalSamplesAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .reasoningEffort( + ReinforcementHyperparameters.ReasoningEffort.DEFAULT + ) + .build() + ) + .build() + ) .supervised( - FineTuningJob.Method.Supervised.builder() + SupervisedMethod.builder() .hyperparameters( - FineTuningJob.Method.Supervised.Hyperparameters.builder() + SupervisedHyperparameters.builder() .batchSizeAuto() .learningRateMultiplierAuto() .nEpochsAuto() @@ -84,7 +117,6 @@ internal class FineTuningJobTest { ) .build() ) - .type(FineTuningJob.Method.Type.SUPERVISED) .build() ) .build() @@ -136,10 +168,11 @@ internal class FineTuningJobTest { assertThat(fineTuningJob.method()) .contains( FineTuningJob.Method.builder() + .type(FineTuningJob.Method.Type.SUPERVISED) .dpo( - FineTuningJob.Method.Dpo.builder() + DpoMethod.builder() .hyperparameters( - FineTuningJob.Method.Dpo.Hyperparameters.builder() + DpoHyperparameters.builder() .batchSizeAuto() .betaAuto() .learningRateMultiplierAuto() @@ -148,10 +181,35 @@ internal class FineTuningJobTest { ) .build() ) + .reinforcement( + ReinforcementMethod.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .hyperparameters( + ReinforcementHyperparameters.builder() + .batchSizeAuto() + .computeMultiplierAuto() + .evalIntervalAuto() + .evalSamplesAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .reasoningEffort( + ReinforcementHyperparameters.ReasoningEffort.DEFAULT + ) + .build() + ) + .build() + ) .supervised( - FineTuningJob.Method.Supervised.builder() + SupervisedMethod.builder() .hyperparameters( - FineTuningJob.Method.Supervised.Hyperparameters.builder() + SupervisedHyperparameters.builder() .batchSizeAuto() .learningRateMultiplierAuto() .nEpochsAuto() @@ -159,7 +217,6 @@ internal class FineTuningJobTest { ) .build() ) - .type(FineTuningJob.Method.Type.SUPERVISED) .build() ) } @@ -215,10 +272,11 @@ internal class FineTuningJobTest { ) .method( FineTuningJob.Method.builder() + .type(FineTuningJob.Method.Type.SUPERVISED) .dpo( - FineTuningJob.Method.Dpo.builder() + DpoMethod.builder() .hyperparameters( - FineTuningJob.Method.Dpo.Hyperparameters.builder() + DpoHyperparameters.builder() .batchSizeAuto() .betaAuto() .learningRateMultiplierAuto() @@ -227,10 +285,35 @@ internal class FineTuningJobTest { ) .build() ) + .reinforcement( + ReinforcementMethod.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .hyperparameters( + ReinforcementHyperparameters.builder() + .batchSizeAuto() + .computeMultiplierAuto() + .evalIntervalAuto() + .evalSamplesAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .reasoningEffort( + ReinforcementHyperparameters.ReasoningEffort.DEFAULT + ) + .build() + ) + .build() + ) .supervised( - FineTuningJob.Method.Supervised.builder() + SupervisedMethod.builder() .hyperparameters( - FineTuningJob.Method.Supervised.Hyperparameters.builder() + SupervisedHyperparameters.builder() .batchSizeAuto() .learningRateMultiplierAuto() .nEpochsAuto() @@ -238,7 +321,6 @@ internal class FineTuningJobTest { ) .build() ) - .type(FineTuningJob.Method.Type.SUPERVISED) .build() ) .build() diff --git a/openai-java-core/src/test/kotlin/com/openai/models/finetuning/jobs/JobCreateParamsTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/finetuning/jobs/JobCreateParamsTest.kt index f3391493..28cd1a8b 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/finetuning/jobs/JobCreateParamsTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/finetuning/jobs/JobCreateParamsTest.kt @@ -3,6 +3,13 @@ package com.openai.models.finetuning.jobs import com.openai.core.JsonValue +import com.openai.models.finetuning.methods.DpoHyperparameters +import com.openai.models.finetuning.methods.DpoMethod +import com.openai.models.finetuning.methods.ReinforcementHyperparameters +import com.openai.models.finetuning.methods.ReinforcementMethod +import com.openai.models.finetuning.methods.SupervisedHyperparameters +import com.openai.models.finetuning.methods.SupervisedMethod +import com.openai.models.graders.gradermodels.StringCheckGrader import kotlin.jvm.optionals.getOrNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test @@ -40,10 +47,11 @@ internal class JobCreateParamsTest { ) .method( JobCreateParams.Method.builder() + .type(JobCreateParams.Method.Type.SUPERVISED) .dpo( - JobCreateParams.Method.Dpo.builder() + DpoMethod.builder() .hyperparameters( - JobCreateParams.Method.Dpo.Hyperparameters.builder() + DpoHyperparameters.builder() .batchSizeAuto() .betaAuto() .learningRateMultiplierAuto() @@ -52,10 +60,35 @@ internal class JobCreateParamsTest { ) .build() ) + .reinforcement( + ReinforcementMethod.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .hyperparameters( + ReinforcementHyperparameters.builder() + .batchSizeAuto() + .computeMultiplierAuto() + .evalIntervalAuto() + .evalSamplesAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .reasoningEffort( + ReinforcementHyperparameters.ReasoningEffort.DEFAULT + ) + .build() + ) + .build() + ) .supervised( - JobCreateParams.Method.Supervised.builder() + SupervisedMethod.builder() .hyperparameters( - JobCreateParams.Method.Supervised.Hyperparameters.builder() + SupervisedHyperparameters.builder() .batchSizeAuto() .learningRateMultiplierAuto() .nEpochsAuto() @@ -63,7 +96,6 @@ internal class JobCreateParamsTest { ) .build() ) - .type(JobCreateParams.Method.Type.SUPERVISED) .build() ) .seed(42L) @@ -104,10 +136,11 @@ internal class JobCreateParamsTest { ) .method( JobCreateParams.Method.builder() + .type(JobCreateParams.Method.Type.SUPERVISED) .dpo( - JobCreateParams.Method.Dpo.builder() + DpoMethod.builder() .hyperparameters( - JobCreateParams.Method.Dpo.Hyperparameters.builder() + DpoHyperparameters.builder() .batchSizeAuto() .betaAuto() .learningRateMultiplierAuto() @@ -116,10 +149,35 @@ internal class JobCreateParamsTest { ) .build() ) + .reinforcement( + ReinforcementMethod.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .hyperparameters( + ReinforcementHyperparameters.builder() + .batchSizeAuto() + .computeMultiplierAuto() + .evalIntervalAuto() + .evalSamplesAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .reasoningEffort( + ReinforcementHyperparameters.ReasoningEffort.DEFAULT + ) + .build() + ) + .build() + ) .supervised( - JobCreateParams.Method.Supervised.builder() + SupervisedMethod.builder() .hyperparameters( - JobCreateParams.Method.Supervised.Hyperparameters.builder() + SupervisedHyperparameters.builder() .batchSizeAuto() .learningRateMultiplierAuto() .nEpochsAuto() @@ -127,7 +185,6 @@ internal class JobCreateParamsTest { ) .build() ) - .type(JobCreateParams.Method.Type.SUPERVISED) .build() ) .seed(42L) @@ -169,10 +226,11 @@ internal class JobCreateParamsTest { assertThat(body.method()) .contains( JobCreateParams.Method.builder() + .type(JobCreateParams.Method.Type.SUPERVISED) .dpo( - JobCreateParams.Method.Dpo.builder() + DpoMethod.builder() .hyperparameters( - JobCreateParams.Method.Dpo.Hyperparameters.builder() + DpoHyperparameters.builder() .batchSizeAuto() .betaAuto() .learningRateMultiplierAuto() @@ -181,10 +239,35 @@ internal class JobCreateParamsTest { ) .build() ) + .reinforcement( + ReinforcementMethod.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .hyperparameters( + ReinforcementHyperparameters.builder() + .batchSizeAuto() + .computeMultiplierAuto() + .evalIntervalAuto() + .evalSamplesAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .reasoningEffort( + ReinforcementHyperparameters.ReasoningEffort.DEFAULT + ) + .build() + ) + .build() + ) .supervised( - JobCreateParams.Method.Supervised.builder() + SupervisedMethod.builder() .hyperparameters( - JobCreateParams.Method.Supervised.Hyperparameters.builder() + SupervisedHyperparameters.builder() .batchSizeAuto() .learningRateMultiplierAuto() .nEpochsAuto() @@ -192,7 +275,6 @@ internal class JobCreateParamsTest { ) .build() ) - .type(JobCreateParams.Method.Type.SUPERVISED) .build() ) assertThat(body.seed()).contains(42L) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/finetuning/jobs/JobListPageResponseTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/finetuning/jobs/JobListPageResponseTest.kt index 833580a8..169aad89 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/finetuning/jobs/JobListPageResponseTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/finetuning/jobs/JobListPageResponseTest.kt @@ -5,6 +5,13 @@ package com.openai.models.finetuning.jobs import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import com.openai.core.JsonValue import com.openai.core.jsonMapper +import com.openai.models.finetuning.methods.DpoHyperparameters +import com.openai.models.finetuning.methods.DpoMethod +import com.openai.models.finetuning.methods.ReinforcementHyperparameters +import com.openai.models.finetuning.methods.ReinforcementMethod +import com.openai.models.finetuning.methods.SupervisedHyperparameters +import com.openai.models.finetuning.methods.SupervisedMethod +import com.openai.models.graders.gradermodels.StringCheckGrader import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test @@ -62,10 +69,11 @@ internal class JobListPageResponseTest { ) .method( FineTuningJob.Method.builder() + .type(FineTuningJob.Method.Type.SUPERVISED) .dpo( - FineTuningJob.Method.Dpo.builder() + DpoMethod.builder() .hyperparameters( - FineTuningJob.Method.Dpo.Hyperparameters.builder() + DpoHyperparameters.builder() .batchSizeAuto() .betaAuto() .learningRateMultiplierAuto() @@ -74,11 +82,36 @@ internal class JobListPageResponseTest { ) .build() ) + .reinforcement( + ReinforcementMethod.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .hyperparameters( + ReinforcementHyperparameters.builder() + .batchSizeAuto() + .computeMultiplierAuto() + .evalIntervalAuto() + .evalSamplesAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .reasoningEffort( + ReinforcementHyperparameters.ReasoningEffort + .DEFAULT + ) + .build() + ) + .build() + ) .supervised( - FineTuningJob.Method.Supervised.builder() + SupervisedMethod.builder() .hyperparameters( - FineTuningJob.Method.Supervised.Hyperparameters - .builder() + SupervisedHyperparameters.builder() .batchSizeAuto() .learningRateMultiplierAuto() .nEpochsAuto() @@ -86,7 +119,6 @@ internal class JobListPageResponseTest { ) .build() ) - .type(FineTuningJob.Method.Type.SUPERVISED) .build() ) .build() @@ -143,10 +175,11 @@ internal class JobListPageResponseTest { ) .method( FineTuningJob.Method.builder() + .type(FineTuningJob.Method.Type.SUPERVISED) .dpo( - FineTuningJob.Method.Dpo.builder() + DpoMethod.builder() .hyperparameters( - FineTuningJob.Method.Dpo.Hyperparameters.builder() + DpoHyperparameters.builder() .batchSizeAuto() .betaAuto() .learningRateMultiplierAuto() @@ -155,10 +188,35 @@ internal class JobListPageResponseTest { ) .build() ) + .reinforcement( + ReinforcementMethod.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .hyperparameters( + ReinforcementHyperparameters.builder() + .batchSizeAuto() + .computeMultiplierAuto() + .evalIntervalAuto() + .evalSamplesAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .reasoningEffort( + ReinforcementHyperparameters.ReasoningEffort.DEFAULT + ) + .build() + ) + .build() + ) .supervised( - FineTuningJob.Method.Supervised.builder() + SupervisedMethod.builder() .hyperparameters( - FineTuningJob.Method.Supervised.Hyperparameters.builder() + SupervisedHyperparameters.builder() .batchSizeAuto() .learningRateMultiplierAuto() .nEpochsAuto() @@ -166,7 +224,6 @@ internal class JobListPageResponseTest { ) .build() ) - .type(FineTuningJob.Method.Type.SUPERVISED) .build() ) .build() @@ -227,10 +284,11 @@ internal class JobListPageResponseTest { ) .method( FineTuningJob.Method.builder() + .type(FineTuningJob.Method.Type.SUPERVISED) .dpo( - FineTuningJob.Method.Dpo.builder() + DpoMethod.builder() .hyperparameters( - FineTuningJob.Method.Dpo.Hyperparameters.builder() + DpoHyperparameters.builder() .batchSizeAuto() .betaAuto() .learningRateMultiplierAuto() @@ -239,11 +297,36 @@ internal class JobListPageResponseTest { ) .build() ) + .reinforcement( + ReinforcementMethod.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .hyperparameters( + ReinforcementHyperparameters.builder() + .batchSizeAuto() + .computeMultiplierAuto() + .evalIntervalAuto() + .evalSamplesAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .reasoningEffort( + ReinforcementHyperparameters.ReasoningEffort + .DEFAULT + ) + .build() + ) + .build() + ) .supervised( - FineTuningJob.Method.Supervised.builder() + SupervisedMethod.builder() .hyperparameters( - FineTuningJob.Method.Supervised.Hyperparameters - .builder() + SupervisedHyperparameters.builder() .batchSizeAuto() .learningRateMultiplierAuto() .nEpochsAuto() @@ -251,7 +334,6 @@ internal class JobListPageResponseTest { ) .build() ) - .type(FineTuningJob.Method.Type.SUPERVISED) .build() ) .build() diff --git a/openai-java-core/src/test/kotlin/com/openai/models/finetuning/jobs/JobPauseParamsTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/finetuning/jobs/JobPauseParamsTest.kt new file mode 100644 index 00000000..052bab3e --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/finetuning/jobs/JobPauseParamsTest.kt @@ -0,0 +1,23 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.finetuning.jobs + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class JobPauseParamsTest { + + @Test + fun create() { + JobPauseParams.builder().fineTuningJobId("ft-AF1WoRqd3aJAHsqc9NY7iL8F").build() + } + + @Test + fun pathParams() { + val params = JobPauseParams.builder().fineTuningJobId("ft-AF1WoRqd3aJAHsqc9NY7iL8F").build() + + assertThat(params._pathParam(0)).isEqualTo("ft-AF1WoRqd3aJAHsqc9NY7iL8F") + // out-of-bound path param + assertThat(params._pathParam(1)).isEqualTo("") + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/finetuning/jobs/JobResumeParamsTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/finetuning/jobs/JobResumeParamsTest.kt new file mode 100644 index 00000000..e3f90315 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/finetuning/jobs/JobResumeParamsTest.kt @@ -0,0 +1,24 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.finetuning.jobs + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class JobResumeParamsTest { + + @Test + fun create() { + JobResumeParams.builder().fineTuningJobId("ft-AF1WoRqd3aJAHsqc9NY7iL8F").build() + } + + @Test + fun pathParams() { + val params = + JobResumeParams.builder().fineTuningJobId("ft-AF1WoRqd3aJAHsqc9NY7iL8F").build() + + assertThat(params._pathParam(0)).isEqualTo("ft-AF1WoRqd3aJAHsqc9NY7iL8F") + // out-of-bound path param + assertThat(params._pathParam(1)).isEqualTo("") + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/finetuning/methods/DpoHyperparametersTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/finetuning/methods/DpoHyperparametersTest.kt new file mode 100644 index 00000000..d220c3c7 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/finetuning/methods/DpoHyperparametersTest.kt @@ -0,0 +1,48 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.finetuning.methods + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class DpoHyperparametersTest { + + @Test + fun create() { + val dpoHyperparameters = + DpoHyperparameters.builder() + .batchSizeAuto() + .betaAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .build() + + assertThat(dpoHyperparameters.batchSize()).contains(DpoHyperparameters.BatchSize.ofAuto()) + assertThat(dpoHyperparameters.beta()).contains(DpoHyperparameters.Beta.ofAuto()) + assertThat(dpoHyperparameters.learningRateMultiplier()) + .contains(DpoHyperparameters.LearningRateMultiplier.ofAuto()) + assertThat(dpoHyperparameters.nEpochs()).contains(DpoHyperparameters.NEpochs.ofAuto()) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val dpoHyperparameters = + DpoHyperparameters.builder() + .batchSizeAuto() + .betaAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .build() + + val roundtrippedDpoHyperparameters = + jsonMapper.readValue( + jsonMapper.writeValueAsString(dpoHyperparameters), + jacksonTypeRef(), + ) + + assertThat(roundtrippedDpoHyperparameters).isEqualTo(dpoHyperparameters) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/finetuning/methods/DpoMethodTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/finetuning/methods/DpoMethodTest.kt new file mode 100644 index 00000000..58ef8731 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/finetuning/methods/DpoMethodTest.kt @@ -0,0 +1,60 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.finetuning.methods + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class DpoMethodTest { + + @Test + fun create() { + val dpoMethod = + DpoMethod.builder() + .hyperparameters( + DpoHyperparameters.builder() + .batchSizeAuto() + .betaAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .build() + ) + .build() + + assertThat(dpoMethod.hyperparameters()) + .contains( + DpoHyperparameters.builder() + .batchSizeAuto() + .betaAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .build() + ) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val dpoMethod = + DpoMethod.builder() + .hyperparameters( + DpoHyperparameters.builder() + .batchSizeAuto() + .betaAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .build() + ) + .build() + + val roundtrippedDpoMethod = + jsonMapper.readValue( + jsonMapper.writeValueAsString(dpoMethod), + jacksonTypeRef(), + ) + + assertThat(roundtrippedDpoMethod).isEqualTo(dpoMethod) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/finetuning/methods/ReinforcementHyperparametersTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/finetuning/methods/ReinforcementHyperparametersTest.kt new file mode 100644 index 00000000..c7204234 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/finetuning/methods/ReinforcementHyperparametersTest.kt @@ -0,0 +1,63 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.finetuning.methods + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class ReinforcementHyperparametersTest { + + @Test + fun create() { + val reinforcementHyperparameters = + ReinforcementHyperparameters.builder() + .batchSizeAuto() + .computeMultiplierAuto() + .evalIntervalAuto() + .evalSamplesAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .reasoningEffort(ReinforcementHyperparameters.ReasoningEffort.DEFAULT) + .build() + + assertThat(reinforcementHyperparameters.batchSize()) + .contains(ReinforcementHyperparameters.BatchSize.ofAuto()) + assertThat(reinforcementHyperparameters.computeMultiplier()) + .contains(ReinforcementHyperparameters.ComputeMultiplier.ofAuto()) + assertThat(reinforcementHyperparameters.evalInterval()) + .contains(ReinforcementHyperparameters.EvalInterval.ofAuto()) + assertThat(reinforcementHyperparameters.evalSamples()) + .contains(ReinforcementHyperparameters.EvalSamples.ofAuto()) + assertThat(reinforcementHyperparameters.learningRateMultiplier()) + .contains(ReinforcementHyperparameters.LearningRateMultiplier.ofAuto()) + assertThat(reinforcementHyperparameters.nEpochs()) + .contains(ReinforcementHyperparameters.NEpochs.ofAuto()) + assertThat(reinforcementHyperparameters.reasoningEffort()) + .contains(ReinforcementHyperparameters.ReasoningEffort.DEFAULT) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val reinforcementHyperparameters = + ReinforcementHyperparameters.builder() + .batchSizeAuto() + .computeMultiplierAuto() + .evalIntervalAuto() + .evalSamplesAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .reasoningEffort(ReinforcementHyperparameters.ReasoningEffort.DEFAULT) + .build() + + val roundtrippedReinforcementHyperparameters = + jsonMapper.readValue( + jsonMapper.writeValueAsString(reinforcementHyperparameters), + jacksonTypeRef(), + ) + + assertThat(roundtrippedReinforcementHyperparameters).isEqualTo(reinforcementHyperparameters) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/finetuning/methods/ReinforcementMethodTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/finetuning/methods/ReinforcementMethodTest.kt new file mode 100644 index 00000000..271a02be --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/finetuning/methods/ReinforcementMethodTest.kt @@ -0,0 +1,97 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.finetuning.methods + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import com.openai.models.graders.gradermodels.StringCheckGrader +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class ReinforcementMethodTest { + + @Test + fun create() { + val reinforcementMethod = + ReinforcementMethod.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .hyperparameters( + ReinforcementHyperparameters.builder() + .batchSizeAuto() + .computeMultiplierAuto() + .evalIntervalAuto() + .evalSamplesAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .reasoningEffort(ReinforcementHyperparameters.ReasoningEffort.DEFAULT) + .build() + ) + .build() + + assertThat(reinforcementMethod.grader()) + .isEqualTo( + ReinforcementMethod.Grader.ofStringCheck( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + ) + assertThat(reinforcementMethod.hyperparameters()) + .contains( + ReinforcementHyperparameters.builder() + .batchSizeAuto() + .computeMultiplierAuto() + .evalIntervalAuto() + .evalSamplesAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .reasoningEffort(ReinforcementHyperparameters.ReasoningEffort.DEFAULT) + .build() + ) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val reinforcementMethod = + ReinforcementMethod.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .hyperparameters( + ReinforcementHyperparameters.builder() + .batchSizeAuto() + .computeMultiplierAuto() + .evalIntervalAuto() + .evalSamplesAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .reasoningEffort(ReinforcementHyperparameters.ReasoningEffort.DEFAULT) + .build() + ) + .build() + + val roundtrippedReinforcementMethod = + jsonMapper.readValue( + jsonMapper.writeValueAsString(reinforcementMethod), + jacksonTypeRef(), + ) + + assertThat(roundtrippedReinforcementMethod).isEqualTo(reinforcementMethod) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/finetuning/methods/SupervisedHyperparametersTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/finetuning/methods/SupervisedHyperparametersTest.kt new file mode 100644 index 00000000..99b9ec04 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/finetuning/methods/SupervisedHyperparametersTest.kt @@ -0,0 +1,47 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.finetuning.methods + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class SupervisedHyperparametersTest { + + @Test + fun create() { + val supervisedHyperparameters = + SupervisedHyperparameters.builder() + .batchSizeAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .build() + + assertThat(supervisedHyperparameters.batchSize()) + .contains(SupervisedHyperparameters.BatchSize.ofAuto()) + assertThat(supervisedHyperparameters.learningRateMultiplier()) + .contains(SupervisedHyperparameters.LearningRateMultiplier.ofAuto()) + assertThat(supervisedHyperparameters.nEpochs()) + .contains(SupervisedHyperparameters.NEpochs.ofAuto()) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val supervisedHyperparameters = + SupervisedHyperparameters.builder() + .batchSizeAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .build() + + val roundtrippedSupervisedHyperparameters = + jsonMapper.readValue( + jsonMapper.writeValueAsString(supervisedHyperparameters), + jacksonTypeRef(), + ) + + assertThat(roundtrippedSupervisedHyperparameters).isEqualTo(supervisedHyperparameters) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/finetuning/methods/SupervisedMethodTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/finetuning/methods/SupervisedMethodTest.kt new file mode 100644 index 00000000..93769d44 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/finetuning/methods/SupervisedMethodTest.kt @@ -0,0 +1,57 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.finetuning.methods + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class SupervisedMethodTest { + + @Test + fun create() { + val supervisedMethod = + SupervisedMethod.builder() + .hyperparameters( + SupervisedHyperparameters.builder() + .batchSizeAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .build() + ) + .build() + + assertThat(supervisedMethod.hyperparameters()) + .contains( + SupervisedHyperparameters.builder() + .batchSizeAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .build() + ) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val supervisedMethod = + SupervisedMethod.builder() + .hyperparameters( + SupervisedHyperparameters.builder() + .batchSizeAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .build() + ) + .build() + + val roundtrippedSupervisedMethod = + jsonMapper.readValue( + jsonMapper.writeValueAsString(supervisedMethod), + jacksonTypeRef(), + ) + + assertThat(roundtrippedSupervisedMethod).isEqualTo(supervisedMethod) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/graders/gradermodels/LabelModelGraderTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/graders/gradermodels/LabelModelGraderTest.kt new file mode 100644 index 00000000..8243d736 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/graders/gradermodels/LabelModelGraderTest.kt @@ -0,0 +1,69 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.graders.gradermodels + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class LabelModelGraderTest { + + @Test + fun create() { + val labelModelGrader = + LabelModelGrader.builder() + .addInput( + LabelModelGrader.Input.builder() + .content("string") + .role(LabelModelGrader.Input.Role.USER) + .type(LabelModelGrader.Input.Type.MESSAGE) + .build() + ) + .addLabel("string") + .model("model") + .name("name") + .addPassingLabel("string") + .build() + + assertThat(labelModelGrader.input()) + .containsExactly( + LabelModelGrader.Input.builder() + .content("string") + .role(LabelModelGrader.Input.Role.USER) + .type(LabelModelGrader.Input.Type.MESSAGE) + .build() + ) + assertThat(labelModelGrader.labels()).containsExactly("string") + assertThat(labelModelGrader.model()).isEqualTo("model") + assertThat(labelModelGrader.name()).isEqualTo("name") + assertThat(labelModelGrader.passingLabels()).containsExactly("string") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val labelModelGrader = + LabelModelGrader.builder() + .addInput( + LabelModelGrader.Input.builder() + .content("string") + .role(LabelModelGrader.Input.Role.USER) + .type(LabelModelGrader.Input.Type.MESSAGE) + .build() + ) + .addLabel("string") + .model("model") + .name("name") + .addPassingLabel("string") + .build() + + val roundtrippedLabelModelGrader = + jsonMapper.readValue( + jsonMapper.writeValueAsString(labelModelGrader), + jacksonTypeRef(), + ) + + assertThat(roundtrippedLabelModelGrader).isEqualTo(labelModelGrader) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/graders/gradermodels/MultiGraderTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/graders/gradermodels/MultiGraderTest.kt new file mode 100644 index 00000000..81423d03 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/graders/gradermodels/MultiGraderTest.kt @@ -0,0 +1,91 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.graders.gradermodels + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.JsonValue +import com.openai.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class MultiGraderTest { + + @Test + fun create() { + val multiGrader = + MultiGrader.builder() + .calculateOutput("calculate_output") + .graders( + MultiGrader.Graders.builder() + .putAdditionalProperty( + "foo", + JsonValue.from( + mapOf( + "input" to "input", + "name" to "name", + "operation" to "eq", + "reference" to "reference", + "type" to "string_check", + ) + ), + ) + .build() + ) + .name("name") + .build() + + assertThat(multiGrader.calculateOutput()).isEqualTo("calculate_output") + assertThat(multiGrader.graders()) + .isEqualTo( + MultiGrader.Graders.builder() + .putAdditionalProperty( + "foo", + JsonValue.from( + mapOf( + "input" to "input", + "name" to "name", + "operation" to "eq", + "reference" to "reference", + "type" to "string_check", + ) + ), + ) + .build() + ) + assertThat(multiGrader.name()).isEqualTo("name") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val multiGrader = + MultiGrader.builder() + .calculateOutput("calculate_output") + .graders( + MultiGrader.Graders.builder() + .putAdditionalProperty( + "foo", + JsonValue.from( + mapOf( + "input" to "input", + "name" to "name", + "operation" to "eq", + "reference" to "reference", + "type" to "string_check", + ) + ), + ) + .build() + ) + .name("name") + .build() + + val roundtrippedMultiGrader = + jsonMapper.readValue( + jsonMapper.writeValueAsString(multiGrader), + jacksonTypeRef(), + ) + + assertThat(roundtrippedMultiGrader).isEqualTo(multiGrader) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/graders/gradermodels/PythonGraderTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/graders/gradermodels/PythonGraderTest.kt new file mode 100644 index 00000000..3ac30afb --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/graders/gradermodels/PythonGraderTest.kt @@ -0,0 +1,36 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.graders.gradermodels + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class PythonGraderTest { + + @Test + fun create() { + val pythonGrader = + PythonGrader.builder().name("name").source("source").imageTag("image_tag").build() + + assertThat(pythonGrader.name()).isEqualTo("name") + assertThat(pythonGrader.source()).isEqualTo("source") + assertThat(pythonGrader.imageTag()).contains("image_tag") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val pythonGrader = + PythonGrader.builder().name("name").source("source").imageTag("image_tag").build() + + val roundtrippedPythonGrader = + jsonMapper.readValue( + jsonMapper.writeValueAsString(pythonGrader), + jacksonTypeRef(), + ) + + assertThat(roundtrippedPythonGrader).isEqualTo(pythonGrader) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/graders/gradermodels/ScoreModelGraderTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/graders/gradermodels/ScoreModelGraderTest.kt new file mode 100644 index 00000000..ff2134b6 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/graders/gradermodels/ScoreModelGraderTest.kt @@ -0,0 +1,72 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.graders.gradermodels + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.JsonValue +import com.openai.core.jsonMapper +import kotlin.jvm.optionals.getOrNull +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class ScoreModelGraderTest { + + @Test + fun create() { + val scoreModelGrader = + ScoreModelGrader.builder() + .addInput( + ScoreModelGrader.Input.builder() + .content("string") + .role(ScoreModelGrader.Input.Role.USER) + .type(ScoreModelGrader.Input.Type.MESSAGE) + .build() + ) + .model("model") + .name("name") + .addRange(0.0) + .samplingParams(JsonValue.from(mapOf())) + .build() + + assertThat(scoreModelGrader.input()) + .containsExactly( + ScoreModelGrader.Input.builder() + .content("string") + .role(ScoreModelGrader.Input.Role.USER) + .type(ScoreModelGrader.Input.Type.MESSAGE) + .build() + ) + assertThat(scoreModelGrader.model()).isEqualTo("model") + assertThat(scoreModelGrader.name()).isEqualTo("name") + assertThat(scoreModelGrader.range().getOrNull()).containsExactly(0.0) + assertThat(scoreModelGrader._samplingParams()) + .isEqualTo(JsonValue.from(mapOf())) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val scoreModelGrader = + ScoreModelGrader.builder() + .addInput( + ScoreModelGrader.Input.builder() + .content("string") + .role(ScoreModelGrader.Input.Role.USER) + .type(ScoreModelGrader.Input.Type.MESSAGE) + .build() + ) + .model("model") + .name("name") + .addRange(0.0) + .samplingParams(JsonValue.from(mapOf())) + .build() + + val roundtrippedScoreModelGrader = + jsonMapper.readValue( + jsonMapper.writeValueAsString(scoreModelGrader), + jacksonTypeRef(), + ) + + assertThat(roundtrippedScoreModelGrader).isEqualTo(scoreModelGrader) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/graders/gradermodels/StringCheckGraderTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/graders/gradermodels/StringCheckGraderTest.kt new file mode 100644 index 00000000..6eb0c92b --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/graders/gradermodels/StringCheckGraderTest.kt @@ -0,0 +1,47 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.graders.gradermodels + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class StringCheckGraderTest { + + @Test + fun create() { + val stringCheckGrader = + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + + assertThat(stringCheckGrader.input()).isEqualTo("input") + assertThat(stringCheckGrader.name()).isEqualTo("name") + assertThat(stringCheckGrader.operation()).isEqualTo(StringCheckGrader.Operation.EQ) + assertThat(stringCheckGrader.reference()).isEqualTo("reference") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val stringCheckGrader = + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + + val roundtrippedStringCheckGrader = + jsonMapper.readValue( + jsonMapper.writeValueAsString(stringCheckGrader), + jacksonTypeRef(), + ) + + assertThat(roundtrippedStringCheckGrader).isEqualTo(stringCheckGrader) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/graders/gradermodels/TextSimilarityGraderTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/graders/gradermodels/TextSimilarityGraderTest.kt new file mode 100644 index 00000000..f271eeb4 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/graders/gradermodels/TextSimilarityGraderTest.kt @@ -0,0 +1,48 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.models.graders.gradermodels + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class TextSimilarityGraderTest { + + @Test + fun create() { + val textSimilarityGrader = + TextSimilarityGrader.builder() + .evaluationMetric(TextSimilarityGrader.EvaluationMetric.FUZZY_MATCH) + .input("input") + .name("name") + .reference("reference") + .build() + + assertThat(textSimilarityGrader.evaluationMetric()) + .isEqualTo(TextSimilarityGrader.EvaluationMetric.FUZZY_MATCH) + assertThat(textSimilarityGrader.input()).isEqualTo("input") + assertThat(textSimilarityGrader.name()).isEqualTo("name") + assertThat(textSimilarityGrader.reference()).isEqualTo("reference") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val textSimilarityGrader = + TextSimilarityGrader.builder() + .evaluationMetric(TextSimilarityGrader.EvaluationMetric.FUZZY_MATCH) + .input("input") + .name("name") + .reference("reference") + .build() + + val roundtrippedTextSimilarityGrader = + jsonMapper.readValue( + jsonMapper.writeValueAsString(textSimilarityGrader), + jacksonTypeRef(), + ) + + assertThat(roundtrippedTextSimilarityGrader).isEqualTo(textSimilarityGrader) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseFileSearchToolCallTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseFileSearchToolCallTest.kt index 50752fd3..414ef927 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseFileSearchToolCallTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseFileSearchToolCallTest.kt @@ -27,7 +27,7 @@ internal class ResponseFileSearchToolCallTest { ) .fileId("file_id") .filename("filename") - .score(0.0) + .score(0.0f) .text("text") .build() ) @@ -47,7 +47,7 @@ internal class ResponseFileSearchToolCallTest { ) .fileId("file_id") .filename("filename") - .score(0.0) + .score(0.0f) .text("text") .build() ) @@ -70,7 +70,7 @@ internal class ResponseFileSearchToolCallTest { ) .fileId("file_id") .filename("filename") - .score(0.0) + .score(0.0f) .text("text") .build() ) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseInputItemTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseInputItemTest.kt index 4ca8296c..875e90e4 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseInputItemTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseInputItemTest.kt @@ -187,7 +187,7 @@ internal class ResponseInputItemTest { ) .fileId("file_id") .filename("filename") - .score(0.0) + .score(0.0f) .text("text") .build() ) @@ -226,7 +226,7 @@ internal class ResponseInputItemTest { ) .fileId("file_id") .filename("filename") - .score(0.0) + .score(0.0f) .text("text") .build() ) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseItemTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseItemTest.kt index 2e4bfed3..2f3896e8 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseItemTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseItemTest.kt @@ -138,7 +138,7 @@ internal class ResponseItemTest { ) .fileId("file_id") .filename("filename") - .score(0.0) + .score(0.0f) .text("text") .build() ) @@ -174,7 +174,7 @@ internal class ResponseItemTest { ) .fileId("file_id") .filename("filename") - .score(0.0) + .score(0.0f) .text("text") .build() ) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseOutputItemTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseOutputItemTest.kt index 763f097a..66edbe7d 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseOutputItemTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseOutputItemTest.kt @@ -90,7 +90,7 @@ internal class ResponseOutputItemTest { ) .fileId("file_id") .filename("filename") - .score(0.0) + .score(0.0f) .text("text") .build() ) @@ -124,7 +124,7 @@ internal class ResponseOutputItemTest { ) .fileId("file_id") .filename("filename") - .score(0.0) + .score(0.0f) .text("text") .build() ) diff --git a/openai-java-core/src/test/kotlin/com/openai/services/ErrorHandlingTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/ErrorHandlingTest.kt index f7e594be..f19d5a98 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/ErrorHandlingTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/ErrorHandlingTest.kt @@ -23,6 +23,13 @@ import com.openai.errors.UnauthorizedException import com.openai.errors.UnexpectedStatusCodeException import com.openai.errors.UnprocessableEntityException import com.openai.models.finetuning.jobs.JobCreateParams +import com.openai.models.finetuning.methods.DpoHyperparameters +import com.openai.models.finetuning.methods.DpoMethod +import com.openai.models.finetuning.methods.ReinforcementHyperparameters +import com.openai.models.finetuning.methods.ReinforcementMethod +import com.openai.models.finetuning.methods.SupervisedHyperparameters +import com.openai.models.finetuning.methods.SupervisedMethod +import com.openai.models.graders.gradermodels.StringCheckGrader import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.entry import org.junit.jupiter.api.BeforeEach @@ -111,10 +118,11 @@ internal class ErrorHandlingTest { ) .method( JobCreateParams.Method.builder() + .type(JobCreateParams.Method.Type.SUPERVISED) .dpo( - JobCreateParams.Method.Dpo.builder() + DpoMethod.builder() .hyperparameters( - JobCreateParams.Method.Dpo.Hyperparameters.builder() + DpoHyperparameters.builder() .batchSizeAuto() .betaAuto() .learningRateMultiplierAuto() @@ -123,11 +131,36 @@ internal class ErrorHandlingTest { ) .build() ) + .reinforcement( + ReinforcementMethod.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .hyperparameters( + ReinforcementHyperparameters.builder() + .batchSizeAuto() + .computeMultiplierAuto() + .evalIntervalAuto() + .evalSamplesAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .reasoningEffort( + ReinforcementHyperparameters.ReasoningEffort + .DEFAULT + ) + .build() + ) + .build() + ) .supervised( - JobCreateParams.Method.Supervised.builder() + SupervisedMethod.builder() .hyperparameters( - JobCreateParams.Method.Supervised.Hyperparameters - .builder() + SupervisedHyperparameters.builder() .batchSizeAuto() .learningRateMultiplierAuto() .nEpochsAuto() @@ -135,7 +168,6 @@ internal class ErrorHandlingTest { ) .build() ) - .type(JobCreateParams.Method.Type.SUPERVISED) .build() ) .seed(42L) @@ -202,10 +234,11 @@ internal class ErrorHandlingTest { ) .method( JobCreateParams.Method.builder() + .type(JobCreateParams.Method.Type.SUPERVISED) .dpo( - JobCreateParams.Method.Dpo.builder() + DpoMethod.builder() .hyperparameters( - JobCreateParams.Method.Dpo.Hyperparameters.builder() + DpoHyperparameters.builder() .batchSizeAuto() .betaAuto() .learningRateMultiplierAuto() @@ -214,11 +247,36 @@ internal class ErrorHandlingTest { ) .build() ) + .reinforcement( + ReinforcementMethod.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .hyperparameters( + ReinforcementHyperparameters.builder() + .batchSizeAuto() + .computeMultiplierAuto() + .evalIntervalAuto() + .evalSamplesAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .reasoningEffort( + ReinforcementHyperparameters.ReasoningEffort + .DEFAULT + ) + .build() + ) + .build() + ) .supervised( - JobCreateParams.Method.Supervised.builder() + SupervisedMethod.builder() .hyperparameters( - JobCreateParams.Method.Supervised.Hyperparameters - .builder() + SupervisedHyperparameters.builder() .batchSizeAuto() .learningRateMultiplierAuto() .nEpochsAuto() @@ -226,7 +284,6 @@ internal class ErrorHandlingTest { ) .build() ) - .type(JobCreateParams.Method.Type.SUPERVISED) .build() ) .seed(42L) @@ -293,10 +350,11 @@ internal class ErrorHandlingTest { ) .method( JobCreateParams.Method.builder() + .type(JobCreateParams.Method.Type.SUPERVISED) .dpo( - JobCreateParams.Method.Dpo.builder() + DpoMethod.builder() .hyperparameters( - JobCreateParams.Method.Dpo.Hyperparameters.builder() + DpoHyperparameters.builder() .batchSizeAuto() .betaAuto() .learningRateMultiplierAuto() @@ -305,11 +363,36 @@ internal class ErrorHandlingTest { ) .build() ) + .reinforcement( + ReinforcementMethod.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .hyperparameters( + ReinforcementHyperparameters.builder() + .batchSizeAuto() + .computeMultiplierAuto() + .evalIntervalAuto() + .evalSamplesAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .reasoningEffort( + ReinforcementHyperparameters.ReasoningEffort + .DEFAULT + ) + .build() + ) + .build() + ) .supervised( - JobCreateParams.Method.Supervised.builder() + SupervisedMethod.builder() .hyperparameters( - JobCreateParams.Method.Supervised.Hyperparameters - .builder() + SupervisedHyperparameters.builder() .batchSizeAuto() .learningRateMultiplierAuto() .nEpochsAuto() @@ -317,7 +400,6 @@ internal class ErrorHandlingTest { ) .build() ) - .type(JobCreateParams.Method.Type.SUPERVISED) .build() ) .seed(42L) @@ -384,10 +466,11 @@ internal class ErrorHandlingTest { ) .method( JobCreateParams.Method.builder() + .type(JobCreateParams.Method.Type.SUPERVISED) .dpo( - JobCreateParams.Method.Dpo.builder() + DpoMethod.builder() .hyperparameters( - JobCreateParams.Method.Dpo.Hyperparameters.builder() + DpoHyperparameters.builder() .batchSizeAuto() .betaAuto() .learningRateMultiplierAuto() @@ -396,11 +479,36 @@ internal class ErrorHandlingTest { ) .build() ) + .reinforcement( + ReinforcementMethod.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .hyperparameters( + ReinforcementHyperparameters.builder() + .batchSizeAuto() + .computeMultiplierAuto() + .evalIntervalAuto() + .evalSamplesAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .reasoningEffort( + ReinforcementHyperparameters.ReasoningEffort + .DEFAULT + ) + .build() + ) + .build() + ) .supervised( - JobCreateParams.Method.Supervised.builder() + SupervisedMethod.builder() .hyperparameters( - JobCreateParams.Method.Supervised.Hyperparameters - .builder() + SupervisedHyperparameters.builder() .batchSizeAuto() .learningRateMultiplierAuto() .nEpochsAuto() @@ -408,7 +516,6 @@ internal class ErrorHandlingTest { ) .build() ) - .type(JobCreateParams.Method.Type.SUPERVISED) .build() ) .seed(42L) @@ -475,10 +582,11 @@ internal class ErrorHandlingTest { ) .method( JobCreateParams.Method.builder() + .type(JobCreateParams.Method.Type.SUPERVISED) .dpo( - JobCreateParams.Method.Dpo.builder() + DpoMethod.builder() .hyperparameters( - JobCreateParams.Method.Dpo.Hyperparameters.builder() + DpoHyperparameters.builder() .batchSizeAuto() .betaAuto() .learningRateMultiplierAuto() @@ -487,11 +595,36 @@ internal class ErrorHandlingTest { ) .build() ) + .reinforcement( + ReinforcementMethod.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .hyperparameters( + ReinforcementHyperparameters.builder() + .batchSizeAuto() + .computeMultiplierAuto() + .evalIntervalAuto() + .evalSamplesAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .reasoningEffort( + ReinforcementHyperparameters.ReasoningEffort + .DEFAULT + ) + .build() + ) + .build() + ) .supervised( - JobCreateParams.Method.Supervised.builder() + SupervisedMethod.builder() .hyperparameters( - JobCreateParams.Method.Supervised.Hyperparameters - .builder() + SupervisedHyperparameters.builder() .batchSizeAuto() .learningRateMultiplierAuto() .nEpochsAuto() @@ -499,7 +632,6 @@ internal class ErrorHandlingTest { ) .build() ) - .type(JobCreateParams.Method.Type.SUPERVISED) .build() ) .seed(42L) @@ -566,10 +698,11 @@ internal class ErrorHandlingTest { ) .method( JobCreateParams.Method.builder() + .type(JobCreateParams.Method.Type.SUPERVISED) .dpo( - JobCreateParams.Method.Dpo.builder() + DpoMethod.builder() .hyperparameters( - JobCreateParams.Method.Dpo.Hyperparameters.builder() + DpoHyperparameters.builder() .batchSizeAuto() .betaAuto() .learningRateMultiplierAuto() @@ -578,11 +711,36 @@ internal class ErrorHandlingTest { ) .build() ) + .reinforcement( + ReinforcementMethod.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .hyperparameters( + ReinforcementHyperparameters.builder() + .batchSizeAuto() + .computeMultiplierAuto() + .evalIntervalAuto() + .evalSamplesAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .reasoningEffort( + ReinforcementHyperparameters.ReasoningEffort + .DEFAULT + ) + .build() + ) + .build() + ) .supervised( - JobCreateParams.Method.Supervised.builder() + SupervisedMethod.builder() .hyperparameters( - JobCreateParams.Method.Supervised.Hyperparameters - .builder() + SupervisedHyperparameters.builder() .batchSizeAuto() .learningRateMultiplierAuto() .nEpochsAuto() @@ -590,7 +748,6 @@ internal class ErrorHandlingTest { ) .build() ) - .type(JobCreateParams.Method.Type.SUPERVISED) .build() ) .seed(42L) @@ -657,10 +814,11 @@ internal class ErrorHandlingTest { ) .method( JobCreateParams.Method.builder() + .type(JobCreateParams.Method.Type.SUPERVISED) .dpo( - JobCreateParams.Method.Dpo.builder() + DpoMethod.builder() .hyperparameters( - JobCreateParams.Method.Dpo.Hyperparameters.builder() + DpoHyperparameters.builder() .batchSizeAuto() .betaAuto() .learningRateMultiplierAuto() @@ -669,11 +827,36 @@ internal class ErrorHandlingTest { ) .build() ) + .reinforcement( + ReinforcementMethod.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .hyperparameters( + ReinforcementHyperparameters.builder() + .batchSizeAuto() + .computeMultiplierAuto() + .evalIntervalAuto() + .evalSamplesAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .reasoningEffort( + ReinforcementHyperparameters.ReasoningEffort + .DEFAULT + ) + .build() + ) + .build() + ) .supervised( - JobCreateParams.Method.Supervised.builder() + SupervisedMethod.builder() .hyperparameters( - JobCreateParams.Method.Supervised.Hyperparameters - .builder() + SupervisedHyperparameters.builder() .batchSizeAuto() .learningRateMultiplierAuto() .nEpochsAuto() @@ -681,7 +864,6 @@ internal class ErrorHandlingTest { ) .build() ) - .type(JobCreateParams.Method.Type.SUPERVISED) .build() ) .seed(42L) @@ -748,10 +930,11 @@ internal class ErrorHandlingTest { ) .method( JobCreateParams.Method.builder() + .type(JobCreateParams.Method.Type.SUPERVISED) .dpo( - JobCreateParams.Method.Dpo.builder() + DpoMethod.builder() .hyperparameters( - JobCreateParams.Method.Dpo.Hyperparameters.builder() + DpoHyperparameters.builder() .batchSizeAuto() .betaAuto() .learningRateMultiplierAuto() @@ -760,11 +943,36 @@ internal class ErrorHandlingTest { ) .build() ) + .reinforcement( + ReinforcementMethod.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .hyperparameters( + ReinforcementHyperparameters.builder() + .batchSizeAuto() + .computeMultiplierAuto() + .evalIntervalAuto() + .evalSamplesAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .reasoningEffort( + ReinforcementHyperparameters.ReasoningEffort + .DEFAULT + ) + .build() + ) + .build() + ) .supervised( - JobCreateParams.Method.Supervised.builder() + SupervisedMethod.builder() .hyperparameters( - JobCreateParams.Method.Supervised.Hyperparameters - .builder() + SupervisedHyperparameters.builder() .batchSizeAuto() .learningRateMultiplierAuto() .nEpochsAuto() @@ -772,7 +980,6 @@ internal class ErrorHandlingTest { ) .build() ) - .type(JobCreateParams.Method.Type.SUPERVISED) .build() ) .seed(42L) @@ -837,10 +1044,11 @@ internal class ErrorHandlingTest { ) .method( JobCreateParams.Method.builder() + .type(JobCreateParams.Method.Type.SUPERVISED) .dpo( - JobCreateParams.Method.Dpo.builder() + DpoMethod.builder() .hyperparameters( - JobCreateParams.Method.Dpo.Hyperparameters.builder() + DpoHyperparameters.builder() .batchSizeAuto() .betaAuto() .learningRateMultiplierAuto() @@ -849,11 +1057,36 @@ internal class ErrorHandlingTest { ) .build() ) + .reinforcement( + ReinforcementMethod.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .hyperparameters( + ReinforcementHyperparameters.builder() + .batchSizeAuto() + .computeMultiplierAuto() + .evalIntervalAuto() + .evalSamplesAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .reasoningEffort( + ReinforcementHyperparameters.ReasoningEffort + .DEFAULT + ) + .build() + ) + .build() + ) .supervised( - JobCreateParams.Method.Supervised.builder() + SupervisedMethod.builder() .hyperparameters( - JobCreateParams.Method.Supervised.Hyperparameters - .builder() + SupervisedHyperparameters.builder() .batchSizeAuto() .learningRateMultiplierAuto() .nEpochsAuto() @@ -861,7 +1094,6 @@ internal class ErrorHandlingTest { ) .build() ) - .type(JobCreateParams.Method.Type.SUPERVISED) .build() ) .seed(42L) diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/BatchServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/BatchServiceAsyncTest.kt index 25228c55..bddf750d 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/async/BatchServiceAsyncTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/BatchServiceAsyncTest.kt @@ -5,9 +5,7 @@ package com.openai.services.async import com.openai.TestServerExtension import com.openai.client.okhttp.OpenAIOkHttpClientAsync import com.openai.core.JsonValue -import com.openai.models.batches.BatchCancelParams import com.openai.models.batches.BatchCreateParams -import com.openai.models.batches.BatchRetrieveParams import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -50,8 +48,7 @@ internal class BatchServiceAsyncTest { .build() val batchServiceAsync = client.batches() - val batchFuture = - batchServiceAsync.retrieve(BatchRetrieveParams.builder().batchId("batch_id").build()) + val batchFuture = batchServiceAsync.retrieve("batch_id") val batch = batchFuture.get() batch.validate() @@ -81,8 +78,7 @@ internal class BatchServiceAsyncTest { .build() val batchServiceAsync = client.batches() - val batchFuture = - batchServiceAsync.cancel(BatchCancelParams.builder().batchId("batch_id").build()) + val batchFuture = batchServiceAsync.cancel("batch_id") val batch = batchFuture.get() batch.validate() diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/EvalServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/EvalServiceAsyncTest.kt index b4a7c4fb..1f940b24 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/async/EvalServiceAsyncTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/EvalServiceAsyncTest.kt @@ -6,8 +6,6 @@ import com.openai.TestServerExtension import com.openai.client.okhttp.OpenAIOkHttpClientAsync import com.openai.core.JsonValue import com.openai.models.evals.EvalCreateParams -import com.openai.models.evals.EvalDeleteParams -import com.openai.models.evals.EvalRetrieveParams import com.openai.models.evals.EvalUpdateParams import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -75,8 +73,7 @@ internal class EvalServiceAsyncTest { .build() val evalServiceAsync = client.evals() - val evalFuture = - evalServiceAsync.retrieve(EvalRetrieveParams.builder().evalId("eval_id").build()) + val evalFuture = evalServiceAsync.retrieve("eval_id") val eval = evalFuture.get() eval.validate() @@ -132,8 +129,7 @@ internal class EvalServiceAsyncTest { .build() val evalServiceAsync = client.evals() - val evalFuture = - evalServiceAsync.delete(EvalDeleteParams.builder().evalId("eval_id").build()) + val evalFuture = evalServiceAsync.delete("eval_id") val eval = evalFuture.get() eval.validate() diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/FileServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/FileServiceAsyncTest.kt index 6c8af86c..0156759e 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/async/FileServiceAsyncTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/FileServiceAsyncTest.kt @@ -10,11 +10,8 @@ import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo import com.github.tomakehurst.wiremock.junit5.WireMockTest import com.openai.TestServerExtension import com.openai.client.okhttp.OpenAIOkHttpClientAsync -import com.openai.models.files.FileContentParams import com.openai.models.files.FileCreateParams -import com.openai.models.files.FileDeleteParams import com.openai.models.files.FilePurpose -import com.openai.models.files.FileRetrieveParams import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -55,8 +52,7 @@ internal class FileServiceAsyncTest { .build() val fileServiceAsync = client.files() - val fileObjectFuture = - fileServiceAsync.retrieve(FileRetrieveParams.builder().fileId("file_id").build()) + val fileObjectFuture = fileServiceAsync.retrieve("file_id") val fileObject = fileObjectFuture.get() fileObject.validate() @@ -86,8 +82,7 @@ internal class FileServiceAsyncTest { .build() val fileServiceAsync = client.files() - val fileDeletedFuture = - fileServiceAsync.delete(FileDeleteParams.builder().fileId("file_id").build()) + val fileDeletedFuture = fileServiceAsync.delete("file_id") val fileDeleted = fileDeletedFuture.get() fileDeleted.validate() @@ -103,8 +98,7 @@ internal class FileServiceAsyncTest { val fileServiceAsync = client.files() stubFor(get(anyUrl()).willReturn(ok().withBody("abc"))) - val responseFuture = - fileServiceAsync.content(FileContentParams.builder().fileId("file_id").build()) + val responseFuture = fileServiceAsync.content("file_id") val response = responseFuture.get() assertThat(response.body()).hasContent("abc") diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/ModelServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/ModelServiceAsyncTest.kt index 25b7ab23..95ab7c7f 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/async/ModelServiceAsyncTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/ModelServiceAsyncTest.kt @@ -4,8 +4,6 @@ package com.openai.services.async import com.openai.TestServerExtension import com.openai.client.okhttp.OpenAIOkHttpClientAsync -import com.openai.models.models.ModelDeleteParams -import com.openai.models.models.ModelRetrieveParams import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -21,8 +19,7 @@ internal class ModelServiceAsyncTest { .build() val modelServiceAsync = client.models() - val modelFuture = - modelServiceAsync.retrieve(ModelRetrieveParams.builder().model("gpt-4o-mini").build()) + val modelFuture = modelServiceAsync.retrieve("gpt-4o-mini") val model = modelFuture.get() model.validate() @@ -52,10 +49,7 @@ internal class ModelServiceAsyncTest { .build() val modelServiceAsync = client.models() - val modelDeletedFuture = - modelServiceAsync.delete( - ModelDeleteParams.builder().model("ft:gpt-4o-mini:acemeco:suffix:abc123").build() - ) + val modelDeletedFuture = modelServiceAsync.delete("ft:gpt-4o-mini:acemeco:suffix:abc123") val modelDeleted = modelDeletedFuture.get() modelDeleted.validate() diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/ResponseServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/ResponseServiceAsyncTest.kt index a7f6183b..8e6658e3 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/async/ResponseServiceAsyncTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/ResponseServiceAsyncTest.kt @@ -12,7 +12,6 @@ import com.openai.models.ReasoningEffort import com.openai.models.ResponseFormatText import com.openai.models.responses.FileSearchTool import com.openai.models.responses.ResponseCreateParams -import com.openai.models.responses.ResponseDeleteParams import com.openai.models.responses.ResponseIncludable import com.openai.models.responses.ResponseRetrieveParams import com.openai.models.responses.ResponseTextConfig @@ -192,12 +191,7 @@ internal class ResponseServiceAsyncTest { .build() val responseServiceAsync = client.responses() - val future = - responseServiceAsync.delete( - ResponseDeleteParams.builder() - .responseId("resp_677efb5139a88190b512bc3fef8e535d") - .build() - ) + val future = responseServiceAsync.delete("resp_677efb5139a88190b512bc3fef8e535d") val response = future.get() } diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/UploadServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/UploadServiceAsyncTest.kt index 0b652b22..48edbd35 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/async/UploadServiceAsyncTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/UploadServiceAsyncTest.kt @@ -5,7 +5,6 @@ package com.openai.services.async import com.openai.TestServerExtension import com.openai.client.okhttp.OpenAIOkHttpClientAsync import com.openai.models.files.FilePurpose -import com.openai.models.uploads.UploadCancelParams import com.openai.models.uploads.UploadCompleteParams import com.openai.models.uploads.UploadCreateParams import org.junit.jupiter.api.Test @@ -46,10 +45,7 @@ internal class UploadServiceAsyncTest { .build() val uploadServiceAsync = client.uploads() - val uploadFuture = - uploadServiceAsync.cancel( - UploadCancelParams.builder().uploadId("upload_abc123").build() - ) + val uploadFuture = uploadServiceAsync.cancel("upload_abc123") val upload = uploadFuture.get() upload.validate() diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/VectorStoreServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/VectorStoreServiceAsyncTest.kt index 90a9bf88..63306b10 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/async/VectorStoreServiceAsyncTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/VectorStoreServiceAsyncTest.kt @@ -7,8 +7,6 @@ import com.openai.client.okhttp.OpenAIOkHttpClientAsync import com.openai.core.JsonValue import com.openai.models.vectorstores.AutoFileChunkingStrategyParam import com.openai.models.vectorstores.VectorStoreCreateParams -import com.openai.models.vectorstores.VectorStoreDeleteParams -import com.openai.models.vectorstores.VectorStoreRetrieveParams import com.openai.models.vectorstores.VectorStoreSearchParams import com.openai.models.vectorstores.VectorStoreUpdateParams import org.junit.jupiter.api.Test @@ -54,10 +52,7 @@ internal class VectorStoreServiceAsyncTest { .build() val vectorStoreServiceAsync = client.vectorStores() - val vectorStoreFuture = - vectorStoreServiceAsync.retrieve( - VectorStoreRetrieveParams.builder().vectorStoreId("vector_store_id").build() - ) + val vectorStoreFuture = vectorStoreServiceAsync.retrieve("vector_store_id") val vectorStore = vectorStoreFuture.get() vectorStore.validate() @@ -114,10 +109,7 @@ internal class VectorStoreServiceAsyncTest { .build() val vectorStoreServiceAsync = client.vectorStores() - val vectorStoreDeletedFuture = - vectorStoreServiceAsync.delete( - VectorStoreDeleteParams.builder().vectorStoreId("vector_store_id").build() - ) + val vectorStoreDeletedFuture = vectorStoreServiceAsync.delete("vector_store_id") val vectorStoreDeleted = vectorStoreDeletedFuture.get() vectorStoreDeleted.validate() diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/beta/AssistantServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/beta/AssistantServiceAsyncTest.kt index b731d493..bf5eebb4 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/async/beta/AssistantServiceAsyncTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/beta/AssistantServiceAsyncTest.kt @@ -8,8 +8,6 @@ import com.openai.core.JsonValue import com.openai.models.ChatModel import com.openai.models.ReasoningEffort import com.openai.models.beta.assistants.AssistantCreateParams -import com.openai.models.beta.assistants.AssistantDeleteParams -import com.openai.models.beta.assistants.AssistantRetrieveParams import com.openai.models.beta.assistants.AssistantUpdateParams import com.openai.models.beta.assistants.CodeInterpreterTool import org.junit.jupiter.api.Test @@ -92,10 +90,7 @@ internal class AssistantServiceAsyncTest { .build() val assistantServiceAsync = client.beta().assistants() - val assistantFuture = - assistantServiceAsync.retrieve( - AssistantRetrieveParams.builder().assistantId("assistant_id").build() - ) + val assistantFuture = assistantServiceAsync.retrieve("assistant_id") val assistant = assistantFuture.get() assistant.validate() @@ -173,10 +168,7 @@ internal class AssistantServiceAsyncTest { .build() val assistantServiceAsync = client.beta().assistants() - val assistantDeletedFuture = - assistantServiceAsync.delete( - AssistantDeleteParams.builder().assistantId("assistant_id").build() - ) + val assistantDeletedFuture = assistantServiceAsync.delete("assistant_id") val assistantDeleted = assistantDeletedFuture.get() assistantDeleted.validate() diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/beta/ThreadServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/beta/ThreadServiceAsyncTest.kt index cb993034..91ba504c 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/async/beta/ThreadServiceAsyncTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/beta/ThreadServiceAsyncTest.kt @@ -10,8 +10,6 @@ import com.openai.models.beta.assistants.CodeInterpreterTool import com.openai.models.beta.threads.AssistantToolChoiceOption import com.openai.models.beta.threads.ThreadCreateAndRunParams import com.openai.models.beta.threads.ThreadCreateParams -import com.openai.models.beta.threads.ThreadDeleteParams -import com.openai.models.beta.threads.ThreadRetrieveParams import com.openai.models.beta.threads.ThreadUpdateParams import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -101,10 +99,7 @@ internal class ThreadServiceAsyncTest { .build() val threadServiceAsync = client.beta().threads() - val threadFuture = - threadServiceAsync.retrieve( - ThreadRetrieveParams.builder().threadId("thread_id").build() - ) + val threadFuture = threadServiceAsync.retrieve("thread_id") val thread = threadFuture.get() thread.validate() @@ -158,8 +153,7 @@ internal class ThreadServiceAsyncTest { .build() val threadServiceAsync = client.beta().threads() - val threadDeletedFuture = - threadServiceAsync.delete(ThreadDeleteParams.builder().threadId("thread_id").build()) + val threadDeletedFuture = threadServiceAsync.delete("thread_id") val threadDeleted = threadDeletedFuture.get() threadDeleted.validate() diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/beta/threads/MessageServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/beta/threads/MessageServiceAsyncTest.kt index 14c21f5c..088486d7 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/async/beta/threads/MessageServiceAsyncTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/beta/threads/MessageServiceAsyncTest.kt @@ -8,7 +8,6 @@ import com.openai.core.JsonValue import com.openai.models.beta.assistants.CodeInterpreterTool import com.openai.models.beta.threads.messages.MessageCreateParams import com.openai.models.beta.threads.messages.MessageDeleteParams -import com.openai.models.beta.threads.messages.MessageListParams import com.openai.models.beta.threads.messages.MessageRetrieveParams import com.openai.models.beta.threads.messages.MessageUpdateParams import org.junit.jupiter.api.Test @@ -106,8 +105,7 @@ internal class MessageServiceAsyncTest { .build() val messageServiceAsync = client.beta().threads().messages() - val pageFuture = - messageServiceAsync.list(MessageListParams.builder().threadId("thread_id").build()) + val pageFuture = messageServiceAsync.list("thread_id") val page = pageFuture.get() page.response().validate() diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/beta/threads/RunServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/beta/threads/RunServiceAsyncTest.kt index 70bdc4c7..51885c40 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/async/beta/threads/RunServiceAsyncTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/beta/threads/RunServiceAsyncTest.kt @@ -11,7 +11,6 @@ import com.openai.models.beta.assistants.CodeInterpreterTool import com.openai.models.beta.threads.AssistantToolChoiceOption import com.openai.models.beta.threads.runs.RunCancelParams import com.openai.models.beta.threads.runs.RunCreateParams -import com.openai.models.beta.threads.runs.RunListParams import com.openai.models.beta.threads.runs.RunRetrieveParams import com.openai.models.beta.threads.runs.RunSubmitToolOutputsParams import com.openai.models.beta.threads.runs.RunUpdateParams @@ -200,7 +199,7 @@ internal class RunServiceAsyncTest { .build() val runServiceAsync = client.beta().threads().runs() - val pageFuture = runServiceAsync.list(RunListParams.builder().threadId("thread_id").build()) + val pageFuture = runServiceAsync.list("thread_id") val page = pageFuture.get() page.response().validate() diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/chat/ChatCompletionServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/chat/ChatCompletionServiceAsyncTest.kt index 02928442..693c02d2 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/async/chat/ChatCompletionServiceAsyncTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/chat/ChatCompletionServiceAsyncTest.kt @@ -12,10 +12,8 @@ import com.openai.models.ReasoningEffort import com.openai.models.ResponseFormatText import com.openai.models.chat.completions.ChatCompletionAudioParam import com.openai.models.chat.completions.ChatCompletionCreateParams -import com.openai.models.chat.completions.ChatCompletionDeleteParams import com.openai.models.chat.completions.ChatCompletionDeveloperMessageParam import com.openai.models.chat.completions.ChatCompletionPredictionContent -import com.openai.models.chat.completions.ChatCompletionRetrieveParams import com.openai.models.chat.completions.ChatCompletionStreamOptions import com.openai.models.chat.completions.ChatCompletionTool import com.openai.models.chat.completions.ChatCompletionToolChoiceOption @@ -262,10 +260,7 @@ internal class ChatCompletionServiceAsyncTest { .build() val chatCompletionServiceAsync = client.chat().completions() - val chatCompletionFuture = - chatCompletionServiceAsync.retrieve( - ChatCompletionRetrieveParams.builder().completionId("completion_id").build() - ) + val chatCompletionFuture = chatCompletionServiceAsync.retrieve("completion_id") val chatCompletion = chatCompletionFuture.get() chatCompletion.validate() @@ -320,10 +315,7 @@ internal class ChatCompletionServiceAsyncTest { .build() val chatCompletionServiceAsync = client.chat().completions() - val chatCompletionDeletedFuture = - chatCompletionServiceAsync.delete( - ChatCompletionDeleteParams.builder().completionId("completion_id").build() - ) + val chatCompletionDeletedFuture = chatCompletionServiceAsync.delete("completion_id") val chatCompletionDeleted = chatCompletionDeletedFuture.get() chatCompletionDeleted.validate() diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/chat/completions/MessageServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/chat/completions/MessageServiceAsyncTest.kt index 5fbbb2fa..2c834f1f 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/async/chat/completions/MessageServiceAsyncTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/chat/completions/MessageServiceAsyncTest.kt @@ -4,7 +4,6 @@ package com.openai.services.async.chat.completions import com.openai.TestServerExtension import com.openai.client.okhttp.OpenAIOkHttpClientAsync -import com.openai.models.chat.completions.messages.MessageListParams import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -20,10 +19,7 @@ internal class MessageServiceAsyncTest { .build() val messageServiceAsync = client.chat().completions().messages() - val pageFuture = - messageServiceAsync.list( - MessageListParams.builder().completionId("completion_id").build() - ) + val pageFuture = messageServiceAsync.list("completion_id") val page = pageFuture.get() page.response().validate() diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/evals/RunServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/evals/RunServiceAsyncTest.kt index 22e9d8e9..2f621297 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/async/evals/RunServiceAsyncTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/evals/RunServiceAsyncTest.kt @@ -9,7 +9,6 @@ import com.openai.models.evals.runs.CreateEvalJsonlRunDataSource import com.openai.models.evals.runs.RunCancelParams import com.openai.models.evals.runs.RunCreateParams import com.openai.models.evals.runs.RunDeleteParams -import com.openai.models.evals.runs.RunListParams import com.openai.models.evals.runs.RunRetrieveParams import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -95,7 +94,7 @@ internal class RunServiceAsyncTest { .build() val runServiceAsync = client.evals().runs() - val pageFuture = runServiceAsync.list(RunListParams.builder().evalId("eval_id").build()) + val pageFuture = runServiceAsync.list("eval_id") val page = pageFuture.get() page.response().validate() diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/finetuning/JobServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/finetuning/JobServiceAsyncTest.kt index 69cee8ab..6a9b1aef 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/async/finetuning/JobServiceAsyncTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/finetuning/JobServiceAsyncTest.kt @@ -5,10 +5,14 @@ package com.openai.services.async.finetuning import com.openai.TestServerExtension import com.openai.client.okhttp.OpenAIOkHttpClientAsync import com.openai.core.JsonValue -import com.openai.models.finetuning.jobs.JobCancelParams import com.openai.models.finetuning.jobs.JobCreateParams -import com.openai.models.finetuning.jobs.JobListEventsParams -import com.openai.models.finetuning.jobs.JobRetrieveParams +import com.openai.models.finetuning.methods.DpoHyperparameters +import com.openai.models.finetuning.methods.DpoMethod +import com.openai.models.finetuning.methods.ReinforcementHyperparameters +import com.openai.models.finetuning.methods.ReinforcementMethod +import com.openai.models.finetuning.methods.SupervisedHyperparameters +import com.openai.models.finetuning.methods.SupervisedMethod +import com.openai.models.graders.gradermodels.StringCheckGrader import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -55,10 +59,11 @@ internal class JobServiceAsyncTest { ) .method( JobCreateParams.Method.builder() + .type(JobCreateParams.Method.Type.SUPERVISED) .dpo( - JobCreateParams.Method.Dpo.builder() + DpoMethod.builder() .hyperparameters( - JobCreateParams.Method.Dpo.Hyperparameters.builder() + DpoHyperparameters.builder() .batchSizeAuto() .betaAuto() .learningRateMultiplierAuto() @@ -67,10 +72,35 @@ internal class JobServiceAsyncTest { ) .build() ) + .reinforcement( + ReinforcementMethod.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .hyperparameters( + ReinforcementHyperparameters.builder() + .batchSizeAuto() + .computeMultiplierAuto() + .evalIntervalAuto() + .evalSamplesAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .reasoningEffort( + ReinforcementHyperparameters.ReasoningEffort.DEFAULT + ) + .build() + ) + .build() + ) .supervised( - JobCreateParams.Method.Supervised.builder() + SupervisedMethod.builder() .hyperparameters( - JobCreateParams.Method.Supervised.Hyperparameters.builder() + SupervisedHyperparameters.builder() .batchSizeAuto() .learningRateMultiplierAuto() .nEpochsAuto() @@ -78,7 +108,6 @@ internal class JobServiceAsyncTest { ) .build() ) - .type(JobCreateParams.Method.Type.SUPERVISED) .build() ) .seed(42L) @@ -100,10 +129,7 @@ internal class JobServiceAsyncTest { .build() val jobServiceAsync = client.fineTuning().jobs() - val fineTuningJobFuture = - jobServiceAsync.retrieve( - JobRetrieveParams.builder().fineTuningJobId("ft-AF1WoRqd3aJAHsqc9NY7iL8F").build() - ) + val fineTuningJobFuture = jobServiceAsync.retrieve("ft-AF1WoRqd3aJAHsqc9NY7iL8F") val fineTuningJob = fineTuningJobFuture.get() fineTuningJob.validate() @@ -133,10 +159,7 @@ internal class JobServiceAsyncTest { .build() val jobServiceAsync = client.fineTuning().jobs() - val fineTuningJobFuture = - jobServiceAsync.cancel( - JobCancelParams.builder().fineTuningJobId("ft-AF1WoRqd3aJAHsqc9NY7iL8F").build() - ) + val fineTuningJobFuture = jobServiceAsync.cancel("ft-AF1WoRqd3aJAHsqc9NY7iL8F") val fineTuningJob = fineTuningJobFuture.get() fineTuningJob.validate() @@ -151,12 +174,39 @@ internal class JobServiceAsyncTest { .build() val jobServiceAsync = client.fineTuning().jobs() - val pageFuture = - jobServiceAsync.listEvents( - JobListEventsParams.builder().fineTuningJobId("ft-AF1WoRqd3aJAHsqc9NY7iL8F").build() - ) + val pageFuture = jobServiceAsync.listEvents("ft-AF1WoRqd3aJAHsqc9NY7iL8F") val page = pageFuture.get() page.response().validate() } + + @Test + fun pause() { + val client = + OpenAIOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val jobServiceAsync = client.fineTuning().jobs() + + val fineTuningJobFuture = jobServiceAsync.pause("ft-AF1WoRqd3aJAHsqc9NY7iL8F") + + val fineTuningJob = fineTuningJobFuture.get() + fineTuningJob.validate() + } + + @Test + fun resume() { + val client = + OpenAIOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val jobServiceAsync = client.fineTuning().jobs() + + val fineTuningJobFuture = jobServiceAsync.resume("ft-AF1WoRqd3aJAHsqc9NY7iL8F") + + val fineTuningJob = fineTuningJobFuture.get() + fineTuningJob.validate() + } } diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/finetuning/alpha/GraderServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/finetuning/alpha/GraderServiceAsyncTest.kt new file mode 100644 index 00000000..e6f3f90e --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/finetuning/alpha/GraderServiceAsyncTest.kt @@ -0,0 +1,71 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.services.async.finetuning.alpha + +import com.openai.TestServerExtension +import com.openai.client.okhttp.OpenAIOkHttpClientAsync +import com.openai.models.finetuning.alpha.graders.GraderRunParams +import com.openai.models.finetuning.alpha.graders.GraderValidateParams +import com.openai.models.graders.gradermodels.StringCheckGrader +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class GraderServiceAsyncTest { + + @Test + fun run() { + val client = + OpenAIOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val graderServiceAsync = client.fineTuning().alpha().graders() + + val responseFuture = + graderServiceAsync.run( + GraderRunParams.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .modelSample("model_sample") + .referenceAnswer("string") + .build() + ) + + val response = responseFuture.get() + response.validate() + } + + @Test + fun validate() { + val client = + OpenAIOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val graderServiceAsync = client.fineTuning().alpha().graders() + + val responseFuture = + graderServiceAsync.validate( + GraderValidateParams.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .build() + ) + + val response = responseFuture.get() + response.validate() + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/finetuning/jobs/CheckpointServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/finetuning/jobs/CheckpointServiceAsyncTest.kt index ff0521c8..75bfa2d2 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/async/finetuning/jobs/CheckpointServiceAsyncTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/finetuning/jobs/CheckpointServiceAsyncTest.kt @@ -4,7 +4,6 @@ package com.openai.services.async.finetuning.jobs import com.openai.TestServerExtension import com.openai.client.okhttp.OpenAIOkHttpClientAsync -import com.openai.models.finetuning.jobs.checkpoints.CheckpointListParams import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -20,12 +19,7 @@ internal class CheckpointServiceAsyncTest { .build() val checkpointServiceAsync = client.fineTuning().jobs().checkpoints() - val pageFuture = - checkpointServiceAsync.list( - CheckpointListParams.builder() - .fineTuningJobId("ft-AF1WoRqd3aJAHsqc9NY7iL8F") - .build() - ) + val pageFuture = checkpointServiceAsync.list("ft-AF1WoRqd3aJAHsqc9NY7iL8F") val page = pageFuture.get() page.response().validate() diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/responses/InputItemServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/responses/InputItemServiceAsyncTest.kt index 241f678d..2c295376 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/async/responses/InputItemServiceAsyncTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/responses/InputItemServiceAsyncTest.kt @@ -4,7 +4,6 @@ package com.openai.services.async.responses import com.openai.TestServerExtension import com.openai.client.okhttp.OpenAIOkHttpClientAsync -import com.openai.models.responses.inputitems.InputItemListParams import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -20,10 +19,7 @@ internal class InputItemServiceAsyncTest { .build() val inputItemServiceAsync = client.responses().inputItems() - val pageFuture = - inputItemServiceAsync.list( - InputItemListParams.builder().responseId("response_id").build() - ) + val pageFuture = inputItemServiceAsync.list("response_id") val page = pageFuture.get() page.response().validate() diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/vectorstores/FileServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/vectorstores/FileServiceAsyncTest.kt index fdcfc551..b9564abe 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/async/vectorstores/FileServiceAsyncTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/vectorstores/FileServiceAsyncTest.kt @@ -9,7 +9,6 @@ import com.openai.models.vectorstores.AutoFileChunkingStrategyParam import com.openai.models.vectorstores.files.FileContentParams import com.openai.models.vectorstores.files.FileCreateParams import com.openai.models.vectorstores.files.FileDeleteParams -import com.openai.models.vectorstores.files.FileListParams import com.openai.models.vectorstores.files.FileRetrieveParams import com.openai.models.vectorstores.files.FileUpdateParams import org.junit.jupiter.api.Test @@ -101,8 +100,7 @@ internal class FileServiceAsyncTest { .build() val fileServiceAsync = client.vectorStores().files() - val pageFuture = - fileServiceAsync.list(FileListParams.builder().vectorStoreId("vector_store_id").build()) + val pageFuture = fileServiceAsync.list("vector_store_id") val page = pageFuture.get() page.response().validate() diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/BatchServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/BatchServiceTest.kt index 04ad53cd..1a798329 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/blocking/BatchServiceTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/BatchServiceTest.kt @@ -5,9 +5,7 @@ package com.openai.services.blocking import com.openai.TestServerExtension import com.openai.client.okhttp.OpenAIOkHttpClient import com.openai.core.JsonValue -import com.openai.models.batches.BatchCancelParams import com.openai.models.batches.BatchCreateParams -import com.openai.models.batches.BatchRetrieveParams import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -49,7 +47,7 @@ internal class BatchServiceTest { .build() val batchService = client.batches() - val batch = batchService.retrieve(BatchRetrieveParams.builder().batchId("batch_id").build()) + val batch = batchService.retrieve("batch_id") batch.validate() } @@ -77,7 +75,7 @@ internal class BatchServiceTest { .build() val batchService = client.batches() - val batch = batchService.cancel(BatchCancelParams.builder().batchId("batch_id").build()) + val batch = batchService.cancel("batch_id") batch.validate() } diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/EvalServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/EvalServiceTest.kt index 940e0822..61e2c487 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/blocking/EvalServiceTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/EvalServiceTest.kt @@ -6,8 +6,6 @@ import com.openai.TestServerExtension import com.openai.client.okhttp.OpenAIOkHttpClient import com.openai.core.JsonValue import com.openai.models.evals.EvalCreateParams -import com.openai.models.evals.EvalDeleteParams -import com.openai.models.evals.EvalRetrieveParams import com.openai.models.evals.EvalUpdateParams import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -74,7 +72,7 @@ internal class EvalServiceTest { .build() val evalService = client.evals() - val eval = evalService.retrieve(EvalRetrieveParams.builder().evalId("eval_id").build()) + val eval = evalService.retrieve("eval_id") eval.validate() } @@ -127,7 +125,7 @@ internal class EvalServiceTest { .build() val evalService = client.evals() - val eval = evalService.delete(EvalDeleteParams.builder().evalId("eval_id").build()) + val eval = evalService.delete("eval_id") eval.validate() } diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/FileServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/FileServiceTest.kt index 673fbbb2..ff77adfc 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/blocking/FileServiceTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/FileServiceTest.kt @@ -10,11 +10,8 @@ import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo import com.github.tomakehurst.wiremock.junit5.WireMockTest import com.openai.TestServerExtension import com.openai.client.okhttp.OpenAIOkHttpClient -import com.openai.models.files.FileContentParams import com.openai.models.files.FileCreateParams -import com.openai.models.files.FileDeleteParams import com.openai.models.files.FilePurpose -import com.openai.models.files.FileRetrieveParams import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -54,8 +51,7 @@ internal class FileServiceTest { .build() val fileService = client.files() - val fileObject = - fileService.retrieve(FileRetrieveParams.builder().fileId("file_id").build()) + val fileObject = fileService.retrieve("file_id") fileObject.validate() } @@ -83,7 +79,7 @@ internal class FileServiceTest { .build() val fileService = client.files() - val fileDeleted = fileService.delete(FileDeleteParams.builder().fileId("file_id").build()) + val fileDeleted = fileService.delete("file_id") fileDeleted.validate() } @@ -98,7 +94,7 @@ internal class FileServiceTest { val fileService = client.files() stubFor(get(anyUrl()).willReturn(ok().withBody("abc"))) - val response = fileService.content(FileContentParams.builder().fileId("file_id").build()) + val response = fileService.content("file_id") assertThat(response.body()).hasContent("abc") } diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/ModelServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/ModelServiceTest.kt index 4d899a1b..f00b554d 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/blocking/ModelServiceTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/ModelServiceTest.kt @@ -4,8 +4,6 @@ package com.openai.services.blocking import com.openai.TestServerExtension import com.openai.client.okhttp.OpenAIOkHttpClient -import com.openai.models.models.ModelDeleteParams -import com.openai.models.models.ModelRetrieveParams import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -21,8 +19,7 @@ internal class ModelServiceTest { .build() val modelService = client.models() - val model = - modelService.retrieve(ModelRetrieveParams.builder().model("gpt-4o-mini").build()) + val model = modelService.retrieve("gpt-4o-mini") model.validate() } @@ -50,10 +47,7 @@ internal class ModelServiceTest { .build() val modelService = client.models() - val modelDeleted = - modelService.delete( - ModelDeleteParams.builder().model("ft:gpt-4o-mini:acemeco:suffix:abc123").build() - ) + val modelDeleted = modelService.delete("ft:gpt-4o-mini:acemeco:suffix:abc123") modelDeleted.validate() } diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/ResponseServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/ResponseServiceTest.kt index e783dcb7..e8ae6452 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/blocking/ResponseServiceTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/ResponseServiceTest.kt @@ -12,7 +12,6 @@ import com.openai.models.ReasoningEffort import com.openai.models.ResponseFormatText import com.openai.models.responses.FileSearchTool import com.openai.models.responses.ResponseCreateParams -import com.openai.models.responses.ResponseDeleteParams import com.openai.models.responses.ResponseIncludable import com.openai.models.responses.ResponseRetrieveParams import com.openai.models.responses.ResponseTextConfig @@ -190,10 +189,6 @@ internal class ResponseServiceTest { .build() val responseService = client.responses() - responseService.delete( - ResponseDeleteParams.builder() - .responseId("resp_677efb5139a88190b512bc3fef8e535d") - .build() - ) + responseService.delete("resp_677efb5139a88190b512bc3fef8e535d") } } diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/UploadServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/UploadServiceTest.kt index 1affd622..26afefc1 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/blocking/UploadServiceTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/UploadServiceTest.kt @@ -5,7 +5,6 @@ package com.openai.services.blocking import com.openai.TestServerExtension import com.openai.client.okhttp.OpenAIOkHttpClient import com.openai.models.files.FilePurpose -import com.openai.models.uploads.UploadCancelParams import com.openai.models.uploads.UploadCompleteParams import com.openai.models.uploads.UploadCreateParams import org.junit.jupiter.api.Test @@ -45,8 +44,7 @@ internal class UploadServiceTest { .build() val uploadService = client.uploads() - val upload = - uploadService.cancel(UploadCancelParams.builder().uploadId("upload_abc123").build()) + val upload = uploadService.cancel("upload_abc123") upload.validate() } diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/VectorStoreServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/VectorStoreServiceTest.kt index 8c12104e..ba6b6886 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/blocking/VectorStoreServiceTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/VectorStoreServiceTest.kt @@ -7,8 +7,6 @@ import com.openai.client.okhttp.OpenAIOkHttpClient import com.openai.core.JsonValue import com.openai.models.vectorstores.AutoFileChunkingStrategyParam import com.openai.models.vectorstores.VectorStoreCreateParams -import com.openai.models.vectorstores.VectorStoreDeleteParams -import com.openai.models.vectorstores.VectorStoreRetrieveParams import com.openai.models.vectorstores.VectorStoreSearchParams import com.openai.models.vectorstores.VectorStoreUpdateParams import org.junit.jupiter.api.Test @@ -53,10 +51,7 @@ internal class VectorStoreServiceTest { .build() val vectorStoreService = client.vectorStores() - val vectorStore = - vectorStoreService.retrieve( - VectorStoreRetrieveParams.builder().vectorStoreId("vector_store_id").build() - ) + val vectorStore = vectorStoreService.retrieve("vector_store_id") vectorStore.validate() } @@ -110,10 +105,7 @@ internal class VectorStoreServiceTest { .build() val vectorStoreService = client.vectorStores() - val vectorStoreDeleted = - vectorStoreService.delete( - VectorStoreDeleteParams.builder().vectorStoreId("vector_store_id").build() - ) + val vectorStoreDeleted = vectorStoreService.delete("vector_store_id") vectorStoreDeleted.validate() } diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/AssistantServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/AssistantServiceTest.kt index d6381fc6..99bf5bf2 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/AssistantServiceTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/AssistantServiceTest.kt @@ -8,8 +8,6 @@ import com.openai.core.JsonValue import com.openai.models.ChatModel import com.openai.models.ReasoningEffort import com.openai.models.beta.assistants.AssistantCreateParams -import com.openai.models.beta.assistants.AssistantDeleteParams -import com.openai.models.beta.assistants.AssistantRetrieveParams import com.openai.models.beta.assistants.AssistantUpdateParams import com.openai.models.beta.assistants.CodeInterpreterTool import org.junit.jupiter.api.Test @@ -91,10 +89,7 @@ internal class AssistantServiceTest { .build() val assistantService = client.beta().assistants() - val assistant = - assistantService.retrieve( - AssistantRetrieveParams.builder().assistantId("assistant_id").build() - ) + val assistant = assistantService.retrieve("assistant_id") assistant.validate() } @@ -169,10 +164,7 @@ internal class AssistantServiceTest { .build() val assistantService = client.beta().assistants() - val assistantDeleted = - assistantService.delete( - AssistantDeleteParams.builder().assistantId("assistant_id").build() - ) + val assistantDeleted = assistantService.delete("assistant_id") assistantDeleted.validate() } diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/ThreadServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/ThreadServiceTest.kt index aefa7318..9cba341a 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/ThreadServiceTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/ThreadServiceTest.kt @@ -10,8 +10,6 @@ import com.openai.models.beta.assistants.CodeInterpreterTool import com.openai.models.beta.threads.AssistantToolChoiceOption import com.openai.models.beta.threads.ThreadCreateAndRunParams import com.openai.models.beta.threads.ThreadCreateParams -import com.openai.models.beta.threads.ThreadDeleteParams -import com.openai.models.beta.threads.ThreadRetrieveParams import com.openai.models.beta.threads.ThreadUpdateParams import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -100,8 +98,7 @@ internal class ThreadServiceTest { .build() val threadService = client.beta().threads() - val thread = - threadService.retrieve(ThreadRetrieveParams.builder().threadId("thread_id").build()) + val thread = threadService.retrieve("thread_id") thread.validate() } @@ -153,8 +150,7 @@ internal class ThreadServiceTest { .build() val threadService = client.beta().threads() - val threadDeleted = - threadService.delete(ThreadDeleteParams.builder().threadId("thread_id").build()) + val threadDeleted = threadService.delete("thread_id") threadDeleted.validate() } diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/threads/MessageServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/threads/MessageServiceTest.kt index be07d655..38c0580d 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/threads/MessageServiceTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/threads/MessageServiceTest.kt @@ -8,7 +8,6 @@ import com.openai.core.JsonValue import com.openai.models.beta.assistants.CodeInterpreterTool import com.openai.models.beta.threads.messages.MessageCreateParams import com.openai.models.beta.threads.messages.MessageDeleteParams -import com.openai.models.beta.threads.messages.MessageListParams import com.openai.models.beta.threads.messages.MessageRetrieveParams import com.openai.models.beta.threads.messages.MessageUpdateParams import org.junit.jupiter.api.Test @@ -103,7 +102,7 @@ internal class MessageServiceTest { .build() val messageService = client.beta().threads().messages() - val page = messageService.list(MessageListParams.builder().threadId("thread_id").build()) + val page = messageService.list("thread_id") page.response().validate() } diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/threads/RunServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/threads/RunServiceTest.kt index 6394703e..6d094b7d 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/threads/RunServiceTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/threads/RunServiceTest.kt @@ -11,7 +11,6 @@ import com.openai.models.beta.assistants.CodeInterpreterTool import com.openai.models.beta.threads.AssistantToolChoiceOption import com.openai.models.beta.threads.runs.RunCancelParams import com.openai.models.beta.threads.runs.RunCreateParams -import com.openai.models.beta.threads.runs.RunListParams import com.openai.models.beta.threads.runs.RunRetrieveParams import com.openai.models.beta.threads.runs.RunSubmitToolOutputsParams import com.openai.models.beta.threads.runs.RunUpdateParams @@ -195,7 +194,7 @@ internal class RunServiceTest { .build() val runService = client.beta().threads().runs() - val page = runService.list(RunListParams.builder().threadId("thread_id").build()) + val page = runService.list("thread_id") page.response().validate() } diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/chat/ChatCompletionServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/chat/ChatCompletionServiceTest.kt index bec6b5bb..9475a0eb 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/blocking/chat/ChatCompletionServiceTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/chat/ChatCompletionServiceTest.kt @@ -12,10 +12,8 @@ import com.openai.models.ReasoningEffort import com.openai.models.ResponseFormatText import com.openai.models.chat.completions.ChatCompletionAudioParam import com.openai.models.chat.completions.ChatCompletionCreateParams -import com.openai.models.chat.completions.ChatCompletionDeleteParams import com.openai.models.chat.completions.ChatCompletionDeveloperMessageParam import com.openai.models.chat.completions.ChatCompletionPredictionContent -import com.openai.models.chat.completions.ChatCompletionRetrieveParams import com.openai.models.chat.completions.ChatCompletionStreamOptions import com.openai.models.chat.completions.ChatCompletionTool import com.openai.models.chat.completions.ChatCompletionToolChoiceOption @@ -261,10 +259,7 @@ internal class ChatCompletionServiceTest { .build() val chatCompletionService = client.chat().completions() - val chatCompletion = - chatCompletionService.retrieve( - ChatCompletionRetrieveParams.builder().completionId("completion_id").build() - ) + val chatCompletion = chatCompletionService.retrieve("completion_id") chatCompletion.validate() } @@ -316,10 +311,7 @@ internal class ChatCompletionServiceTest { .build() val chatCompletionService = client.chat().completions() - val chatCompletionDeleted = - chatCompletionService.delete( - ChatCompletionDeleteParams.builder().completionId("completion_id").build() - ) + val chatCompletionDeleted = chatCompletionService.delete("completion_id") chatCompletionDeleted.validate() } diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/chat/completions/MessageServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/chat/completions/MessageServiceTest.kt index f591070d..3a1a7f10 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/blocking/chat/completions/MessageServiceTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/chat/completions/MessageServiceTest.kt @@ -4,7 +4,6 @@ package com.openai.services.blocking.chat.completions import com.openai.TestServerExtension import com.openai.client.okhttp.OpenAIOkHttpClient -import com.openai.models.chat.completions.messages.MessageListParams import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -20,8 +19,7 @@ internal class MessageServiceTest { .build() val messageService = client.chat().completions().messages() - val page = - messageService.list(MessageListParams.builder().completionId("completion_id").build()) + val page = messageService.list("completion_id") page.response().validate() } diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/evals/RunServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/evals/RunServiceTest.kt index 42a3eaaf..ded7e594 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/blocking/evals/RunServiceTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/evals/RunServiceTest.kt @@ -9,7 +9,6 @@ import com.openai.models.evals.runs.CreateEvalJsonlRunDataSource import com.openai.models.evals.runs.RunCancelParams import com.openai.models.evals.runs.RunCreateParams import com.openai.models.evals.runs.RunDeleteParams -import com.openai.models.evals.runs.RunListParams import com.openai.models.evals.runs.RunRetrieveParams import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -93,7 +92,7 @@ internal class RunServiceTest { .build() val runService = client.evals().runs() - val page = runService.list(RunListParams.builder().evalId("eval_id").build()) + val page = runService.list("eval_id") page.response().validate() } diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/finetuning/JobServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/finetuning/JobServiceTest.kt index fd91a8c0..662a78c5 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/blocking/finetuning/JobServiceTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/finetuning/JobServiceTest.kt @@ -5,10 +5,14 @@ package com.openai.services.blocking.finetuning import com.openai.TestServerExtension import com.openai.client.okhttp.OpenAIOkHttpClient import com.openai.core.JsonValue -import com.openai.models.finetuning.jobs.JobCancelParams import com.openai.models.finetuning.jobs.JobCreateParams -import com.openai.models.finetuning.jobs.JobListEventsParams -import com.openai.models.finetuning.jobs.JobRetrieveParams +import com.openai.models.finetuning.methods.DpoHyperparameters +import com.openai.models.finetuning.methods.DpoMethod +import com.openai.models.finetuning.methods.ReinforcementHyperparameters +import com.openai.models.finetuning.methods.ReinforcementMethod +import com.openai.models.finetuning.methods.SupervisedHyperparameters +import com.openai.models.finetuning.methods.SupervisedMethod +import com.openai.models.graders.gradermodels.StringCheckGrader import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -55,10 +59,11 @@ internal class JobServiceTest { ) .method( JobCreateParams.Method.builder() + .type(JobCreateParams.Method.Type.SUPERVISED) .dpo( - JobCreateParams.Method.Dpo.builder() + DpoMethod.builder() .hyperparameters( - JobCreateParams.Method.Dpo.Hyperparameters.builder() + DpoHyperparameters.builder() .batchSizeAuto() .betaAuto() .learningRateMultiplierAuto() @@ -67,10 +72,35 @@ internal class JobServiceTest { ) .build() ) + .reinforcement( + ReinforcementMethod.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .hyperparameters( + ReinforcementHyperparameters.builder() + .batchSizeAuto() + .computeMultiplierAuto() + .evalIntervalAuto() + .evalSamplesAuto() + .learningRateMultiplierAuto() + .nEpochsAuto() + .reasoningEffort( + ReinforcementHyperparameters.ReasoningEffort.DEFAULT + ) + .build() + ) + .build() + ) .supervised( - JobCreateParams.Method.Supervised.builder() + SupervisedMethod.builder() .hyperparameters( - JobCreateParams.Method.Supervised.Hyperparameters.builder() + SupervisedHyperparameters.builder() .batchSizeAuto() .learningRateMultiplierAuto() .nEpochsAuto() @@ -78,7 +108,6 @@ internal class JobServiceTest { ) .build() ) - .type(JobCreateParams.Method.Type.SUPERVISED) .build() ) .seed(42L) @@ -99,10 +128,7 @@ internal class JobServiceTest { .build() val jobService = client.fineTuning().jobs() - val fineTuningJob = - jobService.retrieve( - JobRetrieveParams.builder().fineTuningJobId("ft-AF1WoRqd3aJAHsqc9NY7iL8F").build() - ) + val fineTuningJob = jobService.retrieve("ft-AF1WoRqd3aJAHsqc9NY7iL8F") fineTuningJob.validate() } @@ -130,10 +156,7 @@ internal class JobServiceTest { .build() val jobService = client.fineTuning().jobs() - val fineTuningJob = - jobService.cancel( - JobCancelParams.builder().fineTuningJobId("ft-AF1WoRqd3aJAHsqc9NY7iL8F").build() - ) + val fineTuningJob = jobService.cancel("ft-AF1WoRqd3aJAHsqc9NY7iL8F") fineTuningJob.validate() } @@ -147,11 +170,36 @@ internal class JobServiceTest { .build() val jobService = client.fineTuning().jobs() - val page = - jobService.listEvents( - JobListEventsParams.builder().fineTuningJobId("ft-AF1WoRqd3aJAHsqc9NY7iL8F").build() - ) + val page = jobService.listEvents("ft-AF1WoRqd3aJAHsqc9NY7iL8F") page.response().validate() } + + @Test + fun pause() { + val client = + OpenAIOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val jobService = client.fineTuning().jobs() + + val fineTuningJob = jobService.pause("ft-AF1WoRqd3aJAHsqc9NY7iL8F") + + fineTuningJob.validate() + } + + @Test + fun resume() { + val client = + OpenAIOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val jobService = client.fineTuning().jobs() + + val fineTuningJob = jobService.resume("ft-AF1WoRqd3aJAHsqc9NY7iL8F") + + fineTuningJob.validate() + } } diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/finetuning/alpha/GraderServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/finetuning/alpha/GraderServiceTest.kt new file mode 100644 index 00000000..8d8ac5e3 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/finetuning/alpha/GraderServiceTest.kt @@ -0,0 +1,69 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.openai.services.blocking.finetuning.alpha + +import com.openai.TestServerExtension +import com.openai.client.okhttp.OpenAIOkHttpClient +import com.openai.models.finetuning.alpha.graders.GraderRunParams +import com.openai.models.finetuning.alpha.graders.GraderValidateParams +import com.openai.models.graders.gradermodels.StringCheckGrader +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class GraderServiceTest { + + @Test + fun run() { + val client = + OpenAIOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val graderService = client.fineTuning().alpha().graders() + + val response = + graderService.run( + GraderRunParams.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .modelSample("model_sample") + .referenceAnswer("string") + .build() + ) + + response.validate() + } + + @Test + fun validate() { + val client = + OpenAIOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val graderService = client.fineTuning().alpha().graders() + + val response = + graderService.validate( + GraderValidateParams.builder() + .grader( + StringCheckGrader.builder() + .input("input") + .name("name") + .operation(StringCheckGrader.Operation.EQ) + .reference("reference") + .build() + ) + .build() + ) + + response.validate() + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/finetuning/jobs/CheckpointServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/finetuning/jobs/CheckpointServiceTest.kt index 3ec97abb..0cb543e5 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/blocking/finetuning/jobs/CheckpointServiceTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/finetuning/jobs/CheckpointServiceTest.kt @@ -4,7 +4,6 @@ package com.openai.services.blocking.finetuning.jobs import com.openai.TestServerExtension import com.openai.client.okhttp.OpenAIOkHttpClient -import com.openai.models.finetuning.jobs.checkpoints.CheckpointListParams import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -20,12 +19,7 @@ internal class CheckpointServiceTest { .build() val checkpointService = client.fineTuning().jobs().checkpoints() - val page = - checkpointService.list( - CheckpointListParams.builder() - .fineTuningJobId("ft-AF1WoRqd3aJAHsqc9NY7iL8F") - .build() - ) + val page = checkpointService.list("ft-AF1WoRqd3aJAHsqc9NY7iL8F") page.response().validate() } diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/responses/InputItemServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/responses/InputItemServiceTest.kt index 7d3f09f0..fa48569e 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/blocking/responses/InputItemServiceTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/responses/InputItemServiceTest.kt @@ -4,7 +4,6 @@ package com.openai.services.blocking.responses import com.openai.TestServerExtension import com.openai.client.okhttp.OpenAIOkHttpClient -import com.openai.models.responses.inputitems.InputItemListParams import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -20,8 +19,7 @@ internal class InputItemServiceTest { .build() val inputItemService = client.responses().inputItems() - val page = - inputItemService.list(InputItemListParams.builder().responseId("response_id").build()) + val page = inputItemService.list("response_id") page.response().validate() } diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/vectorstores/FileServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/vectorstores/FileServiceTest.kt index ae9bdeeb..2c0f8c7e 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/blocking/vectorstores/FileServiceTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/vectorstores/FileServiceTest.kt @@ -9,7 +9,6 @@ import com.openai.models.vectorstores.AutoFileChunkingStrategyParam import com.openai.models.vectorstores.files.FileContentParams import com.openai.models.vectorstores.files.FileCreateParams import com.openai.models.vectorstores.files.FileDeleteParams -import com.openai.models.vectorstores.files.FileListParams import com.openai.models.vectorstores.files.FileRetrieveParams import com.openai.models.vectorstores.files.FileUpdateParams import org.junit.jupiter.api.Test @@ -98,8 +97,7 @@ internal class FileServiceTest { .build() val fileService = client.vectorStores().files() - val page = - fileService.list(FileListParams.builder().vectorStoreId("vector_store_id").build()) + val page = fileService.list("vector_store_id") page.response().validate() } diff --git a/openai-java-example/src/main/java/com/openai/example/AssistantAsyncExample.java b/openai-java-example/src/main/java/com/openai/example/AssistantAsyncExample.java index 93a80bb6..78f88231 100644 --- a/openai-java-example/src/main/java/com/openai/example/AssistantAsyncExample.java +++ b/openai-java-example/src/main/java/com/openai/example/AssistantAsyncExample.java @@ -109,18 +109,14 @@ private static CompletableFuture listThreadMessages(OpenAIClientAsync clie .order(MessageListParams.Order.ASC) .build()); return pageFuture.thenComposeAsync(page -> page.autoPager() - .forEach( - currentMessage -> { - System.out.println(currentMessage.role().toString().toUpperCase()); - currentMessage.content().stream() - .flatMap(content -> content.text().stream()) - .forEach(textBlock -> - System.out.println(textBlock.text().value())); - System.out.println(); - - // Keep iterating - return true; - }, - pageFuture.defaultExecutor())); + .subscribe(currentMessage -> { + System.out.println(currentMessage.role().toString().toUpperCase()); + currentMessage.content().stream() + .flatMap(content -> content.text().stream()) + .forEach(textBlock -> + System.out.println(textBlock.text().value())); + System.out.println(); + }) + .onCompleteFuture()); } } diff --git a/openai-java-example/src/main/java/com/openai/example/ModelListAsyncExample.java b/openai-java-example/src/main/java/com/openai/example/ModelListAsyncExample.java index 29376e7b..3233ef08 100644 --- a/openai-java-example/src/main/java/com/openai/example/ModelListAsyncExample.java +++ b/openai-java-example/src/main/java/com/openai/example/ModelListAsyncExample.java @@ -17,13 +17,8 @@ public static void main(String[] args) { CompletableFuture pageFuture = client.models().list(); pageFuture .thenComposeAsync(page -> page.autoPager() - .forEach( - model -> { - System.out.println(model.id()); - // Keep iterating - return true; - }, - pageFuture.defaultExecutor())) + .subscribe(model -> System.out.println(model.id())) + .onCompleteFuture()) .join(); } }