From 3e970ec8c9b3895b087f5722a0bfae23ca9e4e2c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 21 Oct 2025 22:33:39 +0000 Subject: [PATCH 1/5] fix(api): docs updates --- .stats.yml | 4 ++-- .../kotlin/com/openai/models/Reasoning.kt | 6 +++++ .../openai/models/files/FileCreateParams.kt | 19 +++++++-------- .../models/realtime/RealtimeTracingConfig.kt | 12 ++++++---- .../RealtimeSessionCreateResponse.kt | 18 ++++++++++---- .../openai/services/async/FileServiceAsync.kt | 24 +++++++++---------- .../openai/services/blocking/FileService.kt | 24 +++++++++---------- 7 files changed, 60 insertions(+), 47 deletions(-) diff --git a/.stats.yml b/.stats.yml index 7ec7944d..c55d0890 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 135 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-a4bb37d110a22c2888f53e21281434686a6fffa3e672a40f2503ad9bd2759063.yml -openapi_spec_hash: 2d59eefb494dff4eea8c3d008c7e2070 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-a3c45d9bd3bb25bf4eaa49b7fb473a00038293dec659ffaa44f624ded884abf4.yml +openapi_spec_hash: 9c20aaf786a0700dabd13d9865481c9e config_hash: 50ee3382a63c021a9f821a935950e926 diff --git a/openai-java-core/src/main/kotlin/com/openai/models/Reasoning.kt b/openai-java-core/src/main/kotlin/com/openai/models/Reasoning.kt index 0745f546..103795a3 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/Reasoning.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/Reasoning.kt @@ -72,6 +72,8 @@ private constructor( * A summary of the reasoning performed by the model. This can be useful for debugging and * understanding the model's reasoning process. One of `auto`, `concise`, or `detailed`. * + * `concise` is only supported for `computer-use-preview` models. + * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). */ @@ -187,6 +189,8 @@ private constructor( /** * A summary of the reasoning performed by the model. This can be useful for debugging and * understanding the model's reasoning process. One of `auto`, `concise`, or `detailed`. + * + * `concise` is only supported for `computer-use-preview` models. */ fun summary(summary: Summary?) = summary(JsonField.ofNullable(summary)) @@ -406,6 +410,8 @@ private constructor( /** * A summary of the reasoning performed by the model. This can be useful for debugging and * understanding the model's reasoning process. One of `auto`, `concise`, or `detailed`. + * + * `concise` is only supported for `computer-use-preview` models. */ class Summary @JsonCreator private constructor(private val value: JsonField) : Enum { diff --git a/openai-java-core/src/main/kotlin/com/openai/models/files/FileCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/files/FileCreateParams.kt index ac9548c3..967adfd9 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/files/FileCreateParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/files/FileCreateParams.kt @@ -25,17 +25,14 @@ import kotlin.io.path.name /** * Upload a file that can be used across various endpoints. Individual files can be up to 512 MB, * and the size of all files uploaded by one organization can be up to 1 TB. - * - * The Assistants API supports files up to 2 million tokens and of specific file types. See the - * [Assistants Tools guide](https://platform.openai.com/docs/assistants/tools) for details. - * - * The Fine-tuning API only supports `.jsonl` files. The input also has certain required formats for - * fine-tuning [chat](https://platform.openai.com/docs/api-reference/fine-tuning/chat-input) or - * [completions](https://platform.openai.com/docs/api-reference/fine-tuning/completions-input) - * models. - * - * The Batch API only supports `.jsonl` files up to 200 MB in size. The input also has a specific - * required [format](https://platform.openai.com/docs/api-reference/batch/request-input). + * - The Assistants API supports files up to 2 million tokens and of specific file types. See the + * [Assistants Tools guide](https://platform.openai.com/docs/assistants/tools) for details. + * - The Fine-tuning API only supports `.jsonl` files. The input also has certain required formats + * for fine-tuning [chat](https://platform.openai.com/docs/api-reference/fine-tuning/chat-input) + * or [completions](https://platform.openai.com/docs/api-reference/fine-tuning/completions-input) + * models. + * - The Batch API only supports `.jsonl` files up to 200 MB in size. The input also has a specific + * required [format](https://platform.openai.com/docs/api-reference/batch/request-input). * * Please [contact us](https://help.openai.com/) if you need to increase these storage limits. */ diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeTracingConfig.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeTracingConfig.kt index 33907e1e..6bc41dbe 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeTracingConfig.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeTracingConfig.kt @@ -42,7 +42,7 @@ private constructor( private val _json: JsonValue? = null, ) { - /** Default tracing mode for the session. */ + /** Enables tracing and sets default values for tracing configuration options. Always `auto`. */ fun auto(): Optional = Optional.ofNullable(auto) /** Granular configuration for tracing. */ @@ -53,7 +53,7 @@ private constructor( fun isTracingConfiguration(): Boolean = tracingConfiguration != null - /** Default tracing mode for the session. */ + /** Enables tracing and sets default values for tracing configuration options. Always `auto`. */ fun asAuto(): JsonValue = auto.getOrThrow("auto") /** Granular configuration for tracing. */ @@ -144,7 +144,9 @@ private constructor( companion object { - /** Default tracing mode for the session. */ + /** + * Enables tracing and sets default values for tracing configuration options. Always `auto`. + */ @JvmStatic fun ofAuto() = RealtimeTracingConfig(auto = JsonValue.from("auto")) /** Granular configuration for tracing. */ @@ -159,7 +161,9 @@ private constructor( */ interface Visitor { - /** Default tracing mode for the session. */ + /** + * Enables tracing and sets default values for tracing configuration options. Always `auto`. + */ fun visitAuto(auto: JsonValue): T /** Granular configuration for tracing. */ diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/clientsecrets/RealtimeSessionCreateResponse.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/clientsecrets/RealtimeSessionCreateResponse.kt index ba88b10b..8bb1b0b0 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/clientsecrets/RealtimeSessionCreateResponse.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/clientsecrets/RealtimeSessionCreateResponse.kt @@ -6657,7 +6657,9 @@ private constructor( private val _json: JsonValue? = null, ) { - /** Default tracing mode for the session. */ + /** + * Enables tracing and sets default values for tracing configuration options. Always `auto`. + */ fun auto(): Optional = Optional.ofNullable(auto) /** Granular configuration for tracing. */ @@ -6667,7 +6669,9 @@ private constructor( fun isConfiguration(): Boolean = configuration != null - /** Default tracing mode for the session. */ + /** + * Enables tracing and sets default values for tracing configuration options. Always `auto`. + */ fun asAuto(): JsonValue = auto.getOrThrow("auto") /** Granular configuration for tracing. */ @@ -6755,7 +6759,10 @@ private constructor( companion object { - /** Default tracing mode for the session. */ + /** + * Enables tracing and sets default values for tracing configuration options. Always + * `auto`. + */ @JvmStatic fun ofAuto() = Tracing(auto = JsonValue.from("auto")) /** Granular configuration for tracing. */ @@ -6769,7 +6776,10 @@ private constructor( */ interface Visitor { - /** Default tracing mode for the session. */ + /** + * Enables tracing and sets default values for tracing configuration options. Always + * `auto`. + */ fun visitAuto(auto: JsonValue): T /** Granular configuration for tracing. */ 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 2557498c..88c0d0d0 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 @@ -34,19 +34,17 @@ interface FileServiceAsync { /** * Upload a file that can be used across various endpoints. Individual files can be up to 512 * MB, and the size of all files uploaded by one organization can be up to 1 TB. - * - * The Assistants API supports files up to 2 million tokens and of specific file types. See the - * [Assistants Tools guide](https://platform.openai.com/docs/assistants/tools) for details. - * - * The Fine-tuning API only supports `.jsonl` files. The input also has certain required formats - * for fine-tuning [chat](https://platform.openai.com/docs/api-reference/fine-tuning/chat-input) - * or - * [completions](https://platform.openai.com/docs/api-reference/fine-tuning/completions-input) - * models. - * - * The Batch API only supports `.jsonl` files up to 200 MB in size. The input also has a - * specific required - * [format](https://platform.openai.com/docs/api-reference/batch/request-input). + * - The Assistants API supports files up to 2 million tokens and of specific file types. See + * the [Assistants Tools guide](https://platform.openai.com/docs/assistants/tools) for + * details. + * - The Fine-tuning API only supports `.jsonl` files. The input also has certain required + * formats for fine-tuning + * [chat](https://platform.openai.com/docs/api-reference/fine-tuning/chat-input) or + * [completions](https://platform.openai.com/docs/api-reference/fine-tuning/completions-input) + * models. + * - The Batch API only supports `.jsonl` files up to 200 MB in size. The input also has a + * specific required + * [format](https://platform.openai.com/docs/api-reference/batch/request-input). * * Please [contact us](https://help.openai.com/) if you need to increase these storage limits. */ 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 977b0e4b..ffd5413b 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 @@ -34,19 +34,17 @@ interface FileService { /** * Upload a file that can be used across various endpoints. Individual files can be up to 512 * MB, and the size of all files uploaded by one organization can be up to 1 TB. - * - * The Assistants API supports files up to 2 million tokens and of specific file types. See the - * [Assistants Tools guide](https://platform.openai.com/docs/assistants/tools) for details. - * - * The Fine-tuning API only supports `.jsonl` files. The input also has certain required formats - * for fine-tuning [chat](https://platform.openai.com/docs/api-reference/fine-tuning/chat-input) - * or - * [completions](https://platform.openai.com/docs/api-reference/fine-tuning/completions-input) - * models. - * - * The Batch API only supports `.jsonl` files up to 200 MB in size. The input also has a - * specific required - * [format](https://platform.openai.com/docs/api-reference/batch/request-input). + * - The Assistants API supports files up to 2 million tokens and of specific file types. See + * the [Assistants Tools guide](https://platform.openai.com/docs/assistants/tools) for + * details. + * - The Fine-tuning API only supports `.jsonl` files. The input also has certain required + * formats for fine-tuning + * [chat](https://platform.openai.com/docs/api-reference/fine-tuning/chat-input) or + * [completions](https://platform.openai.com/docs/api-reference/fine-tuning/completions-input) + * models. + * - The Batch API only supports `.jsonl` files up to 200 MB in size. The input also has a + * specific required + * [format](https://platform.openai.com/docs/api-reference/batch/request-input). * * Please [contact us](https://help.openai.com/) if you need to increase these storage limits. */ From 630fecf8f0e04ce82ac0f0df9b5d60df4edd0655 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 28 Oct 2025 00:54:06 +0000 Subject: [PATCH 2/5] feat(api): remove InputAudio from ResponseInputContent Removes the type `InputAudio` from `ResponseInputContent`. This parameter was non-functional and has now been removed. Please note that this is not a feature removal; it was never supported by the Responses API. While this is technically a backward-incompatible change due to the type removal, it reflects the intended behavior and has no functional impact. --- .stats.yml | 4 +- .../com/openai/models/responses/CustomTool.kt | 4 ++ .../models/responses/ResponseContent.kt | 39 +------------- .../models/responses/ResponseInputContent.kt | 36 +------------ .../models/responses/ResponseInputItem.kt | 17 ------ .../responses/ResponseInputMessageItem.kt | 15 ------ .../com/openai/models/responses/Tool.kt | 20 +++++++ .../models/responses/ResponseContentTest.kt | 53 ------------------- .../responses/ResponseInputContentTest.kt | 47 ---------------- 9 files changed, 29 insertions(+), 206 deletions(-) diff --git a/.stats.yml b/.stats.yml index c55d0890..b8fa5809 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 135 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-a3c45d9bd3bb25bf4eaa49b7fb473a00038293dec659ffaa44f624ded884abf4.yml -openapi_spec_hash: 9c20aaf786a0700dabd13d9865481c9e +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-f68f718cd45ac3f9336603601bccc38a718af44d0b26601031de3d0a71b7ce2f.yml +openapi_spec_hash: 1560717860bba4105936647dde8f618d config_hash: 50ee3382a63c021a9f821a935950e926 diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/CustomTool.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/CustomTool.kt index f1bfb23d..a52a482c 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/CustomTool.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/CustomTool.kt @@ -18,6 +18,10 @@ import java.util.Objects import java.util.Optional import kotlin.jvm.optionals.getOrNull +/** + * A custom tool that processes input using a specified format. Learn more about + * [custom tools](https://platform.openai.com/docs/guides/function-calling#custom-tools) + */ class CustomTool @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseContent.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseContent.kt index a074c40e..99610ff1 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseContent.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseContent.kt @@ -35,7 +35,6 @@ private constructor( private val inputText: ResponseInputText? = null, private val inputImage: ResponseInputImage? = null, private val inputFile: ResponseInputFile? = null, - private val inputAudio: ResponseInputAudio? = null, private val outputText: ResponseOutputText? = null, private val outputRefusal: ResponseOutputRefusal? = null, private val reasoningText: ReasoningTextContent? = null, @@ -54,9 +53,6 @@ private constructor( /** A file input to the model. */ fun inputFile(): Optional = Optional.ofNullable(inputFile) - /** An audio input to the model. */ - fun inputAudio(): Optional = Optional.ofNullable(inputAudio) - /** A text output from the model. */ fun outputText(): Optional = Optional.ofNullable(outputText) @@ -72,8 +68,6 @@ private constructor( fun isInputFile(): Boolean = inputFile != null - fun isInputAudio(): Boolean = inputAudio != null - fun isOutputText(): Boolean = outputText != null fun isOutputRefusal(): Boolean = outputRefusal != null @@ -92,9 +86,6 @@ private constructor( /** A file input to the model. */ fun asInputFile(): ResponseInputFile = inputFile.getOrThrow("inputFile") - /** An audio input to the model. */ - fun asInputAudio(): ResponseInputAudio = inputAudio.getOrThrow("inputAudio") - /** A text output from the model. */ fun asOutputText(): ResponseOutputText = outputText.getOrThrow("outputText") @@ -111,7 +102,6 @@ private constructor( inputText != null -> visitor.visitInputText(inputText) inputImage != null -> visitor.visitInputImage(inputImage) inputFile != null -> visitor.visitInputFile(inputFile) - inputAudio != null -> visitor.visitInputAudio(inputAudio) outputText != null -> visitor.visitOutputText(outputText) outputRefusal != null -> visitor.visitOutputRefusal(outputRefusal) reasoningText != null -> visitor.visitReasoningText(reasoningText) @@ -139,10 +129,6 @@ private constructor( inputFile.validate() } - override fun visitInputAudio(inputAudio: ResponseInputAudio) { - inputAudio.validate() - } - override fun visitOutputText(outputText: ResponseOutputText) { outputText.validate() } @@ -182,8 +168,6 @@ private constructor( override fun visitInputFile(inputFile: ResponseInputFile) = inputFile.validity() - override fun visitInputAudio(inputAudio: ResponseInputAudio) = inputAudio.validity() - override fun visitOutputText(outputText: ResponseOutputText) = outputText.validity() override fun visitOutputRefusal(outputRefusal: ResponseOutputRefusal) = @@ -205,29 +189,19 @@ private constructor( inputText == other.inputText && inputImage == other.inputImage && inputFile == other.inputFile && - inputAudio == other.inputAudio && outputText == other.outputText && outputRefusal == other.outputRefusal && reasoningText == other.reasoningText } override fun hashCode(): Int = - Objects.hash( - inputText, - inputImage, - inputFile, - inputAudio, - outputText, - outputRefusal, - reasoningText, - ) + Objects.hash(inputText, inputImage, inputFile, outputText, outputRefusal, reasoningText) override fun toString(): String = when { inputText != null -> "ResponseContent{inputText=$inputText}" inputImage != null -> "ResponseContent{inputImage=$inputImage}" inputFile != null -> "ResponseContent{inputFile=$inputFile}" - inputAudio != null -> "ResponseContent{inputAudio=$inputAudio}" outputText != null -> "ResponseContent{outputText=$outputText}" outputRefusal != null -> "ResponseContent{outputRefusal=$outputRefusal}" reasoningText != null -> "ResponseContent{reasoningText=$reasoningText}" @@ -252,10 +226,6 @@ private constructor( @JvmStatic fun ofInputFile(inputFile: ResponseInputFile) = ResponseContent(inputFile = inputFile) - /** An audio input to the model. */ - @JvmStatic - fun ofInputAudio(inputAudio: ResponseInputAudio) = ResponseContent(inputAudio = inputAudio) - /** A text output from the model. */ @JvmStatic fun ofOutputText(outputText: ResponseOutputText) = ResponseContent(outputText = outputText) @@ -289,9 +259,6 @@ private constructor( /** A file input to the model. */ fun visitInputFile(inputFile: ResponseInputFile): T - /** An audio input to the model. */ - fun visitInputAudio(inputAudio: ResponseInputAudio): T - /** A text output from the model. */ fun visitOutputText(outputText: ResponseOutputText): T @@ -332,9 +299,6 @@ private constructor( tryDeserialize(node, jacksonTypeRef())?.let { ResponseContent(inputFile = it, _json = json) }, - tryDeserialize(node, jacksonTypeRef())?.let { - ResponseContent(inputAudio = it, _json = json) - }, tryDeserialize(node, jacksonTypeRef())?.let { ResponseContent(outputText = it, _json = json) }, @@ -371,7 +335,6 @@ private constructor( value.inputText != null -> generator.writeObject(value.inputText) value.inputImage != null -> generator.writeObject(value.inputImage) value.inputFile != null -> generator.writeObject(value.inputFile) - value.inputAudio != null -> generator.writeObject(value.inputAudio) value.outputText != null -> generator.writeObject(value.outputText) value.outputRefusal != null -> generator.writeObject(value.outputRefusal) value.reasoningText != null -> generator.writeObject(value.reasoningText) diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseInputContent.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseInputContent.kt index 43e26a2a..252ffec1 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseInputContent.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseInputContent.kt @@ -26,7 +26,6 @@ private constructor( private val inputText: ResponseInputText? = null, private val inputImage: ResponseInputImage? = null, private val inputFile: ResponseInputFile? = null, - private val inputAudio: ResponseInputAudio? = null, private val _json: JsonValue? = null, ) { @@ -42,17 +41,12 @@ private constructor( /** A file input to the model. */ fun inputFile(): Optional = Optional.ofNullable(inputFile) - /** An audio input to the model. */ - fun inputAudio(): Optional = Optional.ofNullable(inputAudio) - fun isInputText(): Boolean = inputText != null fun isInputImage(): Boolean = inputImage != null fun isInputFile(): Boolean = inputFile != null - fun isInputAudio(): Boolean = inputAudio != null - /** A text input to the model. */ fun asInputText(): ResponseInputText = inputText.getOrThrow("inputText") @@ -65,9 +59,6 @@ private constructor( /** A file input to the model. */ fun asInputFile(): ResponseInputFile = inputFile.getOrThrow("inputFile") - /** An audio input to the model. */ - fun asInputAudio(): ResponseInputAudio = inputAudio.getOrThrow("inputAudio") - fun _json(): Optional = Optional.ofNullable(_json) fun accept(visitor: Visitor): T = @@ -75,7 +66,6 @@ private constructor( inputText != null -> visitor.visitInputText(inputText) inputImage != null -> visitor.visitInputImage(inputImage) inputFile != null -> visitor.visitInputFile(inputFile) - inputAudio != null -> visitor.visitInputAudio(inputAudio) else -> visitor.unknown(_json) } @@ -99,10 +89,6 @@ private constructor( override fun visitInputFile(inputFile: ResponseInputFile) { inputFile.validate() } - - override fun visitInputAudio(inputAudio: ResponseInputAudio) { - inputAudio.validate() - } } ) validated = true @@ -131,8 +117,6 @@ private constructor( override fun visitInputFile(inputFile: ResponseInputFile) = inputFile.validity() - override fun visitInputAudio(inputAudio: ResponseInputAudio) = inputAudio.validity() - override fun unknown(json: JsonValue?) = 0 } ) @@ -145,18 +129,16 @@ private constructor( return other is ResponseInputContent && inputText == other.inputText && inputImage == other.inputImage && - inputFile == other.inputFile && - inputAudio == other.inputAudio + inputFile == other.inputFile } - override fun hashCode(): Int = Objects.hash(inputText, inputImage, inputFile, inputAudio) + override fun hashCode(): Int = Objects.hash(inputText, inputImage, inputFile) override fun toString(): String = when { inputText != null -> "ResponseInputContent{inputText=$inputText}" inputImage != null -> "ResponseInputContent{inputImage=$inputImage}" inputFile != null -> "ResponseInputContent{inputFile=$inputFile}" - inputAudio != null -> "ResponseInputContent{inputAudio=$inputAudio}" _json != null -> "ResponseInputContent{_unknown=$_json}" else -> throw IllegalStateException("Invalid ResponseInputContent") } @@ -178,11 +160,6 @@ private constructor( /** A file input to the model. */ @JvmStatic fun ofInputFile(inputFile: ResponseInputFile) = ResponseInputContent(inputFile = inputFile) - - /** An audio input to the model. */ - @JvmStatic - fun ofInputAudio(inputAudio: ResponseInputAudio) = - ResponseInputContent(inputAudio = inputAudio) } /** @@ -203,9 +180,6 @@ private constructor( /** A file input to the model. */ fun visitInputFile(inputFile: ResponseInputFile): T - /** An audio input to the model. */ - fun visitInputAudio(inputAudio: ResponseInputAudio): T - /** * Maps an unknown variant of [ResponseInputContent] to a value of type [T]. * @@ -244,11 +218,6 @@ private constructor( ResponseInputContent(inputFile = it, _json = json) } ?: ResponseInputContent(_json = json) } - "input_audio" -> { - return tryDeserialize(node, jacksonTypeRef())?.let { - ResponseInputContent(inputAudio = it, _json = json) - } ?: ResponseInputContent(_json = json) - } } return ResponseInputContent(_json = json) @@ -266,7 +235,6 @@ private constructor( value.inputText != null -> generator.writeObject(value.inputText) value.inputImage != null -> generator.writeObject(value.inputImage) value.inputFile != null -> generator.writeObject(value.inputFile) - value.inputAudio != null -> generator.writeObject(value.inputAudio) value._json != null -> generator.writeObject(value._json) else -> throw IllegalStateException("Invalid ResponseInputContent") } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseInputItem.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseInputItem.kt index 030624ae..2f67115f 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseInputItem.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseInputItem.kt @@ -1232,23 +1232,6 @@ private constructor( fun addContent(inputFile: ResponseInputFile) = addContent(ResponseInputContent.ofInputFile(inputFile)) - /** - * Alias for calling [addContent] with `ResponseInputContent.ofInputAudio(inputAudio)`. - */ - fun addContent(inputAudio: ResponseInputAudio) = - addContent(ResponseInputContent.ofInputAudio(inputAudio)) - - /** - * Alias for calling [addContent] with the following: - * ```java - * ResponseInputAudio.builder() - * .inputAudio(inputAudio) - * .build() - * ``` - */ - fun addInputAudioContent(inputAudio: ResponseInputAudio.InputAudio) = - addContent(ResponseInputAudio.builder().inputAudio(inputAudio).build()) - /** The role of the message input. One of `user`, `system`, or `developer`. */ fun role(role: Role) = role(JsonField.of(role)) diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseInputMessageItem.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseInputMessageItem.kt index 21153b56..154beca6 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseInputMessageItem.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseInputMessageItem.kt @@ -238,21 +238,6 @@ private constructor( fun addContent(inputFile: ResponseInputFile) = addContent(ResponseInputContent.ofInputFile(inputFile)) - /** Alias for calling [addContent] with `ResponseInputContent.ofInputAudio(inputAudio)`. */ - fun addContent(inputAudio: ResponseInputAudio) = - addContent(ResponseInputContent.ofInputAudio(inputAudio)) - - /** - * Alias for calling [addContent] with the following: - * ```java - * ResponseInputAudio.builder() - * .inputAudio(inputAudio) - * .build() - * ``` - */ - fun addInputAudioContent(inputAudio: ResponseInputAudio.InputAudio) = - addContent(ResponseInputAudio.builder().inputAudio(inputAudio).build()) - /** The role of the message input. One of `user`, `system`, or `developer`. */ fun role(role: Role) = role(JsonField.of(role)) diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/Tool.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/Tool.kt index 41c2e659..1900619f 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/Tool.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/Tool.kt @@ -85,8 +85,13 @@ private constructor( /** A tool that generates images using a model like `gpt-image-1`. */ fun imageGeneration(): Optional = Optional.ofNullable(imageGeneration) + /** A tool that allows the model to execute shell commands in a local environment. */ fun localShell(): Optional = Optional.ofNullable(localShell) + /** + * A custom tool that processes input using a specified format. Learn more about + * [custom tools](https://platform.openai.com/docs/guides/function-calling#custom-tools) + */ fun custom(): Optional = Optional.ofNullable(custom) /** @@ -151,8 +156,13 @@ private constructor( /** A tool that generates images using a model like `gpt-image-1`. */ fun asImageGeneration(): ImageGeneration = imageGeneration.getOrThrow("imageGeneration") + /** A tool that allows the model to execute shell commands in a local environment. */ fun asLocalShell(): JsonValue = localShell.getOrThrow("localShell") + /** + * A custom tool that processes input using a specified format. Learn more about + * [custom tools](https://platform.openai.com/docs/guides/function-calling#custom-tools) + */ fun asCustom(): CustomTool = custom.getOrThrow("custom") /** @@ -378,9 +388,14 @@ private constructor( fun ofImageGeneration(imageGeneration: ImageGeneration) = Tool(imageGeneration = imageGeneration) + /** A tool that allows the model to execute shell commands in a local environment. */ @JvmStatic fun ofLocalShell() = Tool(localShell = JsonValue.from(mapOf("type" to "local_shell"))) + /** + * A custom tool that processes input using a specified format. Learn more about + * [custom tools](https://platform.openai.com/docs/guides/function-calling#custom-tools) + */ @JvmStatic fun ofCustom(custom: CustomTool) = Tool(custom = custom) /** @@ -432,8 +447,13 @@ private constructor( /** A tool that generates images using a model like `gpt-image-1`. */ fun visitImageGeneration(imageGeneration: ImageGeneration): T + /** A tool that allows the model to execute shell commands in a local environment. */ fun visitLocalShell(localShell: JsonValue): T + /** + * A custom tool that processes input using a specified format. Learn more about + * [custom tools](https://platform.openai.com/docs/guides/function-calling#custom-tools) + */ fun visitCustom(custom: CustomTool): T /** diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseContentTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseContentTest.kt index ef265ed9..4770c2ce 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseContentTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseContentTest.kt @@ -23,7 +23,6 @@ internal class ResponseContentTest { assertThat(responseContent.inputText()).contains(inputText) assertThat(responseContent.inputImage()).isEmpty assertThat(responseContent.inputFile()).isEmpty - assertThat(responseContent.inputAudio()).isEmpty assertThat(responseContent.outputText()).isEmpty assertThat(responseContent.outputRefusal()).isEmpty assertThat(responseContent.reasoningText()).isEmpty @@ -58,7 +57,6 @@ internal class ResponseContentTest { assertThat(responseContent.inputText()).isEmpty assertThat(responseContent.inputImage()).contains(inputImage) assertThat(responseContent.inputFile()).isEmpty - assertThat(responseContent.inputAudio()).isEmpty assertThat(responseContent.outputText()).isEmpty assertThat(responseContent.outputRefusal()).isEmpty assertThat(responseContent.reasoningText()).isEmpty @@ -100,7 +98,6 @@ internal class ResponseContentTest { assertThat(responseContent.inputText()).isEmpty assertThat(responseContent.inputImage()).isEmpty assertThat(responseContent.inputFile()).contains(inputFile) - assertThat(responseContent.inputAudio()).isEmpty assertThat(responseContent.outputText()).isEmpty assertThat(responseContent.outputRefusal()).isEmpty assertThat(responseContent.reasoningText()).isEmpty @@ -128,53 +125,6 @@ internal class ResponseContentTest { assertThat(roundtrippedResponseContent).isEqualTo(responseContent) } - @Test - fun ofInputAudio() { - val inputAudio = - ResponseInputAudio.builder() - .inputAudio( - ResponseInputAudio.InputAudio.builder() - .data("data") - .format(ResponseInputAudio.InputAudio.Format.MP3) - .build() - ) - .build() - - val responseContent = ResponseContent.ofInputAudio(inputAudio) - - assertThat(responseContent.inputText()).isEmpty - assertThat(responseContent.inputImage()).isEmpty - assertThat(responseContent.inputFile()).isEmpty - assertThat(responseContent.inputAudio()).contains(inputAudio) - assertThat(responseContent.outputText()).isEmpty - assertThat(responseContent.outputRefusal()).isEmpty - assertThat(responseContent.reasoningText()).isEmpty - } - - @Test - fun ofInputAudioRoundtrip() { - val jsonMapper = jsonMapper() - val responseContent = - ResponseContent.ofInputAudio( - ResponseInputAudio.builder() - .inputAudio( - ResponseInputAudio.InputAudio.builder() - .data("data") - .format(ResponseInputAudio.InputAudio.Format.MP3) - .build() - ) - .build() - ) - - val roundtrippedResponseContent = - jsonMapper.readValue( - jsonMapper.writeValueAsString(responseContent), - jacksonTypeRef(), - ) - - assertThat(roundtrippedResponseContent).isEqualTo(responseContent) - } - @Test fun ofOutputText() { val outputText = @@ -208,7 +158,6 @@ internal class ResponseContentTest { assertThat(responseContent.inputText()).isEmpty assertThat(responseContent.inputImage()).isEmpty assertThat(responseContent.inputFile()).isEmpty - assertThat(responseContent.inputAudio()).isEmpty assertThat(responseContent.outputText()).contains(outputText) assertThat(responseContent.outputRefusal()).isEmpty assertThat(responseContent.reasoningText()).isEmpty @@ -263,7 +212,6 @@ internal class ResponseContentTest { assertThat(responseContent.inputText()).isEmpty assertThat(responseContent.inputImage()).isEmpty assertThat(responseContent.inputFile()).isEmpty - assertThat(responseContent.inputAudio()).isEmpty assertThat(responseContent.outputText()).isEmpty assertThat(responseContent.outputRefusal()).contains(outputRefusal) assertThat(responseContent.reasoningText()).isEmpty @@ -295,7 +243,6 @@ internal class ResponseContentTest { assertThat(responseContent.inputText()).isEmpty assertThat(responseContent.inputImage()).isEmpty assertThat(responseContent.inputFile()).isEmpty - assertThat(responseContent.inputAudio()).isEmpty assertThat(responseContent.outputText()).isEmpty assertThat(responseContent.outputRefusal()).isEmpty assertThat(responseContent.reasoningText()).contains(reasoningText) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseInputContentTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseInputContentTest.kt index f2370583..a262e03e 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseInputContentTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseInputContentTest.kt @@ -23,7 +23,6 @@ internal class ResponseInputContentTest { assertThat(responseInputContent.inputText()).contains(inputText) assertThat(responseInputContent.inputImage()).isEmpty assertThat(responseInputContent.inputFile()).isEmpty - assertThat(responseInputContent.inputAudio()).isEmpty } @Test @@ -55,7 +54,6 @@ internal class ResponseInputContentTest { assertThat(responseInputContent.inputText()).isEmpty assertThat(responseInputContent.inputImage()).contains(inputImage) assertThat(responseInputContent.inputFile()).isEmpty - assertThat(responseInputContent.inputAudio()).isEmpty } @Test @@ -94,7 +92,6 @@ internal class ResponseInputContentTest { assertThat(responseInputContent.inputText()).isEmpty assertThat(responseInputContent.inputImage()).isEmpty assertThat(responseInputContent.inputFile()).contains(inputFile) - assertThat(responseInputContent.inputAudio()).isEmpty } @Test @@ -119,50 +116,6 @@ internal class ResponseInputContentTest { assertThat(roundtrippedResponseInputContent).isEqualTo(responseInputContent) } - @Test - fun ofInputAudio() { - val inputAudio = - ResponseInputAudio.builder() - .inputAudio( - ResponseInputAudio.InputAudio.builder() - .data("data") - .format(ResponseInputAudio.InputAudio.Format.MP3) - .build() - ) - .build() - - val responseInputContent = ResponseInputContent.ofInputAudio(inputAudio) - - assertThat(responseInputContent.inputText()).isEmpty - assertThat(responseInputContent.inputImage()).isEmpty - assertThat(responseInputContent.inputFile()).isEmpty - assertThat(responseInputContent.inputAudio()).contains(inputAudio) - } - - @Test - fun ofInputAudioRoundtrip() { - val jsonMapper = jsonMapper() - val responseInputContent = - ResponseInputContent.ofInputAudio( - ResponseInputAudio.builder() - .inputAudio( - ResponseInputAudio.InputAudio.builder() - .data("data") - .format(ResponseInputAudio.InputAudio.Format.MP3) - .build() - ) - .build() - ) - - val roundtrippedResponseInputContent = - jsonMapper.readValue( - jsonMapper.writeValueAsString(responseInputContent), - jacksonTypeRef(), - ) - - assertThat(roundtrippedResponseInputContent).isEqualTo(responseInputContent) - } - enum class IncompatibleJsonShapeTestCase(val value: JsonValue) { BOOLEAN(JsonValue.from(false)), STRING(JsonValue.from("invalid")), From bd9bcfdd560cfc8df2a9336d162a0ee1f6604b84 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 3 Nov 2025 23:06:56 +0000 Subject: [PATCH 3/5] feat(api): Realtime API token_limits, Hybrid searching ranking options --- .stats.yml | 6 +- .../openai/models/CustomToolInputFormat.kt | 9 + .../openai/models/images/ImageEditParams.kt | 21 +- .../realtime/RealtimeSessionCreateRequest.kt | 27 +- .../models/realtime/RealtimeTruncation.kt | 13 +- .../RealtimeTruncationRetentionRatio.kt | 232 +++++- .../RealtimeSessionCreateResponse.kt | 27 +- .../openai/models/responses/FileSearchTool.kt | 284 ++++++- .../models/responses/ResponseOutputText.kt | 102 +-- .../com/openai/models/responses/Tool.kt | 213 ++++- .../filebatches/FileBatchCreateParams.kt | 728 +++++++++++++++--- .../kotlin/com/openai/models/videos/Video.kt | 43 +- .../vectorstores/FileBatchServiceAsync.kt | 50 +- .../blocking/vectorstores/FileBatchService.kt | 47 +- .../RealtimeTruncationRetentionRatioTest.kt | 22 +- .../models/realtime/RealtimeTruncationTest.kt | 19 +- .../models/responses/FileSearchToolTest.kt | 18 + .../responses/ResponseCompletedEventTest.kt | 6 +- .../ResponseContentPartAddedEventTest.kt | 6 +- .../ResponseContentPartDoneEventTest.kt | 6 +- .../models/responses/ResponseContentTest.kt | 4 +- .../responses/ResponseCreatedEventTest.kt | 6 +- .../responses/ResponseFailedEventTest.kt | 6 +- .../responses/ResponseInProgressEventTest.kt | 6 +- .../responses/ResponseIncompleteEventTest.kt | 6 +- .../models/responses/ResponseInputItemTest.kt | 4 +- .../models/responses/ResponseItemTest.kt | 4 +- .../ResponseOutputItemAddedEventTest.kt | 6 +- .../ResponseOutputItemDoneEventTest.kt | 6 +- .../responses/ResponseOutputItemTest.kt | 4 +- .../responses/ResponseOutputMessageTest.kt | 6 +- .../responses/ResponseOutputTextTest.kt | 9 +- .../responses/ResponseQueuedEventTest.kt | 6 +- .../responses/ResponseStreamEventTest.kt | 40 +- .../openai/models/responses/ResponseTest.kt | 6 +- .../com/openai/models/responses/ToolTest.kt | 12 + .../filebatches/FileBatchCreateParamsTest.kt | 49 +- .../videos/VideoListPageResponseTest.kt | 3 + .../com/openai/models/videos/VideoTest.kt | 3 + .../vectorstores/FileBatchServiceAsyncTest.kt | 13 +- .../vectorstores/FileBatchServiceTest.kt | 13 +- 41 files changed, 1772 insertions(+), 319 deletions(-) diff --git a/.stats.yml b/.stats.yml index b8fa5809..689bfb5c 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 135 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-f68f718cd45ac3f9336603601bccc38a718af44d0b26601031de3d0a71b7ce2f.yml -openapi_spec_hash: 1560717860bba4105936647dde8f618d -config_hash: 50ee3382a63c021a9f821a935950e926 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-3c5d1593d7c6f2b38a7d78d7906041465ee9d6e9022f0651e1da194654488108.yml +openapi_spec_hash: 0a4d8ad2469823ce24a3fd94f23f1c2b +config_hash: 032995825500a503a76da119f5354905 diff --git a/openai-java-core/src/main/kotlin/com/openai/models/CustomToolInputFormat.kt b/openai-java-core/src/main/kotlin/com/openai/models/CustomToolInputFormat.kt index 398b7fbe..1f0d125d 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/CustomToolInputFormat.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/CustomToolInputFormat.kt @@ -38,16 +38,20 @@ private constructor( private val _json: JsonValue? = null, ) { + /** Unconstrained free-form text. */ fun text(): Optional = Optional.ofNullable(text) + /** A grammar defined by the user. */ fun grammar(): Optional = Optional.ofNullable(grammar) fun isText(): Boolean = text != null fun isGrammar(): Boolean = grammar != null + /** Unconstrained free-form text. */ fun asText(): JsonValue = text.getOrThrow("text") + /** A grammar defined by the user. */ fun asGrammar(): Grammar = grammar.getOrThrow("grammar") fun _json(): Optional = Optional.ofNullable(_json) @@ -130,9 +134,11 @@ private constructor( companion object { + /** Unconstrained free-form text. */ @JvmStatic fun ofText() = CustomToolInputFormat(text = JsonValue.from(mapOf("type" to "text"))) + /** A grammar defined by the user. */ @JvmStatic fun ofGrammar(grammar: Grammar) = CustomToolInputFormat(grammar = grammar) } @@ -142,8 +148,10 @@ private constructor( */ interface Visitor { + /** Unconstrained free-form text. */ fun visitText(text: JsonValue): T + /** A grammar defined by the user. */ fun visitGrammar(grammar: Grammar): T /** @@ -202,6 +210,7 @@ private constructor( } } + /** A grammar defined by the user. */ class Grammar @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( diff --git a/openai-java-core/src/main/kotlin/com/openai/models/images/ImageEditParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/images/ImageEditParams.kt index 47ba62b7..e0612f18 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/images/ImageEditParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/images/ImageEditParams.kt @@ -80,7 +80,9 @@ private constructor( fun background(): Optional = body.background() /** - * Control how much effort the model will exert to match the style and features, especially facial features, of input images. This parameter is only supported for `gpt-image-1`. Unsupported for `gpt-image-1-mini`. Supports `high` and `low`. Defaults to `low`. + * Control how much effort the model will exert to match the style and features, especially + * facial features, of input images. This parameter is only supported for `gpt-image-1`. + * Unsupported for `gpt-image-1-mini`. Supports `high` and `low`. Defaults to `low`. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -429,7 +431,9 @@ private constructor( } /** - * Control how much effort the model will exert to match the style and features, especially facial features, of input images. This parameter is only supported for `gpt-image-1`. Unsupported for `gpt-image-1-mini`. Supports `high` and `low`. Defaults to `low`. + * Control how much effort the model will exert to match the style and features, especially + * facial features, of input images. This parameter is only supported for `gpt-image-1`. + * Unsupported for `gpt-image-1-mini`. Supports `high` and `low`. Defaults to `low`. */ fun inputFidelity(inputFidelity: InputFidelity?) = apply { body.inputFidelity(inputFidelity) @@ -903,7 +907,9 @@ private constructor( fun background(): Optional = background.value.getOptional("background") /** - * Control how much effort the model will exert to match the style and features, especially facial features, of input images. This parameter is only supported for `gpt-image-1`. Unsupported for `gpt-image-1-mini`. Supports `high` and `low`. Defaults to `low`. + * Control how much effort the model will exert to match the style and features, especially + * facial features, of input images. This parameter is only supported for `gpt-image-1`. + * Unsupported for `gpt-image-1-mini`. Supports `high` and `low`. Defaults to `low`. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -1297,7 +1303,10 @@ private constructor( } /** - * Control how much effort the model will exert to match the style and features, especially facial features, of input images. This parameter is only supported for `gpt-image-1`. Unsupported for `gpt-image-1-mini`. Supports `high` and `low`. Defaults to `low`. + * Control how much effort the model will exert to match the style and features, + * especially facial features, of input images. This parameter is only supported for + * `gpt-image-1`. Unsupported for `gpt-image-1-mini`. Supports `high` and `low`. + * Defaults to `low`. */ fun inputFidelity(inputFidelity: InputFidelity?) = inputFidelity(MultipartField.of(inputFidelity)) @@ -1981,7 +1990,9 @@ private constructor( } /** - * Control how much effort the model will exert to match the style and features, especially facial features, of input images. This parameter is only supported for `gpt-image-1`. Unsupported for `gpt-image-1-mini`. Supports `high` and `low`. Defaults to `low`. + * Control how much effort the model will exert to match the style and features, especially + * facial features, of input images. This parameter is only supported for `gpt-image-1`. + * Unsupported for `gpt-image-1-mini`. Supports `high` and `low`. Defaults to `low`. */ class InputFidelity @JsonCreator private constructor(private val value: JsonField) : Enum { diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeSessionCreateRequest.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeSessionCreateRequest.kt index 8e6b9d05..8ce46c57 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeSessionCreateRequest.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeSessionCreateRequest.kt @@ -221,8 +221,17 @@ private constructor( fun tracing(): Optional = tracing.getOptional("tracing") /** - * Controls how the realtime conversation is truncated prior to model inference. The default is - * `auto`. + * When the number of tokens in a conversation exceeds the model's input token limit, the + * conversation be truncated, meaning messages (starting from the oldest) will not be included + * in the model's context. A 32k context model with 4,096 max output tokens can only include + * 28,224 tokens in the context before truncation occurs. Clients can configure truncation + * behavior to truncate with a lower max token limit, which is an effective way to control token + * usage and cost. Truncation will reduce the number of cached tokens on the next turn (busting + * the cache), since messages are dropped from the beginning of the context. However, clients + * can also configure truncation to retain messages up to a fraction of the maximum context + * size, which will reduce the need for future truncations and thus improve the cache rate. + * Truncation can be disabled entirely, which means the server will never truncate but would + * instead return an error if the conversation exceeds the model's input token limit. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -666,8 +675,18 @@ private constructor( tracing(RealtimeTracingConfig.ofTracingConfiguration(tracingConfiguration)) /** - * Controls how the realtime conversation is truncated prior to model inference. The default - * is `auto`. + * When the number of tokens in a conversation exceeds the model's input token limit, the + * conversation be truncated, meaning messages (starting from the oldest) will not be + * included in the model's context. A 32k context model with 4,096 max output tokens can + * only include 28,224 tokens in the context before truncation occurs. Clients can configure + * truncation behavior to truncate with a lower max token limit, which is an effective way + * to control token usage and cost. Truncation will reduce the number of cached tokens on + * the next turn (busting the cache), since messages are dropped from the beginning of the + * context. However, clients can also configure truncation to retain messages up to a + * fraction of the maximum context size, which will reduce the need for future truncations + * and thus improve the cache rate. Truncation can be disabled entirely, which means the + * server will never truncate but would instead return an error if the conversation exceeds + * the model's input token limit. */ fun truncation(truncation: RealtimeTruncation) = truncation(JsonField.of(truncation)) diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeTruncation.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeTruncation.kt index 56055652..42acf274 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeTruncation.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeTruncation.kt @@ -22,8 +22,17 @@ import java.util.Objects import java.util.Optional /** - * Controls how the realtime conversation is truncated prior to model inference. The default is - * `auto`. + * When the number of tokens in a conversation exceeds the model's input token limit, the + * conversation be truncated, meaning messages (starting from the oldest) will not be included in + * the model's context. A 32k context model with 4,096 max output tokens can only include 28,224 + * tokens in the context before truncation occurs. Clients can configure truncation behavior to + * truncate with a lower max token limit, which is an effective way to control token usage and cost. + * Truncation will reduce the number of cached tokens on the next turn (busting the cache), since + * messages are dropped from the beginning of the context. However, clients can also configure + * truncation to retain messages up to a fraction of the maximum context size, which will reduce the + * need for future truncations and thus improve the cache rate. Truncation can be disabled entirely, + * which means the server will never truncate but would instead return an error if the conversation + * exceeds the model's input token limit. */ @JsonDeserialize(using = RealtimeTruncation.Deserializer::class) @JsonSerialize(using = RealtimeTruncation.Serializer::class) diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeTruncationRetentionRatio.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeTruncationRetentionRatio.kt index abcd2862..a1fb9cf8 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeTruncationRetentionRatio.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/RealtimeTruncationRetentionRatio.kt @@ -14,6 +14,8 @@ 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 /** * Retain a fraction of the conversation tokens when the conversation exceeds the input token limit. @@ -25,6 +27,7 @@ class RealtimeTruncationRetentionRatio private constructor( private val retentionRatio: JsonField, private val type: JsonValue, + private val tokenLimits: JsonField, private val additionalProperties: MutableMap, ) { @@ -34,11 +37,16 @@ private constructor( @ExcludeMissing retentionRatio: JsonField = JsonMissing.of(), @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), - ) : this(retentionRatio, type, mutableMapOf()) + @JsonProperty("token_limits") + @ExcludeMissing + tokenLimits: JsonField = JsonMissing.of(), + ) : this(retentionRatio, type, tokenLimits, mutableMapOf()) /** - * Fraction of post-instruction conversation tokens to retain (0.0 - 1.0) when the conversation - * exceeds the input token limit. + * Fraction of post-instruction conversation tokens to retain (`0.0` - `1.0`) when the + * conversation exceeds the input token limit. Setting this to `0.8` means that messages will be + * dropped until 80% of the maximum allowed tokens are used. This helps reduce the frequency of + * truncations and improve cache rates. * * @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). @@ -58,6 +66,15 @@ private constructor( */ @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + /** + * Optional custom token limits for this truncation strategy. If not provided, the model's + * default token limits will be used. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun tokenLimits(): Optional = tokenLimits.getOptional("token_limits") + /** * Returns the raw JSON value of [retentionRatio]. * @@ -67,6 +84,15 @@ private constructor( @ExcludeMissing fun _retentionRatio(): JsonField = retentionRatio + /** + * Returns the raw JSON value of [tokenLimits]. + * + * Unlike [tokenLimits], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("token_limits") + @ExcludeMissing + fun _tokenLimits(): JsonField = tokenLimits + @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { additionalProperties.put(key, value) @@ -98,6 +124,7 @@ private constructor( private var retentionRatio: JsonField? = null private var type: JsonValue = JsonValue.from("retention_ratio") + private var tokenLimits: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic @@ -105,13 +132,16 @@ private constructor( apply { retentionRatio = realtimeTruncationRetentionRatio.retentionRatio type = realtimeTruncationRetentionRatio.type + tokenLimits = realtimeTruncationRetentionRatio.tokenLimits additionalProperties = realtimeTruncationRetentionRatio.additionalProperties.toMutableMap() } /** - * Fraction of post-instruction conversation tokens to retain (0.0 - 1.0) when the - * conversation exceeds the input token limit. + * Fraction of post-instruction conversation tokens to retain (`0.0` - `1.0`) when the + * conversation exceeds the input token limit. Setting this to `0.8` means that messages + * will be dropped until 80% of the maximum allowed tokens are used. This helps reduce the + * frequency of truncations and improve cache rates. */ fun retentionRatio(retentionRatio: Double) = retentionRatio(JsonField.of(retentionRatio)) @@ -140,6 +170,23 @@ private constructor( */ fun type(type: JsonValue) = apply { this.type = type } + /** + * Optional custom token limits for this truncation strategy. If not provided, the model's + * default token limits will be used. + */ + fun tokenLimits(tokenLimits: TokenLimits) = tokenLimits(JsonField.of(tokenLimits)) + + /** + * Sets [Builder.tokenLimits] to an arbitrary JSON value. + * + * You should usually call [Builder.tokenLimits] with a well-typed [TokenLimits] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun tokenLimits(tokenLimits: JsonField) = apply { + this.tokenLimits = tokenLimits + } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() putAllAdditionalProperties(additionalProperties) @@ -175,6 +222,7 @@ private constructor( RealtimeTruncationRetentionRatio( checkRequired("retentionRatio", retentionRatio), type, + tokenLimits, additionalProperties.toMutableMap(), ) } @@ -192,6 +240,7 @@ private constructor( throw OpenAIInvalidDataException("'type' is invalid, received $it") } } + tokenLimits().ifPresent { it.validate() } validated = true } @@ -211,7 +260,171 @@ private constructor( @JvmSynthetic internal fun validity(): Int = (if (retentionRatio.asKnown().isPresent) 1 else 0) + - type.let { if (it == JsonValue.from("retention_ratio")) 1 else 0 } + type.let { if (it == JsonValue.from("retention_ratio")) 1 else 0 } + + (tokenLimits.asKnown().getOrNull()?.validity() ?: 0) + + /** + * Optional custom token limits for this truncation strategy. If not provided, the model's + * default token limits will be used. + */ + class TokenLimits + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val postInstructions: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("post_instructions") + @ExcludeMissing + postInstructions: JsonField = JsonMissing.of() + ) : this(postInstructions, mutableMapOf()) + + /** + * Maximum tokens allowed in the conversation after instructions (which including tool + * definitions). For example, setting this to 5,000 would mean that truncation would occur + * when the conversation exceeds 5,000 tokens after instructions. This cannot be higher than + * the model's context window size minus the maximum output tokens. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun postInstructions(): Optional = postInstructions.getOptional("post_instructions") + + /** + * Returns the raw JSON value of [postInstructions]. + * + * Unlike [postInstructions], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("post_instructions") + @ExcludeMissing + fun _postInstructions(): JsonField = postInstructions + + @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 [TokenLimits]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [TokenLimits]. */ + class Builder internal constructor() { + + private var postInstructions: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(tokenLimits: TokenLimits) = apply { + postInstructions = tokenLimits.postInstructions + additionalProperties = tokenLimits.additionalProperties.toMutableMap() + } + + /** + * Maximum tokens allowed in the conversation after instructions (which including tool + * definitions). For example, setting this to 5,000 would mean that truncation would + * occur when the conversation exceeds 5,000 tokens after instructions. This cannot be + * higher than the model's context window size minus the maximum output tokens. + */ + fun postInstructions(postInstructions: Long) = + postInstructions(JsonField.of(postInstructions)) + + /** + * Sets [Builder.postInstructions] to an arbitrary JSON value. + * + * You should usually call [Builder.postInstructions] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun postInstructions(postInstructions: JsonField) = apply { + this.postInstructions = postInstructions + } + + 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 [TokenLimits]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): TokenLimits = + TokenLimits(postInstructions, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): TokenLimits = apply { + if (validated) { + return@apply + } + + postInstructions() + 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 (postInstructions.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is TokenLimits && + postInstructions == other.postInstructions && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(postInstructions, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "TokenLimits{postInstructions=$postInstructions, additionalProperties=$additionalProperties}" + } override fun equals(other: Any?): Boolean { if (this === other) { @@ -221,13 +434,16 @@ private constructor( return other is RealtimeTruncationRetentionRatio && retentionRatio == other.retentionRatio && type == other.type && + tokenLimits == other.tokenLimits && additionalProperties == other.additionalProperties } - private val hashCode: Int by lazy { Objects.hash(retentionRatio, type, additionalProperties) } + private val hashCode: Int by lazy { + Objects.hash(retentionRatio, type, tokenLimits, additionalProperties) + } override fun hashCode(): Int = hashCode override fun toString() = - "RealtimeTruncationRetentionRatio{retentionRatio=$retentionRatio, type=$type, additionalProperties=$additionalProperties}" + "RealtimeTruncationRetentionRatio{retentionRatio=$retentionRatio, type=$type, tokenLimits=$tokenLimits, additionalProperties=$additionalProperties}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/realtime/clientsecrets/RealtimeSessionCreateResponse.kt b/openai-java-core/src/main/kotlin/com/openai/models/realtime/clientsecrets/RealtimeSessionCreateResponse.kt index 8bb1b0b0..01e4d2c4 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/realtime/clientsecrets/RealtimeSessionCreateResponse.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/realtime/clientsecrets/RealtimeSessionCreateResponse.kt @@ -237,8 +237,17 @@ private constructor( fun tracing(): Optional = tracing.getOptional("tracing") /** - * Controls how the realtime conversation is truncated prior to model inference. The default is - * `auto`. + * When the number of tokens in a conversation exceeds the model's input token limit, the + * conversation be truncated, meaning messages (starting from the oldest) will not be included + * in the model's context. A 32k context model with 4,096 max output tokens can only include + * 28,224 tokens in the context before truncation occurs. Clients can configure truncation + * behavior to truncate with a lower max token limit, which is an effective way to control token + * usage and cost. Truncation will reduce the number of cached tokens on the next turn (busting + * the cache), since messages are dropped from the beginning of the context. However, clients + * can also configure truncation to retain messages up to a fraction of the maximum context + * size, which will reduce the need for future truncations and thus improve the cache rate. + * Truncation can be disabled entirely, which means the server will never truncate but would + * instead return an error if the conversation exceeds the model's input token limit. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -679,8 +688,18 @@ private constructor( tracing(Tracing.ofConfiguration(configuration)) /** - * Controls how the realtime conversation is truncated prior to model inference. The default - * is `auto`. + * When the number of tokens in a conversation exceeds the model's input token limit, the + * conversation be truncated, meaning messages (starting from the oldest) will not be + * included in the model's context. A 32k context model with 4,096 max output tokens can + * only include 28,224 tokens in the context before truncation occurs. Clients can configure + * truncation behavior to truncate with a lower max token limit, which is an effective way + * to control token usage and cost. Truncation will reduce the number of cached tokens on + * the next turn (busting the cache), since messages are dropped from the beginning of the + * context. However, clients can also configure truncation to retain messages up to a + * fraction of the maximum context size, which will reduce the need for future truncations + * and thus improve the cache rate. Truncation can be disabled entirely, which means the + * server will never truncate but would instead return an error if the conversation exceeds + * the model's input token limit. */ fun truncation(truncation: RealtimeTruncation) = truncation(JsonField.of(truncation)) diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/FileSearchTool.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/FileSearchTool.kt index 7b8aa390..20254d9c 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/FileSearchTool.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/FileSearchTool.kt @@ -570,6 +570,7 @@ private constructor( class RankingOptions @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( + private val hybridSearch: JsonField, private val ranker: JsonField, private val scoreThreshold: JsonField, private val additionalProperties: MutableMap, @@ -577,11 +578,23 @@ private constructor( @JsonCreator private constructor( + @JsonProperty("hybrid_search") + @ExcludeMissing + hybridSearch: JsonField = JsonMissing.of(), @JsonProperty("ranker") @ExcludeMissing ranker: JsonField = JsonMissing.of(), @JsonProperty("score_threshold") @ExcludeMissing scoreThreshold: JsonField = JsonMissing.of(), - ) : this(ranker, scoreThreshold, mutableMapOf()) + ) : this(hybridSearch, ranker, scoreThreshold, mutableMapOf()) + + /** + * Weights that control how reciprocal rank fusion balances semantic embedding matches + * versus sparse keyword matches when hybrid search is enabled. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun hybridSearch(): Optional = hybridSearch.getOptional("hybrid_search") /** * The ranker to use for the file search. @@ -600,6 +613,16 @@ private constructor( */ fun scoreThreshold(): Optional = scoreThreshold.getOptional("score_threshold") + /** + * Returns the raw JSON value of [hybridSearch]. + * + * Unlike [hybridSearch], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("hybrid_search") + @ExcludeMissing + fun _hybridSearch(): JsonField = hybridSearch + /** * Returns the raw JSON value of [ranker]. * @@ -638,17 +661,36 @@ private constructor( /** A builder for [RankingOptions]. */ class Builder internal constructor() { + private var hybridSearch: JsonField = JsonMissing.of() private var ranker: JsonField = JsonMissing.of() private var scoreThreshold: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(rankingOptions: RankingOptions) = apply { + hybridSearch = rankingOptions.hybridSearch ranker = rankingOptions.ranker scoreThreshold = rankingOptions.scoreThreshold additionalProperties = rankingOptions.additionalProperties.toMutableMap() } + /** + * Weights that control how reciprocal rank fusion balances semantic embedding matches + * versus sparse keyword matches when hybrid search is enabled. + */ + fun hybridSearch(hybridSearch: HybridSearch) = hybridSearch(JsonField.of(hybridSearch)) + + /** + * Sets [Builder.hybridSearch] to an arbitrary JSON value. + * + * You should usually call [Builder.hybridSearch] with a well-typed [HybridSearch] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun hybridSearch(hybridSearch: JsonField) = apply { + this.hybridSearch = hybridSearch + } + /** The ranker to use for the file search. */ fun ranker(ranker: Ranker) = ranker(JsonField.of(ranker)) @@ -705,7 +747,12 @@ private constructor( * Further updates to this [Builder] will not mutate the returned instance. */ fun build(): RankingOptions = - RankingOptions(ranker, scoreThreshold, additionalProperties.toMutableMap()) + RankingOptions( + hybridSearch, + ranker, + scoreThreshold, + additionalProperties.toMutableMap(), + ) } private var validated: Boolean = false @@ -715,6 +762,7 @@ private constructor( return@apply } + hybridSearch().ifPresent { it.validate() } ranker().ifPresent { it.validate() } scoreThreshold() validated = true @@ -736,9 +784,234 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (ranker.asKnown().getOrNull()?.validity() ?: 0) + + (hybridSearch.asKnown().getOrNull()?.validity() ?: 0) + + (ranker.asKnown().getOrNull()?.validity() ?: 0) + (if (scoreThreshold.asKnown().isPresent) 1 else 0) + /** + * Weights that control how reciprocal rank fusion balances semantic embedding matches + * versus sparse keyword matches when hybrid search is enabled. + */ + class HybridSearch + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val embeddingWeight: JsonField, + private val textWeight: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("embedding_weight") + @ExcludeMissing + embeddingWeight: JsonField = JsonMissing.of(), + @JsonProperty("text_weight") + @ExcludeMissing + textWeight: JsonField = JsonMissing.of(), + ) : this(embeddingWeight, textWeight, mutableMapOf()) + + /** + * The weight of the embedding in the reciprocal ranking fusion. + * + * @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 embeddingWeight(): Double = embeddingWeight.getRequired("embedding_weight") + + /** + * The weight of the text in the reciprocal ranking fusion. + * + * @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 textWeight(): Double = textWeight.getRequired("text_weight") + + /** + * Returns the raw JSON value of [embeddingWeight]. + * + * Unlike [embeddingWeight], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("embedding_weight") + @ExcludeMissing + fun _embeddingWeight(): JsonField = embeddingWeight + + /** + * Returns the raw JSON value of [textWeight]. + * + * Unlike [textWeight], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("text_weight") + @ExcludeMissing + fun _textWeight(): JsonField = textWeight + + @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 [HybridSearch]. + * + * The following fields are required: + * ```java + * .embeddingWeight() + * .textWeight() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [HybridSearch]. */ + class Builder internal constructor() { + + private var embeddingWeight: JsonField? = null + private var textWeight: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(hybridSearch: HybridSearch) = apply { + embeddingWeight = hybridSearch.embeddingWeight + textWeight = hybridSearch.textWeight + additionalProperties = hybridSearch.additionalProperties.toMutableMap() + } + + /** The weight of the embedding in the reciprocal ranking fusion. */ + fun embeddingWeight(embeddingWeight: Double) = + embeddingWeight(JsonField.of(embeddingWeight)) + + /** + * Sets [Builder.embeddingWeight] to an arbitrary JSON value. + * + * You should usually call [Builder.embeddingWeight] with a well-typed [Double] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun embeddingWeight(embeddingWeight: JsonField) = apply { + this.embeddingWeight = embeddingWeight + } + + /** The weight of the text in the reciprocal ranking fusion. */ + fun textWeight(textWeight: Double) = textWeight(JsonField.of(textWeight)) + + /** + * Sets [Builder.textWeight] to an arbitrary JSON value. + * + * You should usually call [Builder.textWeight] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun textWeight(textWeight: JsonField) = apply { + this.textWeight = textWeight + } + + 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 [HybridSearch]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .embeddingWeight() + * .textWeight() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): HybridSearch = + HybridSearch( + checkRequired("embeddingWeight", embeddingWeight), + checkRequired("textWeight", textWeight), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): HybridSearch = apply { + if (validated) { + return@apply + } + + embeddingWeight() + textWeight() + 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 (embeddingWeight.asKnown().isPresent) 1 else 0) + + (if (textWeight.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is HybridSearch && + embeddingWeight == other.embeddingWeight && + textWeight == other.textWeight && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(embeddingWeight, textWeight, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "HybridSearch{embeddingWeight=$embeddingWeight, textWeight=$textWeight, additionalProperties=$additionalProperties}" + } + /** The ranker to use for the file search. */ class Ranker @JsonCreator private constructor(private val value: JsonField) : Enum { @@ -875,19 +1148,20 @@ private constructor( } return other is RankingOptions && + hybridSearch == other.hybridSearch && ranker == other.ranker && scoreThreshold == other.scoreThreshold && additionalProperties == other.additionalProperties } private val hashCode: Int by lazy { - Objects.hash(ranker, scoreThreshold, additionalProperties) + Objects.hash(hybridSearch, ranker, scoreThreshold, additionalProperties) } override fun hashCode(): Int = hashCode override fun toString() = - "RankingOptions{ranker=$ranker, scoreThreshold=$scoreThreshold, additionalProperties=$additionalProperties}" + "RankingOptions{hybridSearch=$hybridSearch, ranker=$ranker, scoreThreshold=$scoreThreshold, additionalProperties=$additionalProperties}" } override fun equals(other: Any?): Boolean { diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseOutputText.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseOutputText.kt index d252e82b..c117a3f4 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseOutputText.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseOutputText.kt @@ -34,9 +34,9 @@ class ResponseOutputText @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val annotations: JsonField>, + private val logprobs: JsonField>, private val text: JsonField, private val type: JsonValue, - private val logprobs: JsonField>, private val additionalProperties: MutableMap, ) { @@ -45,12 +45,12 @@ private constructor( @JsonProperty("annotations") @ExcludeMissing annotations: JsonField> = JsonMissing.of(), - @JsonProperty("text") @ExcludeMissing text: JsonField = JsonMissing.of(), - @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), @JsonProperty("logprobs") @ExcludeMissing logprobs: JsonField> = JsonMissing.of(), - ) : this(annotations, text, type, logprobs, mutableMapOf()) + @JsonProperty("text") @ExcludeMissing text: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + ) : this(annotations, logprobs, text, type, mutableMapOf()) /** * The annotations of the text output. @@ -60,6 +60,12 @@ private constructor( */ fun annotations(): List = annotations.getRequired("annotations") + /** + * @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 logprobs(): List = logprobs.getRequired("logprobs") + /** * The text output from the model. * @@ -81,12 +87,6 @@ private constructor( */ @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type - /** - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun logprobs(): Optional> = logprobs.getOptional("logprobs") - /** * Returns the raw JSON value of [annotations]. * @@ -97,18 +97,18 @@ private constructor( fun _annotations(): JsonField> = annotations /** - * Returns the raw JSON value of [text]. + * Returns the raw JSON value of [logprobs]. * - * Unlike [text], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [logprobs], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("text") @ExcludeMissing fun _text(): JsonField = text + @JsonProperty("logprobs") @ExcludeMissing fun _logprobs(): JsonField> = logprobs /** - * Returns the raw JSON value of [logprobs]. + * Returns the raw JSON value of [text]. * - * Unlike [logprobs], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [text], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("logprobs") @ExcludeMissing fun _logprobs(): JsonField> = logprobs + @JsonProperty("text") @ExcludeMissing fun _text(): JsonField = text @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { @@ -130,6 +130,7 @@ private constructor( * The following fields are required: * ```java * .annotations() + * .logprobs() * .text() * ``` */ @@ -140,17 +141,17 @@ private constructor( class Builder internal constructor() { private var annotations: JsonField>? = null + private var logprobs: JsonField>? = null private var text: JsonField? = null private var type: JsonValue = JsonValue.from("output_text") - private var logprobs: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(responseOutputText: ResponseOutputText) = apply { annotations = responseOutputText.annotations.map { it.toMutableList() } + logprobs = responseOutputText.logprobs.map { it.toMutableList() } text = responseOutputText.text type = responseOutputText.type - logprobs = responseOutputText.logprobs.map { it.toMutableList() } additionalProperties = responseOutputText.additionalProperties.toMutableMap() } @@ -199,31 +200,6 @@ private constructor( fun addAnnotation(filePath: Annotation.FilePath) = addAnnotation(Annotation.ofFilePath(filePath)) - /** 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 logprobs(logprobs: List) = logprobs(JsonField.of(logprobs)) /** @@ -249,6 +225,31 @@ private constructor( } } + /** 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) @@ -276,6 +277,7 @@ private constructor( * The following fields are required: * ```java * .annotations() + * .logprobs() * .text() * ``` * @@ -284,9 +286,9 @@ private constructor( fun build(): ResponseOutputText = ResponseOutputText( checkRequired("annotations", annotations).map { it.toImmutable() }, + checkRequired("logprobs", logprobs).map { it.toImmutable() }, checkRequired("text", text), type, - (logprobs ?: JsonMissing.of()).map { it.toImmutable() }, additionalProperties.toMutableMap(), ) } @@ -299,13 +301,13 @@ private constructor( } annotations().forEach { it.validate() } + logprobs().forEach { it.validate() } text() _type().let { if (it != JsonValue.from("output_text")) { throw OpenAIInvalidDataException("'type' is invalid, received $it") } } - logprobs().ifPresent { it.forEach { it.validate() } } validated = true } @@ -325,9 +327,9 @@ private constructor( @JvmSynthetic internal fun validity(): Int = (annotations.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (logprobs.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + (if (text.asKnown().isPresent) 1 else 0) + - type.let { if (it == JsonValue.from("output_text")) 1 else 0 } + - (logprobs.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + type.let { if (it == JsonValue.from("output_text")) 1 else 0 } /** A citation to a file. */ @JsonDeserialize(using = Annotation.Deserializer::class) @@ -2392,18 +2394,18 @@ private constructor( return other is ResponseOutputText && annotations == other.annotations && + logprobs == other.logprobs && text == other.text && type == other.type && - logprobs == other.logprobs && additionalProperties == other.additionalProperties } private val hashCode: Int by lazy { - Objects.hash(annotations, text, type, logprobs, additionalProperties) + Objects.hash(annotations, logprobs, text, type, additionalProperties) } override fun hashCode(): Int = hashCode override fun toString() = - "ResponseOutputText{annotations=$annotations, text=$text, type=$type, logprobs=$logprobs, additionalProperties=$additionalProperties}" + "ResponseOutputText{annotations=$annotations, logprobs=$logprobs, text=$text, type=$type, additionalProperties=$additionalProperties}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/Tool.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/Tool.kt index 1900619f..c5ca0f90 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/Tool.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/Tool.kt @@ -3304,6 +3304,7 @@ private constructor( private constructor( private val type: JsonValue, private val fileIds: JsonField>, + private val memoryLimit: JsonField, private val additionalProperties: MutableMap, ) { @@ -3313,7 +3314,10 @@ private constructor( @JsonProperty("file_ids") @ExcludeMissing fileIds: JsonField> = JsonMissing.of(), - ) : this(type, fileIds, mutableMapOf()) + @JsonProperty("memory_limit") + @ExcludeMissing + memoryLimit: JsonField = JsonMissing.of(), + ) : this(type, fileIds, memoryLimit, mutableMapOf()) /** * Always `auto`. @@ -3336,6 +3340,12 @@ private constructor( */ fun fileIds(): Optional> = fileIds.getOptional("file_ids") + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun memoryLimit(): Optional = memoryLimit.getOptional("memory_limit") + /** * Returns the raw JSON value of [fileIds]. * @@ -3346,6 +3356,16 @@ private constructor( @ExcludeMissing fun _fileIds(): JsonField> = fileIds + /** + * Returns the raw JSON value of [memoryLimit]. + * + * Unlike [memoryLimit], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("memory_limit") + @ExcludeMissing + fun _memoryLimit(): JsonField = memoryLimit + @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { additionalProperties.put(key, value) @@ -3372,12 +3392,14 @@ private constructor( private var type: JsonValue = JsonValue.from("auto") private var fileIds: JsonField>? = null + private var memoryLimit: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(codeInterpreterToolAuto: CodeInterpreterToolAuto) = apply { type = codeInterpreterToolAuto.type fileIds = codeInterpreterToolAuto.fileIds.map { it.toMutableList() } + memoryLimit = codeInterpreterToolAuto.memoryLimit additionalProperties = codeInterpreterToolAuto.additionalProperties.toMutableMap() } @@ -3422,6 +3444,24 @@ private constructor( } } + fun memoryLimit(memoryLimit: MemoryLimit?) = + memoryLimit(JsonField.ofNullable(memoryLimit)) + + /** Alias for calling [Builder.memoryLimit] with `memoryLimit.orElse(null)`. */ + fun memoryLimit(memoryLimit: Optional) = + memoryLimit(memoryLimit.getOrNull()) + + /** + * Sets [Builder.memoryLimit] to an arbitrary JSON value. + * + * You should usually call [Builder.memoryLimit] with a well-typed [MemoryLimit] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun memoryLimit(memoryLimit: JsonField) = apply { + this.memoryLimit = memoryLimit + } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() putAllAdditionalProperties(additionalProperties) @@ -3453,6 +3493,7 @@ private constructor( CodeInterpreterToolAuto( type, (fileIds ?: JsonMissing.of()).map { it.toImmutable() }, + memoryLimit, additionalProperties.toMutableMap(), ) } @@ -3470,6 +3511,7 @@ private constructor( } } fileIds() + memoryLimit().ifPresent { it.validate() } validated = true } @@ -3490,7 +3532,156 @@ private constructor( @JvmSynthetic internal fun validity(): Int = type.let { if (it == JsonValue.from("auto")) 1 else 0 } + - (fileIds.asKnown().getOrNull()?.size ?: 0) + (fileIds.asKnown().getOrNull()?.size ?: 0) + + (memoryLimit.asKnown().getOrNull()?.validity() ?: 0) + + class MemoryLimit + @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 _1G = of("1g") + + @JvmField val _4G = of("4g") + + @JvmField val _16G = of("16g") + + @JvmField val _64G = of("64g") + + @JvmStatic fun of(value: String) = MemoryLimit(JsonField.of(value)) + } + + /** An enum containing [MemoryLimit]'s known values. */ + enum class Known { + _1G, + _4G, + _16G, + _64G, + } + + /** + * An enum containing [MemoryLimit]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [MemoryLimit] 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 { + _1G, + _4G, + _16G, + _64G, + /** + * An enum member indicating that [MemoryLimit] 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) { + _1G -> Value._1G + _4G -> Value._4G + _16G -> Value._16G + _64G -> Value._64G + 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) { + _1G -> Known._1G + _4G -> Known._4G + _16G -> Known._16G + _64G -> Known._64G + else -> throw OpenAIInvalidDataException("Unknown MemoryLimit: $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(): MemoryLimit = 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 other is MemoryLimit && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } override fun equals(other: Any?): Boolean { if (this === other) { @@ -3500,17 +3691,18 @@ private constructor( return other is CodeInterpreterToolAuto && type == other.type && fileIds == other.fileIds && + memoryLimit == other.memoryLimit && additionalProperties == other.additionalProperties } private val hashCode: Int by lazy { - Objects.hash(type, fileIds, additionalProperties) + Objects.hash(type, fileIds, memoryLimit, additionalProperties) } override fun hashCode(): Int = hashCode override fun toString() = - "CodeInterpreterToolAuto{type=$type, fileIds=$fileIds, additionalProperties=$additionalProperties}" + "CodeInterpreterToolAuto{type=$type, fileIds=$fileIds, memoryLimit=$memoryLimit, additionalProperties=$additionalProperties}" } } @@ -3616,7 +3808,9 @@ private constructor( fun background(): Optional = background.getOptional("background") /** - * Control how much effort the model will exert to match the style and features, especially facial features, of input images. This parameter is only supported for `gpt-image-1`. Unsupported for `gpt-image-1-mini`. Supports `high` and `low`. Defaults to `low`. + * Control how much effort the model will exert to match the style and features, especially + * facial features, of input images. This parameter is only supported for `gpt-image-1`. + * Unsupported for `gpt-image-1-mini`. Supports `high` and `low`. Defaults to `low`. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -3864,7 +4058,10 @@ private constructor( } /** - * Control how much effort the model will exert to match the style and features, especially facial features, of input images. This parameter is only supported for `gpt-image-1`. Unsupported for `gpt-image-1-mini`. Supports `high` and `low`. Defaults to `low`. + * Control how much effort the model will exert to match the style and features, + * especially facial features, of input images. This parameter is only supported for + * `gpt-image-1`. Unsupported for `gpt-image-1-mini`. Supports `high` and `low`. + * Defaults to `low`. */ fun inputFidelity(inputFidelity: InputFidelity?) = inputFidelity(JsonField.ofNullable(inputFidelity)) @@ -4242,7 +4439,9 @@ private constructor( } /** - * Control how much effort the model will exert to match the style and features, especially facial features, of input images. This parameter is only supported for `gpt-image-1`. Unsupported for `gpt-image-1-mini`. Supports `high` and `low`. Defaults to `low`. + * Control how much effort the model will exert to match the style and features, especially + * facial features, of input images. This parameter is only supported for `gpt-image-1`. + * Unsupported for `gpt-image-1-mini`. Supports `high` and `low`. Defaults to `low`. */ class InputFidelity @JsonCreator private constructor(private val value: JsonField) : Enum { 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 45ace9f7..50d84fa0 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 @@ -37,15 +37,6 @@ private constructor( fun vectorStoreId(): Optional = Optional.ofNullable(vectorStoreId) - /** - * A list of [File](https://platform.openai.com/docs/api-reference/files) IDs that the vector - * store should use. Useful for tools like `file_search` that can access files. - * - * @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 fileIds(): List = body.fileIds() - /** * Set of 16 key-value pairs that can be attached to an object. This can be useful for storing * additional information about the object in a structured format, and querying for objects via @@ -67,11 +58,26 @@ private constructor( fun chunkingStrategy(): Optional = body.chunkingStrategy() /** - * Returns the raw JSON value of [fileIds]. + * A list of [File](https://platform.openai.com/docs/api-reference/files) IDs that the vector + * store should use. Useful for tools like `file_search` that can access files. If `attributes` + * or `chunking_strategy` are provided, they will be applied to all files in the batch. Mutually + * exclusive with `files`. * - * Unlike [fileIds], this method doesn't throw if the JSON field has an unexpected type. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun _fileIds(): JsonField> = body._fileIds() + fun fileIds(): Optional> = body.fileIds() + + /** + * A list of objects that each include a `file_id` plus optional `attributes` or + * `chunking_strategy`. Use this when you need to override metadata for specific files. The + * global `attributes` or `chunking_strategy` will be ignored and must be specified for each + * file. Mutually exclusive with `file_ids`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun files(): Optional> = body.files() /** * Returns the raw JSON value of [attributes]. @@ -88,6 +94,20 @@ private constructor( */ fun _chunkingStrategy(): JsonField = body._chunkingStrategy() + /** + * Returns the raw JSON value of [fileIds]. + * + * Unlike [fileIds], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _fileIds(): JsonField> = body._fileIds() + + /** + * Returns the raw JSON value of [files]. + * + * Unlike [files], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _files(): JsonField> = body._files() + fun _additionalBodyProperties(): Map = body._additionalProperties() /** Additional headers to send with the request. */ @@ -100,14 +120,9 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [FileBatchCreateParams]. - * - * The following fields are required: - * ```java - * .fileIds() - * ``` - */ + @JvmStatic fun none(): FileBatchCreateParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [FileBatchCreateParams]. */ @JvmStatic fun builder() = Builder() } @@ -138,34 +153,13 @@ private constructor( * * 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: - * - [fileIds] * - [attributes] * - [chunkingStrategy] + * - [fileIds] + * - [files] */ fun body(body: Body) = apply { this.body = body.toBuilder() } - /** - * A list of [File](https://platform.openai.com/docs/api-reference/files) IDs that the - * vector store should use. Useful for tools like `file_search` that can access files. - */ - fun fileIds(fileIds: List) = apply { body.fileIds(fileIds) } - - /** - * Sets [Builder.fileIds] to an arbitrary JSON value. - * - * You should usually call [Builder.fileIds] with a well-typed `List` value instead. - * This method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun fileIds(fileIds: JsonField>) = apply { body.fileIds(fileIds) } - - /** - * Adds a single [String] to [fileIds]. - * - * @throws IllegalStateException if the field was previously set to a non-list. - */ - fun addFileId(fileId: String) = apply { body.addFileId(fileId) } - /** * Set of 16 key-value pairs that can be attached to an object. This can be useful for * storing additional information about the object in a structured format, and querying for @@ -230,6 +224,54 @@ private constructor( body.staticChunkingStrategy(static_) } + /** + * A list of [File](https://platform.openai.com/docs/api-reference/files) IDs that the + * vector store should use. Useful for tools like `file_search` that can access files. If + * `attributes` or `chunking_strategy` are provided, they will be applied to all files in + * the batch. Mutually exclusive with `files`. + */ + fun fileIds(fileIds: List) = apply { body.fileIds(fileIds) } + + /** + * Sets [Builder.fileIds] to an arbitrary JSON value. + * + * You should usually call [Builder.fileIds] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun fileIds(fileIds: JsonField>) = apply { body.fileIds(fileIds) } + + /** + * Adds a single [String] to [fileIds]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addFileId(fileId: String) = apply { body.addFileId(fileId) } + + /** + * A list of objects that each include a `file_id` plus optional `attributes` or + * `chunking_strategy`. Use this when you need to override metadata for specific files. The + * global `attributes` or `chunking_strategy` will be ignored and must be specified for each + * file. Mutually exclusive with `file_ids`. + */ + fun files(files: List) = apply { body.files(files) } + + /** + * Sets [Builder.files] to an arbitrary JSON value. + * + * You should usually call [Builder.files] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun files(files: JsonField>) = apply { body.files(files) } + + /** + * Adds a single [File] to [files]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addFile(file: File) = apply { body.addFile(file) } + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { body.additionalProperties(additionalBodyProperties) } @@ -351,13 +393,6 @@ private constructor( * Returns an immutable instance of [FileBatchCreateParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .fileIds() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): FileBatchCreateParams = FileBatchCreateParams( @@ -383,33 +418,26 @@ private constructor( class Body @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( - private val fileIds: JsonField>, private val attributes: JsonField, private val chunkingStrategy: JsonField, + private val fileIds: JsonField>, + private val files: JsonField>, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( - @JsonProperty("file_ids") - @ExcludeMissing - fileIds: JsonField> = JsonMissing.of(), @JsonProperty("attributes") @ExcludeMissing attributes: JsonField = JsonMissing.of(), @JsonProperty("chunking_strategy") @ExcludeMissing chunkingStrategy: JsonField = JsonMissing.of(), - ) : this(fileIds, attributes, chunkingStrategy, mutableMapOf()) - - /** - * A list of [File](https://platform.openai.com/docs/api-reference/files) IDs that the - * vector store should use. Useful for tools like `file_search` that can access files. - * - * @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 fileIds(): List = fileIds.getRequired("file_ids") + @JsonProperty("file_ids") + @ExcludeMissing + fileIds: JsonField> = JsonMissing.of(), + @JsonProperty("files") @ExcludeMissing files: JsonField> = JsonMissing.of(), + ) : this(attributes, chunkingStrategy, fileIds, files, mutableMapOf()) /** * Set of 16 key-value pairs that can be attached to an object. This can be useful for @@ -434,11 +462,26 @@ private constructor( chunkingStrategy.getOptional("chunking_strategy") /** - * Returns the raw JSON value of [fileIds]. + * A list of [File](https://platform.openai.com/docs/api-reference/files) IDs that the + * vector store should use. Useful for tools like `file_search` that can access files. If + * `attributes` or `chunking_strategy` are provided, they will be applied to all files in + * the batch. Mutually exclusive with `files`. * - * Unlike [fileIds], this method doesn't throw if the JSON field has an unexpected type. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - @JsonProperty("file_ids") @ExcludeMissing fun _fileIds(): JsonField> = fileIds + fun fileIds(): Optional> = fileIds.getOptional("file_ids") + + /** + * A list of objects that each include a `file_id` plus optional `attributes` or + * `chunking_strategy`. Use this when you need to override metadata for specific files. The + * global `attributes` or `chunking_strategy` will be ignored and must be specified for each + * file. Mutually exclusive with `file_ids`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun files(): Optional> = files.getOptional("files") /** * Returns the raw JSON value of [attributes]. @@ -459,6 +502,20 @@ private constructor( @ExcludeMissing fun _chunkingStrategy(): JsonField = chunkingStrategy + /** + * Returns the raw JSON value of [fileIds]. + * + * Unlike [fileIds], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("file_ids") @ExcludeMissing fun _fileIds(): JsonField> = fileIds + + /** + * Returns the raw JSON value of [files]. + * + * Unlike [files], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("files") @ExcludeMissing fun _files(): JsonField> = files + @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { additionalProperties.put(key, value) @@ -473,62 +530,28 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [Body]. - * - * The following fields are required: - * ```java - * .fileIds() - * ``` - */ + /** Returns a mutable builder for constructing an instance of [Body]. */ @JvmStatic fun builder() = Builder() } /** A builder for [Body]. */ class Builder internal constructor() { - private var fileIds: JsonField>? = null private var attributes: JsonField = JsonMissing.of() private var chunkingStrategy: JsonField = JsonMissing.of() + private var fileIds: JsonField>? = null + private var files: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(body: Body) = apply { - fileIds = body.fileIds.map { it.toMutableList() } attributes = body.attributes chunkingStrategy = body.chunkingStrategy + fileIds = body.fileIds.map { it.toMutableList() } + files = body.files.map { it.toMutableList() } additionalProperties = body.additionalProperties.toMutableMap() } - /** - * A list of [File](https://platform.openai.com/docs/api-reference/files) IDs that the - * vector store should use. Useful for tools like `file_search` that can access files. - */ - fun fileIds(fileIds: List) = fileIds(JsonField.of(fileIds)) - - /** - * Sets [Builder.fileIds] to an arbitrary JSON value. - * - * You should usually call [Builder.fileIds] with a well-typed `List` value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun fileIds(fileIds: JsonField>) = apply { - this.fileIds = fileIds.map { it.toMutableList() } - } - - /** - * Adds a single [String] to [fileIds]. - * - * @throws IllegalStateException if the field was previously set to a non-list. - */ - fun addFileId(fileId: String) = apply { - fileIds = - (fileIds ?: JsonField.of(mutableListOf())).also { - checkKnown("fileIds", it).add(fileId) - } - } - /** * Set of 16 key-value pairs that can be attached to an object. This can be useful for * storing additional information about the object in a structured format, and querying @@ -596,6 +619,68 @@ private constructor( StaticFileChunkingStrategyObjectParam.builder().static_(static_).build() ) + /** + * A list of [File](https://platform.openai.com/docs/api-reference/files) IDs that the + * vector store should use. Useful for tools like `file_search` that can access files. + * If `attributes` or `chunking_strategy` are provided, they will be applied to all + * files in the batch. Mutually exclusive with `files`. + */ + fun fileIds(fileIds: List) = fileIds(JsonField.of(fileIds)) + + /** + * Sets [Builder.fileIds] to an arbitrary JSON value. + * + * You should usually call [Builder.fileIds] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun fileIds(fileIds: JsonField>) = apply { + this.fileIds = fileIds.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [fileIds]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addFileId(fileId: String) = apply { + fileIds = + (fileIds ?: JsonField.of(mutableListOf())).also { + checkKnown("fileIds", it).add(fileId) + } + } + + /** + * A list of objects that each include a `file_id` plus optional `attributes` or + * `chunking_strategy`. Use this when you need to override metadata for specific files. + * The global `attributes` or `chunking_strategy` will be ignored and must be specified + * for each file. Mutually exclusive with `file_ids`. + */ + fun files(files: List) = files(JsonField.of(files)) + + /** + * Sets [Builder.files] to an arbitrary JSON value. + * + * You should usually call [Builder.files] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun files(files: JsonField>) = apply { + this.files = files.map { it.toMutableList() } + } + + /** + * Adds a single [File] to [files]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addFile(file: File) = apply { + files = + (files ?: JsonField.of(mutableListOf())).also { + checkKnown("files", it).add(file) + } + } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() putAllAdditionalProperties(additionalProperties) @@ -619,19 +704,13 @@ private constructor( * Returns an immutable instance of [Body]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .fileIds() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): Body = Body( - checkRequired("fileIds", fileIds).map { it.toImmutable() }, attributes, chunkingStrategy, + (fileIds ?: JsonMissing.of()).map { it.toImmutable() }, + (files ?: JsonMissing.of()).map { it.toImmutable() }, additionalProperties.toMutableMap(), ) } @@ -643,9 +722,10 @@ private constructor( return@apply } - fileIds() attributes().ifPresent { it.validate() } chunkingStrategy().ifPresent { it.validate() } + fileIds() + files().ifPresent { it.forEach { it.validate() } } validated = true } @@ -665,9 +745,10 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (fileIds.asKnown().getOrNull()?.size ?: 0) + - (attributes.asKnown().getOrNull()?.validity() ?: 0) + - (chunkingStrategy.asKnown().getOrNull()?.validity() ?: 0) + (attributes.asKnown().getOrNull()?.validity() ?: 0) + + (chunkingStrategy.asKnown().getOrNull()?.validity() ?: 0) + + (fileIds.asKnown().getOrNull()?.size ?: 0) + + (files.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) override fun equals(other: Any?): Boolean { if (this === other) { @@ -675,20 +756,21 @@ private constructor( } return other is Body && - fileIds == other.fileIds && attributes == other.attributes && chunkingStrategy == other.chunkingStrategy && + fileIds == other.fileIds && + files == other.files && additionalProperties == other.additionalProperties } private val hashCode: Int by lazy { - Objects.hash(fileIds, attributes, chunkingStrategy, additionalProperties) + Objects.hash(attributes, chunkingStrategy, fileIds, files, additionalProperties) } override fun hashCode(): Int = hashCode override fun toString() = - "Body{fileIds=$fileIds, attributes=$attributes, chunkingStrategy=$chunkingStrategy, additionalProperties=$additionalProperties}" + "Body{attributes=$attributes, chunkingStrategy=$chunkingStrategy, fileIds=$fileIds, files=$files, additionalProperties=$additionalProperties}" } /** @@ -796,6 +878,410 @@ private constructor( override fun toString() = "Attributes{additionalProperties=$additionalProperties}" } + class File + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val fileId: JsonField, + private val attributes: JsonField, + private val chunkingStrategy: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("file_id") @ExcludeMissing fileId: JsonField = JsonMissing.of(), + @JsonProperty("attributes") + @ExcludeMissing + attributes: JsonField = JsonMissing.of(), + @JsonProperty("chunking_strategy") + @ExcludeMissing + chunkingStrategy: JsonField = JsonMissing.of(), + ) : this(fileId, attributes, chunkingStrategy, mutableMapOf()) + + /** + * A [File](https://platform.openai.com/docs/api-reference/files) ID that the vector store + * should use. Useful for tools like `file_search` that can access files. + * + * @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 fileId(): String = fileId.getRequired("file_id") + + /** + * Set of 16 key-value pairs that can be attached to an object. This can be useful for + * storing additional information about the object in a structured format, and querying for + * objects via API or the dashboard. Keys are strings with a maximum length of 64 + * characters. Values are strings with a maximum length of 512 characters, booleans, or + * numbers. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun attributes(): Optional = attributes.getOptional("attributes") + + /** + * The chunking strategy used to chunk the file(s). If not set, will use the `auto` + * strategy. Only applicable if `file_ids` is non-empty. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun chunkingStrategy(): Optional = + chunkingStrategy.getOptional("chunking_strategy") + + /** + * Returns the raw JSON value of [fileId]. + * + * Unlike [fileId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("file_id") @ExcludeMissing fun _fileId(): JsonField = fileId + + /** + * Returns the raw JSON value of [attributes]. + * + * Unlike [attributes], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("attributes") + @ExcludeMissing + fun _attributes(): JsonField = attributes + + /** + * Returns the raw JSON value of [chunkingStrategy]. + * + * Unlike [chunkingStrategy], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("chunking_strategy") + @ExcludeMissing + fun _chunkingStrategy(): JsonField = chunkingStrategy + + @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 [File]. + * + * The following fields are required: + * ```java + * .fileId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [File]. */ + class Builder internal constructor() { + + private var fileId: JsonField? = null + private var attributes: JsonField = JsonMissing.of() + private var chunkingStrategy: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(file: File) = apply { + fileId = file.fileId + attributes = file.attributes + chunkingStrategy = file.chunkingStrategy + additionalProperties = file.additionalProperties.toMutableMap() + } + + /** + * A [File](https://platform.openai.com/docs/api-reference/files) ID that the vector + * store should use. Useful for tools like `file_search` that can access files. + */ + fun fileId(fileId: String) = fileId(JsonField.of(fileId)) + + /** + * Sets [Builder.fileId] to an arbitrary JSON value. + * + * You should usually call [Builder.fileId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun fileId(fileId: JsonField) = apply { this.fileId = fileId } + + /** + * Set of 16 key-value pairs that can be attached to an object. This can be useful for + * storing additional information about the object in a structured format, and querying + * for objects via API or the dashboard. Keys are strings with a maximum length of 64 + * characters. Values are strings with a maximum length of 512 characters, booleans, or + * numbers. + */ + fun attributes(attributes: Attributes?) = attributes(JsonField.ofNullable(attributes)) + + /** Alias for calling [Builder.attributes] with `attributes.orElse(null)`. */ + fun attributes(attributes: Optional) = attributes(attributes.getOrNull()) + + /** + * Sets [Builder.attributes] to an arbitrary JSON value. + * + * You should usually call [Builder.attributes] with a well-typed [Attributes] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun attributes(attributes: JsonField) = apply { + this.attributes = attributes + } + + /** + * The chunking strategy used to chunk the file(s). If not set, will use the `auto` + * strategy. Only applicable if `file_ids` is non-empty. + */ + fun chunkingStrategy(chunkingStrategy: FileChunkingStrategyParam) = + chunkingStrategy(JsonField.of(chunkingStrategy)) + + /** + * Sets [Builder.chunkingStrategy] to an arbitrary JSON value. + * + * You should usually call [Builder.chunkingStrategy] with a well-typed + * [FileChunkingStrategyParam] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun chunkingStrategy(chunkingStrategy: JsonField) = apply { + this.chunkingStrategy = chunkingStrategy + } + + /** + * Alias for calling [chunkingStrategy] with `FileChunkingStrategyParam.ofAuto(auto)`. + */ + fun chunkingStrategy(auto: AutoFileChunkingStrategyParam) = + chunkingStrategy(FileChunkingStrategyParam.ofAuto(auto)) + + /** + * Alias for calling [chunkingStrategy] with + * `FileChunkingStrategyParam.ofStatic(static_)`. + */ + fun chunkingStrategy(static_: StaticFileChunkingStrategyObjectParam) = + chunkingStrategy(FileChunkingStrategyParam.ofStatic(static_)) + + /** + * Alias for calling [chunkingStrategy] with the following: + * ```java + * StaticFileChunkingStrategyObjectParam.builder() + * .static_(static_) + * .build() + * ``` + */ + fun staticChunkingStrategy(static_: StaticFileChunkingStrategy) = + chunkingStrategy( + StaticFileChunkingStrategyObjectParam.builder().static_(static_).build() + ) + + 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 [File]. + * + * 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(): File = + File( + checkRequired("fileId", fileId), + attributes, + chunkingStrategy, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): File = apply { + if (validated) { + return@apply + } + + fileId() + attributes().ifPresent { it.validate() } + chunkingStrategy().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 = + (if (fileId.asKnown().isPresent) 1 else 0) + + (attributes.asKnown().getOrNull()?.validity() ?: 0) + + (chunkingStrategy.asKnown().getOrNull()?.validity() ?: 0) + + /** + * Set of 16 key-value pairs that can be attached to an object. This can be useful for + * storing additional information about the object in a structured format, and querying for + * objects via API or the dashboard. Keys are strings with a maximum length of 64 + * characters. Values are strings with a maximum length of 512 characters, booleans, or + * numbers. + */ + class Attributes + @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 [Attributes]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Attributes]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(attributes: Attributes) = apply { + additionalProperties = attributes.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 [Attributes]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Attributes = Attributes(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Attributes = 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 other is Attributes && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Attributes{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is File && + fileId == other.fileId && + attributes == other.attributes && + chunkingStrategy == other.chunkingStrategy && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(fileId, attributes, chunkingStrategy, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "File{fileId=$fileId, attributes=$attributes, chunkingStrategy=$chunkingStrategy, additionalProperties=$additionalProperties}" + } + override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/openai-java-core/src/main/kotlin/com/openai/models/videos/Video.kt b/openai-java-core/src/main/kotlin/com/openai/models/videos/Video.kt index d351b9b2..486552d3 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/videos/Video.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/videos/Video.kt @@ -30,6 +30,7 @@ private constructor( private val model: JsonField, private val object_: JsonValue, private val progress: JsonField, + private val prompt: JsonField, private val remixedFromVideoId: JsonField, private val seconds: JsonField, private val size: JsonField, @@ -51,6 +52,7 @@ private constructor( @JsonProperty("model") @ExcludeMissing model: JsonField = JsonMissing.of(), @JsonProperty("object") @ExcludeMissing object_: JsonValue = JsonMissing.of(), @JsonProperty("progress") @ExcludeMissing progress: JsonField = JsonMissing.of(), + @JsonProperty("prompt") @ExcludeMissing prompt: JsonField = JsonMissing.of(), @JsonProperty("remixed_from_video_id") @ExcludeMissing remixedFromVideoId: JsonField = JsonMissing.of(), @@ -68,6 +70,7 @@ private constructor( model, object_, progress, + prompt, remixedFromVideoId, seconds, size, @@ -144,6 +147,14 @@ private constructor( */ fun progress(): Long = progress.getRequired("progress") + /** + * The prompt that was used to generate the video. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun prompt(): Optional = prompt.getOptional("prompt") + /** * Identifier of the source video if this video is a remix. * @@ -226,6 +237,13 @@ private constructor( */ @JsonProperty("progress") @ExcludeMissing fun _progress(): JsonField = progress + /** + * Returns the raw JSON value of [prompt]. + * + * Unlike [prompt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("prompt") @ExcludeMissing fun _prompt(): JsonField = prompt + /** * Returns the raw JSON value of [remixedFromVideoId]. * @@ -283,6 +301,7 @@ private constructor( * .expiresAt() * .model() * .progress() + * .prompt() * .remixedFromVideoId() * .seconds() * .size() @@ -303,6 +322,7 @@ private constructor( private var model: JsonField? = null private var object_: JsonValue = JsonValue.from("video") private var progress: JsonField? = null + private var prompt: JsonField? = null private var remixedFromVideoId: JsonField? = null private var seconds: JsonField? = null private var size: JsonField? = null @@ -319,6 +339,7 @@ private constructor( model = video.model object_ = video.object_ progress = video.progress + prompt = video.prompt remixedFromVideoId = video.remixedFromVideoId seconds = video.seconds size = video.size @@ -443,6 +464,20 @@ private constructor( */ fun progress(progress: JsonField) = apply { this.progress = progress } + /** The prompt that was used to generate the video. */ + fun prompt(prompt: String?) = prompt(JsonField.ofNullable(prompt)) + + /** Alias for calling [Builder.prompt] with `prompt.orElse(null)`. */ + fun prompt(prompt: Optional) = prompt(prompt.getOrNull()) + + /** + * Sets [Builder.prompt] to an arbitrary JSON value. + * + * You should usually call [Builder.prompt] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun prompt(prompt: JsonField) = apply { this.prompt = prompt } + /** Identifier of the source video if this video is a remix. */ fun remixedFromVideoId(remixedFromVideoId: String?) = remixedFromVideoId(JsonField.ofNullable(remixedFromVideoId)) @@ -531,6 +566,7 @@ private constructor( * .expiresAt() * .model() * .progress() + * .prompt() * .remixedFromVideoId() * .seconds() * .size() @@ -549,6 +585,7 @@ private constructor( checkRequired("model", model), object_, checkRequired("progress", progress), + checkRequired("prompt", prompt), checkRequired("remixedFromVideoId", remixedFromVideoId), checkRequired("seconds", seconds), checkRequired("size", size), @@ -576,6 +613,7 @@ private constructor( } } progress() + prompt() remixedFromVideoId() seconds().validate() size().validate() @@ -606,6 +644,7 @@ private constructor( (model.asKnown().getOrNull()?.validity() ?: 0) + object_.let { if (it == JsonValue.from("video")) 1 else 0 } + (if (progress.asKnown().isPresent) 1 else 0) + + (if (prompt.asKnown().isPresent) 1 else 0) + (if (remixedFromVideoId.asKnown().isPresent) 1 else 0) + (seconds.asKnown().getOrNull()?.validity() ?: 0) + (size.asKnown().getOrNull()?.validity() ?: 0) + @@ -763,6 +802,7 @@ private constructor( model == other.model && object_ == other.object_ && progress == other.progress && + prompt == other.prompt && remixedFromVideoId == other.remixedFromVideoId && seconds == other.seconds && size == other.size && @@ -780,6 +820,7 @@ private constructor( model, object_, progress, + prompt, remixedFromVideoId, seconds, size, @@ -791,5 +832,5 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "Video{id=$id, completedAt=$completedAt, createdAt=$createdAt, error=$error, expiresAt=$expiresAt, model=$model, object_=$object_, progress=$progress, remixedFromVideoId=$remixedFromVideoId, seconds=$seconds, size=$size, status=$status, additionalProperties=$additionalProperties}" + "Video{id=$id, completedAt=$completedAt, createdAt=$createdAt, error=$error, expiresAt=$expiresAt, model=$model, object_=$object_, progress=$progress, prompt=$prompt, remixedFromVideoId=$remixedFromVideoId, seconds=$seconds, size=$size, status=$status, additionalProperties=$additionalProperties}" } 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 6d2f1a0b..0c80d8e7 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 @@ -29,19 +29,29 @@ interface FileBatchServiceAsync { fun withOptions(modifier: Consumer): FileBatchServiceAsync /** Create a vector store file batch. */ + fun create(vectorStoreId: String): CompletableFuture = + create(vectorStoreId, FileBatchCreateParams.none()) + + /** @see create */ fun create( vectorStoreId: String, - params: FileBatchCreateParams, + params: FileBatchCreateParams = FileBatchCreateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture = - create(vectorStoreId, params, RequestOptions.none()) + create(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) /** @see create */ fun create( vectorStoreId: String, + params: FileBatchCreateParams = FileBatchCreateParams.none(), + ): CompletableFuture = + create(vectorStoreId, params, RequestOptions.none()) + + /** @see create */ + fun create( params: FileBatchCreateParams, requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture = - create(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) + ): CompletableFuture /** @see create */ fun create(params: FileBatchCreateParams): CompletableFuture = @@ -49,9 +59,10 @@ interface FileBatchServiceAsync { /** @see create */ fun create( - params: FileBatchCreateParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture + vectorStoreId: String, + requestOptions: RequestOptions, + ): CompletableFuture = + create(vectorStoreId, FileBatchCreateParams.none(), requestOptions) /** Retrieves a vector store file batch. */ fun retrieve( @@ -149,24 +160,24 @@ interface FileBatchServiceAsync { * is otherwise the same as [FileBatchServiceAsync.create]. */ fun create( - vectorStoreId: String, - params: FileBatchCreateParams, + vectorStoreId: String ): CompletableFuture> = - create(vectorStoreId, params, RequestOptions.none()) + create(vectorStoreId, FileBatchCreateParams.none()) /** @see create */ fun create( vectorStoreId: String, - params: FileBatchCreateParams, + params: FileBatchCreateParams = FileBatchCreateParams.none(), requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> = create(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) /** @see create */ fun create( - params: FileBatchCreateParams + vectorStoreId: String, + params: FileBatchCreateParams = FileBatchCreateParams.none(), ): CompletableFuture> = - create(params, RequestOptions.none()) + create(vectorStoreId, params, RequestOptions.none()) /** @see create */ fun create( @@ -174,6 +185,19 @@ interface FileBatchServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** @see create */ + fun create( + params: FileBatchCreateParams + ): CompletableFuture> = + create(params, RequestOptions.none()) + + /** @see create */ + fun create( + vectorStoreId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + create(vectorStoreId, FileBatchCreateParams.none(), requestOptions) + /** * Returns a raw HTTP response for `get * /vector_stores/{vector_store_id}/file_batches/{batch_id}`, but is otherwise the same as 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 716311fa..32b63f4d 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 @@ -29,20 +29,22 @@ interface FileBatchService { fun withOptions(modifier: Consumer): FileBatchService /** Create a vector store file batch. */ - fun create(vectorStoreId: String, params: FileBatchCreateParams): VectorStoreFileBatch = - create(vectorStoreId, params, RequestOptions.none()) + fun create(vectorStoreId: String): VectorStoreFileBatch = + create(vectorStoreId, FileBatchCreateParams.none()) /** @see create */ fun create( vectorStoreId: String, - params: FileBatchCreateParams, + params: FileBatchCreateParams = FileBatchCreateParams.none(), requestOptions: RequestOptions = RequestOptions.none(), ): VectorStoreFileBatch = create(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) /** @see create */ - fun create(params: FileBatchCreateParams): VectorStoreFileBatch = - create(params, RequestOptions.none()) + fun create( + vectorStoreId: String, + params: FileBatchCreateParams = FileBatchCreateParams.none(), + ): VectorStoreFileBatch = create(vectorStoreId, params, RequestOptions.none()) /** @see create */ fun create( @@ -50,6 +52,14 @@ interface FileBatchService { requestOptions: RequestOptions = RequestOptions.none(), ): VectorStoreFileBatch + /** @see create */ + fun create(params: FileBatchCreateParams): VectorStoreFileBatch = + create(params, RequestOptions.none()) + + /** @see create */ + fun create(vectorStoreId: String, requestOptions: RequestOptions): VectorStoreFileBatch = + create(vectorStoreId, FileBatchCreateParams.none(), requestOptions) + /** Retrieves a vector store file batch. */ fun retrieve(batchId: String, params: FileBatchRetrieveParams): VectorStoreFileBatch = retrieve(batchId, params, RequestOptions.none()) @@ -132,20 +142,32 @@ interface FileBatchService { * is otherwise the same as [FileBatchService.create]. */ @MustBeClosed + fun create(vectorStoreId: String): HttpResponseFor = + create(vectorStoreId, FileBatchCreateParams.none()) + + /** @see create */ + @MustBeClosed fun create( vectorStoreId: String, - params: FileBatchCreateParams, + params: FileBatchCreateParams = FileBatchCreateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor = - create(vectorStoreId, params, RequestOptions.none()) + create(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) /** @see create */ @MustBeClosed fun create( vectorStoreId: String, + params: FileBatchCreateParams = FileBatchCreateParams.none(), + ): HttpResponseFor = + create(vectorStoreId, params, RequestOptions.none()) + + /** @see create */ + @MustBeClosed + fun create( params: FileBatchCreateParams, requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor = - create(params.toBuilder().vectorStoreId(vectorStoreId).build(), requestOptions) + ): HttpResponseFor /** @see create */ @MustBeClosed @@ -155,9 +177,10 @@ interface FileBatchService { /** @see create */ @MustBeClosed fun create( - params: FileBatchCreateParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor + vectorStoreId: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + create(vectorStoreId, FileBatchCreateParams.none(), requestOptions) /** * Returns a raw HTTP response for `get diff --git a/openai-java-core/src/test/kotlin/com/openai/models/realtime/RealtimeTruncationRetentionRatioTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/realtime/RealtimeTruncationRetentionRatioTest.kt index b28eaf75..6f835dbd 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/realtime/RealtimeTruncationRetentionRatioTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/realtime/RealtimeTruncationRetentionRatioTest.kt @@ -12,16 +12,34 @@ internal class RealtimeTruncationRetentionRatioTest { @Test fun create() { val realtimeTruncationRetentionRatio = - RealtimeTruncationRetentionRatio.builder().retentionRatio(0.0).build() + RealtimeTruncationRetentionRatio.builder() + .retentionRatio(0.0) + .tokenLimits( + RealtimeTruncationRetentionRatio.TokenLimits.builder() + .postInstructions(0L) + .build() + ) + .build() assertThat(realtimeTruncationRetentionRatio.retentionRatio()).isEqualTo(0.0) + assertThat(realtimeTruncationRetentionRatio.tokenLimits()) + .contains( + RealtimeTruncationRetentionRatio.TokenLimits.builder().postInstructions(0L).build() + ) } @Test fun roundtrip() { val jsonMapper = jsonMapper() val realtimeTruncationRetentionRatio = - RealtimeTruncationRetentionRatio.builder().retentionRatio(0.0).build() + RealtimeTruncationRetentionRatio.builder() + .retentionRatio(0.0) + .tokenLimits( + RealtimeTruncationRetentionRatio.TokenLimits.builder() + .postInstructions(0L) + .build() + ) + .build() val roundtrippedRealtimeTruncationRetentionRatio = jsonMapper.readValue( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/realtime/RealtimeTruncationTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/realtime/RealtimeTruncationTest.kt index 250b1f88..1696a99c 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/realtime/RealtimeTruncationTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/realtime/RealtimeTruncationTest.kt @@ -39,7 +39,15 @@ internal class RealtimeTruncationTest { @Test fun ofRetentionRatio() { - val retentionRatio = RealtimeTruncationRetentionRatio.builder().retentionRatio(0.0).build() + val retentionRatio = + RealtimeTruncationRetentionRatio.builder() + .retentionRatio(0.0) + .tokenLimits( + RealtimeTruncationRetentionRatio.TokenLimits.builder() + .postInstructions(0L) + .build() + ) + .build() val realtimeTruncation = RealtimeTruncation.ofRetentionRatio(retentionRatio) @@ -52,7 +60,14 @@ internal class RealtimeTruncationTest { val jsonMapper = jsonMapper() val realtimeTruncation = RealtimeTruncation.ofRetentionRatio( - RealtimeTruncationRetentionRatio.builder().retentionRatio(0.0).build() + RealtimeTruncationRetentionRatio.builder() + .retentionRatio(0.0) + .tokenLimits( + RealtimeTruncationRetentionRatio.TokenLimits.builder() + .postInstructions(0L) + .build() + ) + .build() ) val roundtrippedRealtimeTruncation = diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/FileSearchToolTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/FileSearchToolTest.kt index 17ec2988..5a5a7a15 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/FileSearchToolTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/FileSearchToolTest.kt @@ -25,6 +25,12 @@ internal class FileSearchToolTest { .maxNumResults(0L) .rankingOptions( FileSearchTool.RankingOptions.builder() + .hybridSearch( + FileSearchTool.RankingOptions.HybridSearch.builder() + .embeddingWeight(0.0) + .textWeight(0.0) + .build() + ) .ranker(FileSearchTool.RankingOptions.Ranker.AUTO) .scoreThreshold(0.0) .build() @@ -46,6 +52,12 @@ internal class FileSearchToolTest { assertThat(fileSearchTool.rankingOptions()) .contains( FileSearchTool.RankingOptions.builder() + .hybridSearch( + FileSearchTool.RankingOptions.HybridSearch.builder() + .embeddingWeight(0.0) + .textWeight(0.0) + .build() + ) .ranker(FileSearchTool.RankingOptions.Ranker.AUTO) .scoreThreshold(0.0) .build() @@ -68,6 +80,12 @@ internal class FileSearchToolTest { .maxNumResults(0L) .rankingOptions( FileSearchTool.RankingOptions.builder() + .hybridSearch( + FileSearchTool.RankingOptions.HybridSearch.builder() + .embeddingWeight(0.0) + .textWeight(0.0) + .build() + ) .ranker(FileSearchTool.RankingOptions.Ranker.AUTO) .scoreThreshold(0.0) .build() diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCompletedEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCompletedEventTest.kt index 09f60ba4..d84ae08b 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCompletedEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCompletedEventTest.kt @@ -52,7 +52,6 @@ internal class ResponseCompletedEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -67,6 +66,7 @@ internal class ResponseCompletedEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -181,7 +181,6 @@ internal class ResponseCompletedEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -196,6 +195,7 @@ internal class ResponseCompletedEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -312,7 +312,6 @@ internal class ResponseCompletedEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -327,6 +326,7 @@ internal class ResponseCompletedEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseContentPartAddedEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseContentPartAddedEventTest.kt index cb7901c4..c096fe96 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseContentPartAddedEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseContentPartAddedEventTest.kt @@ -25,7 +25,6 @@ internal class ResponseContentPartAddedEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -40,6 +39,7 @@ internal class ResponseContentPartAddedEventTest { ) .build() ) + .text("text") .build() ) .sequenceNumber(0L) @@ -59,7 +59,6 @@ internal class ResponseContentPartAddedEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -74,6 +73,7 @@ internal class ResponseContentPartAddedEventTest { ) .build() ) + .text("text") .build() ) ) @@ -97,7 +97,6 @@ internal class ResponseContentPartAddedEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -112,6 +111,7 @@ internal class ResponseContentPartAddedEventTest { ) .build() ) + .text("text") .build() ) .sequenceNumber(0L) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseContentPartDoneEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseContentPartDoneEventTest.kt index d292a559..cc02b1e9 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseContentPartDoneEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseContentPartDoneEventTest.kt @@ -25,7 +25,6 @@ internal class ResponseContentPartDoneEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -40,6 +39,7 @@ internal class ResponseContentPartDoneEventTest { ) .build() ) + .text("text") .build() ) .sequenceNumber(0L) @@ -59,7 +59,6 @@ internal class ResponseContentPartDoneEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -74,6 +73,7 @@ internal class ResponseContentPartDoneEventTest { ) .build() ) + .text("text") .build() ) ) @@ -97,7 +97,6 @@ internal class ResponseContentPartDoneEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -112,6 +111,7 @@ internal class ResponseContentPartDoneEventTest { ) .build() ) + .text("text") .build() ) .sequenceNumber(0L) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseContentTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseContentTest.kt index 4770c2ce..dbf0ccf1 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseContentTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseContentTest.kt @@ -136,7 +136,6 @@ internal class ResponseContentTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -151,6 +150,7 @@ internal class ResponseContentTest { ) .build() ) + .text("text") .build() val responseContent = ResponseContent.ofOutputText(outputText) @@ -176,7 +176,6 @@ internal class ResponseContentTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -191,6 +190,7 @@ internal class ResponseContentTest { ) .build() ) + .text("text") .build() ) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCreatedEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCreatedEventTest.kt index 8c3d8a36..e2c7c09c 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCreatedEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCreatedEventTest.kt @@ -52,7 +52,6 @@ internal class ResponseCreatedEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -67,6 +66,7 @@ internal class ResponseCreatedEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -181,7 +181,6 @@ internal class ResponseCreatedEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -196,6 +195,7 @@ internal class ResponseCreatedEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -312,7 +312,6 @@ internal class ResponseCreatedEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -327,6 +326,7 @@ internal class ResponseCreatedEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseFailedEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseFailedEventTest.kt index 52070146..cf7a71b7 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseFailedEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseFailedEventTest.kt @@ -52,7 +52,6 @@ internal class ResponseFailedEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -67,6 +66,7 @@ internal class ResponseFailedEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -181,7 +181,6 @@ internal class ResponseFailedEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -196,6 +195,7 @@ internal class ResponseFailedEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -312,7 +312,6 @@ internal class ResponseFailedEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -327,6 +326,7 @@ internal class ResponseFailedEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseInProgressEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseInProgressEventTest.kt index bdaac431..0f5015ef 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseInProgressEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseInProgressEventTest.kt @@ -52,7 +52,6 @@ internal class ResponseInProgressEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -67,6 +66,7 @@ internal class ResponseInProgressEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -181,7 +181,6 @@ internal class ResponseInProgressEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -196,6 +195,7 @@ internal class ResponseInProgressEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -312,7 +312,6 @@ internal class ResponseInProgressEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -327,6 +326,7 @@ internal class ResponseInProgressEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseIncompleteEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseIncompleteEventTest.kt index ce16b8b7..e2ae86b9 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseIncompleteEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseIncompleteEventTest.kt @@ -52,7 +52,6 @@ internal class ResponseIncompleteEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -67,6 +66,7 @@ internal class ResponseIncompleteEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -181,7 +181,6 @@ internal class ResponseIncompleteEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -196,6 +195,7 @@ internal class ResponseIncompleteEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -312,7 +312,6 @@ internal class ResponseIncompleteEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -327,6 +326,7 @@ internal class ResponseIncompleteEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) 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 557b79e7..72d7beba 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 @@ -140,7 +140,6 @@ internal class ResponseInputItemTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -155,6 +154,7 @@ internal class ResponseInputItemTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -201,7 +201,6 @@ internal class ResponseInputItemTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -216,6 +215,7 @@ internal class ResponseInputItemTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) 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 aa46ea72..2698d995 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 @@ -82,7 +82,6 @@ internal class ResponseItemTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -97,6 +96,7 @@ internal class ResponseItemTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -138,7 +138,6 @@ internal class ResponseItemTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -153,6 +152,7 @@ internal class ResponseItemTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseOutputItemAddedEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseOutputItemAddedEventTest.kt index fcd2d401..162cb01a 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseOutputItemAddedEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseOutputItemAddedEventTest.kt @@ -25,7 +25,6 @@ internal class ResponseOutputItemAddedEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -40,6 +39,7 @@ internal class ResponseOutputItemAddedEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -63,7 +63,6 @@ internal class ResponseOutputItemAddedEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -78,6 +77,7 @@ internal class ResponseOutputItemAddedEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -105,7 +105,6 @@ internal class ResponseOutputItemAddedEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -120,6 +119,7 @@ internal class ResponseOutputItemAddedEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseOutputItemDoneEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseOutputItemDoneEventTest.kt index 81972846..13606f81 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseOutputItemDoneEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseOutputItemDoneEventTest.kt @@ -25,7 +25,6 @@ internal class ResponseOutputItemDoneEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -40,6 +39,7 @@ internal class ResponseOutputItemDoneEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -63,7 +63,6 @@ internal class ResponseOutputItemDoneEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -78,6 +77,7 @@ internal class ResponseOutputItemDoneEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -105,7 +105,6 @@ internal class ResponseOutputItemDoneEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -120,6 +119,7 @@ internal class ResponseOutputItemDoneEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) 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 d7615365..8fac3b0e 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 @@ -28,7 +28,6 @@ internal class ResponseOutputItemTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -43,6 +42,7 @@ internal class ResponseOutputItemTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -81,7 +81,6 @@ internal class ResponseOutputItemTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -96,6 +95,7 @@ internal class ResponseOutputItemTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseOutputMessageTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseOutputMessageTest.kt index f9482d06..782b891b 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseOutputMessageTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseOutputMessageTest.kt @@ -23,7 +23,6 @@ internal class ResponseOutputMessageTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -38,6 +37,7 @@ internal class ResponseOutputMessageTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -55,7 +55,6 @@ internal class ResponseOutputMessageTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -70,6 +69,7 @@ internal class ResponseOutputMessageTest { ) .build() ) + .text("text") .build() ) ) @@ -92,7 +92,6 @@ internal class ResponseOutputMessageTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -107,6 +106,7 @@ internal class ResponseOutputMessageTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseOutputTextTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseOutputTextTest.kt index a8d2ccca..b57f289c 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseOutputTextTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseOutputTextTest.kt @@ -4,7 +4,6 @@ package com.openai.models.responses import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import com.openai.core.jsonMapper -import kotlin.jvm.optionals.getOrNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test @@ -21,7 +20,6 @@ internal class ResponseOutputTextTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -36,6 +34,7 @@ internal class ResponseOutputTextTest { ) .build() ) + .text("text") .build() assertThat(responseOutputText.annotations()) @@ -48,8 +47,7 @@ internal class ResponseOutputTextTest { .build() ) ) - assertThat(responseOutputText.text()).isEqualTo("text") - assertThat(responseOutputText.logprobs().getOrNull()) + assertThat(responseOutputText.logprobs()) .containsExactly( ResponseOutputText.Logprob.builder() .token("token") @@ -64,6 +62,7 @@ internal class ResponseOutputTextTest { ) .build() ) + assertThat(responseOutputText.text()).isEqualTo("text") } @Test @@ -78,7 +77,6 @@ internal class ResponseOutputTextTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -93,6 +91,7 @@ internal class ResponseOutputTextTest { ) .build() ) + .text("text") .build() val roundtrippedResponseOutputText = diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseQueuedEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseQueuedEventTest.kt index 927392e6..cdd24e37 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseQueuedEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseQueuedEventTest.kt @@ -52,7 +52,6 @@ internal class ResponseQueuedEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -67,6 +66,7 @@ internal class ResponseQueuedEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -181,7 +181,6 @@ internal class ResponseQueuedEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -196,6 +195,7 @@ internal class ResponseQueuedEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -312,7 +312,6 @@ internal class ResponseQueuedEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -327,6 +326,7 @@ internal class ResponseQueuedEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseStreamEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseStreamEventTest.kt index 0a2a864b..2bc07be4 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseStreamEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseStreamEventTest.kt @@ -822,7 +822,6 @@ internal class ResponseStreamEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -837,6 +836,7 @@ internal class ResponseStreamEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -1013,7 +1013,6 @@ internal class ResponseStreamEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -1029,6 +1028,7 @@ internal class ResponseStreamEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -1134,7 +1134,6 @@ internal class ResponseStreamEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -1149,6 +1148,7 @@ internal class ResponseStreamEventTest { ) .build() ) + .text("text") .build() ) .sequenceNumber(0L) @@ -1229,7 +1229,6 @@ internal class ResponseStreamEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -1244,6 +1243,7 @@ internal class ResponseStreamEventTest { ) .build() ) + .text("text") .build() ) .sequenceNumber(0L) @@ -1275,7 +1275,6 @@ internal class ResponseStreamEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -1290,6 +1289,7 @@ internal class ResponseStreamEventTest { ) .build() ) + .text("text") .build() ) .sequenceNumber(0L) @@ -1370,7 +1370,6 @@ internal class ResponseStreamEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -1385,6 +1384,7 @@ internal class ResponseStreamEventTest { ) .build() ) + .text("text") .build() ) .sequenceNumber(0L) @@ -1438,7 +1438,6 @@ internal class ResponseStreamEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -1453,6 +1452,7 @@ internal class ResponseStreamEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -1629,7 +1629,6 @@ internal class ResponseStreamEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -1645,6 +1644,7 @@ internal class ResponseStreamEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -2310,7 +2310,6 @@ internal class ResponseStreamEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -2325,6 +2324,7 @@ internal class ResponseStreamEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -2501,7 +2501,6 @@ internal class ResponseStreamEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -2517,6 +2516,7 @@ internal class ResponseStreamEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -2644,7 +2644,6 @@ internal class ResponseStreamEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -2659,6 +2658,7 @@ internal class ResponseStreamEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -2835,7 +2835,6 @@ internal class ResponseStreamEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -2851,6 +2850,7 @@ internal class ResponseStreamEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -2978,7 +2978,6 @@ internal class ResponseStreamEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -2993,6 +2992,7 @@ internal class ResponseStreamEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -3169,7 +3169,6 @@ internal class ResponseStreamEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -3185,6 +3184,7 @@ internal class ResponseStreamEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -3290,7 +3290,6 @@ internal class ResponseStreamEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -3305,6 +3304,7 @@ internal class ResponseStreamEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -3389,7 +3389,6 @@ internal class ResponseStreamEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -3404,6 +3403,7 @@ internal class ResponseStreamEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -3439,7 +3439,6 @@ internal class ResponseStreamEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -3454,6 +3453,7 @@ internal class ResponseStreamEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -3538,7 +3538,6 @@ internal class ResponseStreamEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -3553,6 +3552,7 @@ internal class ResponseStreamEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -5998,7 +5998,6 @@ internal class ResponseStreamEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -6013,6 +6012,7 @@ internal class ResponseStreamEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -6189,7 +6189,6 @@ internal class ResponseStreamEventTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -6205,6 +6204,7 @@ internal class ResponseStreamEventTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseTest.kt index dba13d8b..ec60999b 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseTest.kt @@ -51,7 +51,6 @@ internal class ResponseTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -66,6 +65,7 @@ internal class ResponseTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -175,7 +175,6 @@ internal class ResponseTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -190,6 +189,7 @@ internal class ResponseTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) @@ -309,7 +309,6 @@ internal class ResponseTest { .index(0L) .build() ) - .text("text") .addLogprob( ResponseOutputText.Logprob.builder() .token("token") @@ -324,6 +323,7 @@ internal class ResponseTest { ) .build() ) + .text("text") .build() ) .status(ResponseOutputMessage.Status.IN_PROGRESS) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ToolTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ToolTest.kt index a059eabb..126d73be 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ToolTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ToolTest.kt @@ -81,6 +81,12 @@ internal class ToolTest { .maxNumResults(0L) .rankingOptions( FileSearchTool.RankingOptions.builder() + .hybridSearch( + FileSearchTool.RankingOptions.HybridSearch.builder() + .embeddingWeight(0.0) + .textWeight(0.0) + .build() + ) .ranker(FileSearchTool.RankingOptions.Ranker.AUTO) .scoreThreshold(0.0) .build() @@ -118,6 +124,12 @@ internal class ToolTest { .maxNumResults(0L) .rankingOptions( FileSearchTool.RankingOptions.builder() + .hybridSearch( + FileSearchTool.RankingOptions.HybridSearch.builder() + .embeddingWeight(0.0) + .textWeight(0.0) + .build() + ) .ranker(FileSearchTool.RankingOptions.Ranker.AUTO) .scoreThreshold(0.0) .build() diff --git a/openai-java-core/src/test/kotlin/com/openai/models/vectorstores/filebatches/FileBatchCreateParamsTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/vectorstores/filebatches/FileBatchCreateParamsTest.kt index 11cf3581..655b71d2 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/vectorstores/filebatches/FileBatchCreateParamsTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/vectorstores/filebatches/FileBatchCreateParamsTest.kt @@ -5,6 +5,7 @@ package com.openai.models.vectorstores.filebatches import com.openai.core.JsonValue import com.openai.models.vectorstores.AutoFileChunkingStrategyParam import com.openai.models.vectorstores.FileChunkingStrategyParam +import kotlin.jvm.optionals.getOrNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test @@ -14,20 +15,30 @@ internal class FileBatchCreateParamsTest { fun create() { FileBatchCreateParams.builder() .vectorStoreId("vs_abc123") - .addFileId("string") .attributes( FileBatchCreateParams.Attributes.builder() .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) .chunkingStrategy(AutoFileChunkingStrategyParam.builder().build()) + .addFileId("string") + .addFile( + FileBatchCreateParams.File.builder() + .fileId("file_id") + .attributes( + FileBatchCreateParams.File.Attributes.builder() + .putAdditionalProperty("foo", JsonValue.from("string")) + .build() + ) + .chunkingStrategy(AutoFileChunkingStrategyParam.builder().build()) + .build() + ) .build() } @Test fun pathParams() { - val params = - FileBatchCreateParams.builder().vectorStoreId("vs_abc123").addFileId("string").build() + val params = FileBatchCreateParams.builder().vectorStoreId("vs_abc123").build() assertThat(params._pathParam(0)).isEqualTo("vs_abc123") // out-of-bound path param @@ -39,18 +50,28 @@ internal class FileBatchCreateParamsTest { val params = FileBatchCreateParams.builder() .vectorStoreId("vs_abc123") - .addFileId("string") .attributes( FileBatchCreateParams.Attributes.builder() .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) .chunkingStrategy(AutoFileChunkingStrategyParam.builder().build()) + .addFileId("string") + .addFile( + FileBatchCreateParams.File.builder() + .fileId("file_id") + .attributes( + FileBatchCreateParams.File.Attributes.builder() + .putAdditionalProperty("foo", JsonValue.from("string")) + .build() + ) + .chunkingStrategy(AutoFileChunkingStrategyParam.builder().build()) + .build() + ) .build() val body = params._body() - assertThat(body.fileIds()).containsExactly("string") assertThat(body.attributes()) .contains( FileBatchCreateParams.Attributes.builder() @@ -61,15 +82,25 @@ internal class FileBatchCreateParamsTest { .contains( FileChunkingStrategyParam.ofAuto(AutoFileChunkingStrategyParam.builder().build()) ) + assertThat(body.fileIds().getOrNull()).containsExactly("string") + assertThat(body.files().getOrNull()) + .containsExactly( + FileBatchCreateParams.File.builder() + .fileId("file_id") + .attributes( + FileBatchCreateParams.File.Attributes.builder() + .putAdditionalProperty("foo", JsonValue.from("string")) + .build() + ) + .chunkingStrategy(AutoFileChunkingStrategyParam.builder().build()) + .build() + ) } @Test fun bodyWithoutOptionalFields() { - val params = - FileBatchCreateParams.builder().vectorStoreId("vs_abc123").addFileId("string").build() + val params = FileBatchCreateParams.builder().vectorStoreId("vs_abc123").build() val body = params._body() - - assertThat(body.fileIds()).containsExactly("string") } } diff --git a/openai-java-core/src/test/kotlin/com/openai/models/videos/VideoListPageResponseTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/videos/VideoListPageResponseTest.kt index 885fb7e7..f83345b0 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/videos/VideoListPageResponseTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/videos/VideoListPageResponseTest.kt @@ -22,6 +22,7 @@ internal class VideoListPageResponseTest { .expiresAt(0L) .model(VideoModel.SORA_2) .progress(0L) + .prompt("prompt") .remixedFromVideoId("remixed_from_video_id") .seconds(VideoSeconds._4) .size(VideoSize._720X1280) @@ -43,6 +44,7 @@ internal class VideoListPageResponseTest { .expiresAt(0L) .model(VideoModel.SORA_2) .progress(0L) + .prompt("prompt") .remixedFromVideoId("remixed_from_video_id") .seconds(VideoSeconds._4) .size(VideoSize._720X1280) @@ -68,6 +70,7 @@ internal class VideoListPageResponseTest { .expiresAt(0L) .model(VideoModel.SORA_2) .progress(0L) + .prompt("prompt") .remixedFromVideoId("remixed_from_video_id") .seconds(VideoSeconds._4) .size(VideoSize._720X1280) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/videos/VideoTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/videos/VideoTest.kt index e4f7fe9a..f071abb4 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/videos/VideoTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/videos/VideoTest.kt @@ -20,6 +20,7 @@ internal class VideoTest { .expiresAt(0L) .model(VideoModel.SORA_2) .progress(0L) + .prompt("prompt") .remixedFromVideoId("remixed_from_video_id") .seconds(VideoSeconds._4) .size(VideoSize._720X1280) @@ -34,6 +35,7 @@ internal class VideoTest { assertThat(video.expiresAt()).contains(0L) assertThat(video.model()).isEqualTo(VideoModel.SORA_2) assertThat(video.progress()).isEqualTo(0L) + assertThat(video.prompt()).contains("prompt") assertThat(video.remixedFromVideoId()).contains("remixed_from_video_id") assertThat(video.seconds()).isEqualTo(VideoSeconds._4) assertThat(video.size()).isEqualTo(VideoSize._720X1280) @@ -52,6 +54,7 @@ internal class VideoTest { .expiresAt(0L) .model(VideoModel.SORA_2) .progress(0L) + .prompt("prompt") .remixedFromVideoId("remixed_from_video_id") .seconds(VideoSeconds._4) .size(VideoSize._720X1280) diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/vectorstores/FileBatchServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/vectorstores/FileBatchServiceAsyncTest.kt index a657588d..9fdd3657 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/async/vectorstores/FileBatchServiceAsyncTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/vectorstores/FileBatchServiceAsyncTest.kt @@ -29,13 +29,24 @@ internal class FileBatchServiceAsyncTest { fileBatchServiceAsync.create( FileBatchCreateParams.builder() .vectorStoreId("vs_abc123") - .addFileId("string") .attributes( FileBatchCreateParams.Attributes.builder() .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) .chunkingStrategy(AutoFileChunkingStrategyParam.builder().build()) + .addFileId("string") + .addFile( + FileBatchCreateParams.File.builder() + .fileId("file_id") + .attributes( + FileBatchCreateParams.File.Attributes.builder() + .putAdditionalProperty("foo", JsonValue.from("string")) + .build() + ) + .chunkingStrategy(AutoFileChunkingStrategyParam.builder().build()) + .build() + ) .build() ) diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/vectorstores/FileBatchServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/vectorstores/FileBatchServiceTest.kt index 9f3e3091..ca3652f3 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/blocking/vectorstores/FileBatchServiceTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/vectorstores/FileBatchServiceTest.kt @@ -29,13 +29,24 @@ internal class FileBatchServiceTest { fileBatchService.create( FileBatchCreateParams.builder() .vectorStoreId("vs_abc123") - .addFileId("string") .attributes( FileBatchCreateParams.Attributes.builder() .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) .chunkingStrategy(AutoFileChunkingStrategyParam.builder().build()) + .addFileId("string") + .addFile( + FileBatchCreateParams.File.builder() + .fileId("file_id") + .attributes( + FileBatchCreateParams.File.Attributes.builder() + .putAdditionalProperty("foo", JsonValue.from("string")) + .build() + ) + .chunkingStrategy(AutoFileChunkingStrategyParam.builder().build()) + .build() + ) .build() ) From dc240a62ee03057161a7709922c7c0d3b4dc1663 Mon Sep 17 00:00:00 2001 From: Alex Chang Date: Mon, 3 Nov 2025 19:58:10 -0500 Subject: [PATCH 4/5] fix tests --- .../kotlin/com/openai/helpers/ResponseAccumulatorTest.kt | 6 +++++- .../responses/StructuredResponseOutputMessageTest.kt | 8 +++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/openai-java-core/src/test/kotlin/com/openai/helpers/ResponseAccumulatorTest.kt b/openai-java-core/src/test/kotlin/com/openai/helpers/ResponseAccumulatorTest.kt index 81d0b833..2b12569d 100644 --- a/openai-java-core/src/test/kotlin/com/openai/helpers/ResponseAccumulatorTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/helpers/ResponseAccumulatorTest.kt @@ -162,5 +162,9 @@ internal class ResponseAccumulatorTest { .build() private fun responseOutputText() = - ResponseOutputText.builder().text("Hello World").annotations(listOf()).build() + ResponseOutputText.builder() + .text("Hello World") + .annotations(listOf()) + .logprobs(listOf()) + .build() } diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/StructuredResponseOutputMessageTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/StructuredResponseOutputMessageTest.kt index 2b093cf5..9e4aa5a5 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/StructuredResponseOutputMessageTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/StructuredResponseOutputMessageTest.kt @@ -39,7 +39,11 @@ internal class StructuredResponseOutputMessageTest { companion object { private val MESSAGE_STATUS = ResponseOutputMessage.Status.COMPLETED private val OUTPUT_TEXT = - ResponseOutputText.builder().annotations(listOf()).text(STRING).build() + ResponseOutputText.builder() + .annotations(listOf()) + .logprobs(listOf()) + .text(STRING) + .build() private val OUTPUT_REFUSAL = ResponseOutputRefusal.builder().refusal(STRING).build() private val CONTENT = ResponseOutputMessage.Content.ofOutputText(OUTPUT_TEXT) @@ -218,6 +222,7 @@ internal class StructuredResponseOutputMessageTest { Optional.of( ResponseOutputText.builder() .annotations(listOf()) + .logprobs(listOf()) .text("{\"s\" : \"hello\"}") .build() ) @@ -240,6 +245,7 @@ internal class StructuredResponseOutputMessageTest { Optional.of( ResponseOutputText.builder() .annotations(listOf()) + .logprobs(listOf()) .text("{\"s\" : \"hello\"}") .build() ) From 3a5af607c90437c6e675d89f511a69b97873df01 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 4 Nov 2025 00:58:42 +0000 Subject: [PATCH 5/5] release: 4.7.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 14 ++++++++++++++ README.md | 14 +++++++------- build.gradle.kts | 2 +- 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index b20ed366..1eec10e9 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "4.6.1" + ".": "4.7.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index f0a6b8f9..5137ae11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## 4.7.0 (2025-11-04) + +Full Changelog: [v4.6.1...v4.7.0](https://github.com/openai/openai-java/compare/v4.6.1...v4.7.0) + +### Features + +* **api:** Realtime API token_limits, Hybrid searching ranking options ([bd9bcfd](https://github.com/openai/openai-java/commit/bd9bcfdd560cfc8df2a9336d162a0ee1f6604b84)) +* **api:** remove InputAudio from ResponseInputContent ([630fecf](https://github.com/openai/openai-java/commit/630fecf8f0e04ce82ac0f0df9b5d60df4edd0655)) + + +### Bug Fixes + +* **api:** docs updates ([3e970ec](https://github.com/openai/openai-java/commit/3e970ec8c9b3895b087f5722a0bfae23ca9e4e2c)) + ## 4.6.1 (2025-10-20) Full Changelog: [v4.6.0...v4.6.1](https://github.com/openai/openai-java/compare/v4.6.0...v4.6.1) diff --git a/README.md b/README.md index 6bcbe64c..518565b6 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/4.6.1) -[![javadoc](https://javadoc.io/badge2/com.openai/openai-java/4.6.1/javadoc.svg)](https://javadoc.io/doc/com.openai/openai-java/4.6.1) +[![Maven Central](https://img.shields.io/maven-central/v/com.openai/openai-java)](https://central.sonatype.com/artifact/com.openai/openai-java/4.7.0) +[![javadoc](https://javadoc.io/badge2/com.openai/openai-java/4.7.0/javadoc.svg)](https://javadoc.io/doc/com.openai/openai-java/4.7.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/4.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/4.7.0). @@ -24,7 +24,7 @@ The REST API documentation can be found on [platform.openai.com](https://platfor ### Gradle ```kotlin -implementation("com.openai:openai-java:4.6.1") +implementation("com.openai:openai-java:4.7.0") ``` ### Maven @@ -33,7 +33,7 @@ implementation("com.openai:openai-java:4.6.1") com.openai openai-java - 4.6.1 + 4.7.0 ``` @@ -1342,7 +1342,7 @@ If you're using Spring Boot, then you can use the SDK's [Spring Boot starter](ht #### Gradle ```kotlin -implementation("com.openai:openai-java-spring-boot-starter:4.6.1") +implementation("com.openai:openai-java-spring-boot-starter:4.7.0") ``` #### Maven @@ -1351,7 +1351,7 @@ implementation("com.openai:openai-java-spring-boot-starter:4.6.1") com.openai openai-java-spring-boot-starter - 4.6.1 + 4.7.0 ``` diff --git a/build.gradle.kts b/build.gradle.kts index 08ef2034..c1752622 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ repositories { allprojects { group = "com.openai" - version = "4.6.1" // x-release-please-version + version = "4.7.0" // x-release-please-version } subprojects {