"vllm/vscode:/vscode.git/clone" did not exist on "92510edc325c855848653c8864f0805eb7fbb022"
Unverified Commit fd5cc288 authored by ishandhanani's avatar ishandhanani Committed by GitHub
Browse files

refactor(3/3): switch dynamo-protocols to upstream async-openai types (#7625)


Co-authored-by: default avatarDmitry Tokarev <dtokarev@nvidia.com>
parent d517fb80
// SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
use crate::error::OpenAIError;
use derive_builder::Builder;
use serde::{Deserialize, Serialize};
use utoipa::ToSchema;
#[derive(ToSchema, Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Default)]
#[serde(rename_all = "lowercase")]
pub enum GrammarSyntax {
Lark,
#[default]
Regex,
}
#[derive(ToSchema, Debug, Serialize, Deserialize, Clone, PartialEq, Default, Builder)]
#[builder(build_fn(error = "OpenAIError"))]
pub struct CustomGrammarFormatParam {
/// The grammar definition.
pub definition: String,
/// The syntax of the grammar definition. One of `lark` or `regex`.
pub syntax: GrammarSyntax,
}
// SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
use serde::{Deserialize, Serialize};
use utoipa::ToSchema;
/// Filters for file search.
#[derive(ToSchema, Debug, Serialize, Deserialize, Clone, PartialEq)]
#[serde(untagged)]
pub enum Filter {
/// A filter used to compare a specified attribute key to a given value using a defined
/// comparison operation.
Comparison(ComparisonFilter),
/// Combine multiple filters using and or or.
Compound(CompoundFilter),
}
/// Single comparison filter.
#[derive(ToSchema, Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct ComparisonFilter {
/// Specifies the comparison operator
#[serde(rename = "type")]
pub op: ComparisonType,
/// The key to compare against the value.
pub key: String,
/// The value to compare against the attribute key; supports string, number, or boolean types.
pub value: serde_json::Value,
}
#[derive(ToSchema, Debug, Serialize, Deserialize, Clone, Copy, PartialEq)]
pub enum ComparisonType {
#[serde(rename = "eq")]
Equals,
#[serde(rename = "ne")]
NotEquals,
#[serde(rename = "gt")]
GreaterThan,
#[serde(rename = "gte")]
GreaterThanOrEqualTo,
#[serde(rename = "lt")]
LessThan,
#[serde(rename = "lte")]
LessThanOrEqualTo,
}
/// Combine multiple filters.
#[derive(ToSchema, Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct CompoundFilter {
/// Type of operation
#[serde(rename = "type")]
pub op: CompoundType,
/// Array of filters to combine. Items can be ComparisonFilter or CompoundFilter.
#[schema(no_recursion)]
pub filters: Vec<Filter>,
}
#[derive(ToSchema, Debug, Serialize, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum CompoundType {
And,
Or,
}
// SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
mod custom_grammar_format_param;
mod filter;
mod response_usage;
pub use custom_grammar_format_param::*;
pub use filter::*;
pub use response_usage::*;
// Re-export types that already exist in the crate
pub use crate::types::CompletionTokensDetails;
pub use crate::types::ImageDetail;
pub use crate::types::PromptTokensDetails;
pub use crate::types::ReasoningEffort;
pub use crate::types::ResponseFormatJsonSchema;
// SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
use serde::{Deserialize, Serialize};
use utoipa::ToSchema;
#[derive(ToSchema, Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct InputTokenDetails {
/// The number of tokens that were retrieved from the cache.
pub cached_tokens: u32,
}
#[derive(ToSchema, Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct OutputTokenDetails {
/// The number of reasoning tokens.
pub reasoning_tokens: u32,
}
/// Usage statistics for a response.
#[derive(ToSchema, Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct ResponseUsage {
/// The number of input tokens.
pub input_tokens: u32,
/// A detailed breakdown of the input tokens.
pub input_tokens_details: InputTokenDetails,
/// The number of output tokens.
pub output_tokens: u32,
/// A detailed breakdown of the output tokens.
pub output_tokens_details: OutputTokenDetails,
/// The total number of tokens used.
pub total_tokens: u32,
}
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Based on https://github.com/64bit/async-openai/ by Himanshu Neema
// Original Copyright (c) 2022 Himanshu Neema
// Licensed under MIT License (see ATTRIBUTIONS-Rust.md)
//
// Modifications Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES.
// Licensed under Apache 2.0
use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use super::{FileSearchRankingOptions, ImageFile, LastError, RunStatus};
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum RunStepType {
MessageCreation,
ToolCalls,
}
/// Represents a step in execution of a run.
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct RunStepObject {
/// The identifier, which can be referenced in API endpoints.
pub id: String,
/// The object type, which is always `thread.run.step`.
pub object: String,
/// The Unix timestamp (in seconds) for when the run step was created.
pub created_at: i32,
/// The ID of the [assistant](https://platform.openai.com/docs/api-reference/assistants) associated with the run step.
pub assistant_id: Option<String>,
/// The ID of the [thread](https://platform.openai.com/docs/api-reference/threads) that was run.
pub thread_id: String,
/// The ID of the [run](https://platform.openai.com/docs/api-reference/runs) that this run step is a part of.
pub run_id: String,
/// The type of run step, which can be either `message_creation` or `tool_calls`.
pub r#type: RunStepType,
/// The status of the run step, which can be either `in_progress`, `cancelled`, `failed`, `completed`, or `expired`.
pub status: RunStatus,
/// The details of the run step.
pub step_details: StepDetails,
/// The last error associated with this run. Will be `null` if there are no errors.
pub last_error: Option<LastError>,
///The Unix timestamp (in seconds) for when the run step expired. A step is considered expired if the parent run is expired.
pub expires_at: Option<i32>,
/// The Unix timestamp (in seconds) for when the run step was cancelled.
pub cancelled_at: Option<i32>,
/// The Unix timestamp (in seconds) for when the run step failed.
pub failed_at: Option<i32>,
/// The Unix timestamp (in seconds) for when the run step completed.
pub completed_at: Option<i32>,
pub metadata: Option<HashMap<String, serde_json::Value>>,
/// Usage statistics related to the run step. This value will be `null` while the run step's status is `in_progress`.
pub usage: Option<RunStepCompletionUsage>,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct RunStepCompletionUsage {
/// Number of completion tokens used over the course of the run step.
pub completion_tokens: u32,
/// Number of prompt tokens used over the course of the run step.
pub prompt_tokens: u32,
/// Total number of tokens used (prompt + completion).
pub total_tokens: u32,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
#[serde(tag = "type")]
#[serde(rename_all = "snake_case")]
pub enum StepDetails {
MessageCreation(RunStepDetailsMessageCreationObject),
ToolCalls(RunStepDetailsToolCallsObject),
}
/// Details of the message creation by the run step.
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct RunStepDetailsMessageCreationObject {
pub message_creation: MessageCreation,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct MessageCreation {
/// The ID of the message that was created by this run step.
pub message_id: String,
}
/// Details of the tool call.
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct RunStepDetailsToolCallsObject {
/// An array of tool calls the run step was involved in. These can be associated with one of three types of tools: `code_interpreter`, `file_search`, or `function`.
pub tool_calls: Vec<RunStepDetailsToolCalls>,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
#[serde(tag = "type")]
#[serde(rename_all = "snake_case")]
pub enum RunStepDetailsToolCalls {
/// Details of the Code Interpreter tool call the run step was involved in.
CodeInterpreter(RunStepDetailsToolCallsCodeObject),
FileSearch(RunStepDetailsToolCallsFileSearchObject),
Function(RunStepDetailsToolCallsFunctionObject),
}
/// Code interpreter tool call
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct RunStepDetailsToolCallsCodeObject {
/// The ID of the tool call.
pub id: String,
/// The Code Interpreter tool call definition.
pub code_interpreter: CodeInterpreter,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct CodeInterpreter {
/// The input to the Code Interpreter tool call.
pub input: String,
/// The outputs from the Code Interpreter tool call. Code Interpreter can output one or more items, including text (`logs`) or images (`image`). Each of these are represented by a different object type.
pub outputs: Vec<CodeInterpreterOutput>,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
#[serde(tag = "type")]
#[serde(rename_all = "lowercase")]
pub enum CodeInterpreterOutput {
/// Code interpreter log output
Logs(RunStepDetailsToolCallsCodeOutputLogsObject),
/// Code interpreter image output
Image(RunStepDetailsToolCallsCodeOutputImageObject),
}
/// Text output from the Code Interpreter tool call as part of a run step.
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct RunStepDetailsToolCallsCodeOutputLogsObject {
/// The text output from the Code Interpreter tool call.
pub logs: String,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct RunStepDetailsToolCallsCodeOutputImageObject {
/// The [file](https://platform.openai.com/docs/api-reference/files) ID of the image.
pub image: ImageFile,
}
/// File search tool call
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct RunStepDetailsToolCallsFileSearchObject {
/// The ID of the tool call object.
pub id: String,
/// For now, this is always going to be an empty object.
pub file_search: RunStepDetailsToolCallsFileSearchObjectFileSearch,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct RunStepDetailsToolCallsFileSearchObjectFileSearch {
pub ranking_options: Option<FileSearchRankingOptions>,
/// The results of the file search.
pub results: Option<Vec<RunStepDetailsToolCallsFileSearchResultObject>>,
}
/// A result instance of the file search.
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct RunStepDetailsToolCallsFileSearchResultObject {
/// The ID of the file that result was found in.
pub file_id: String,
/// The name of the file that result was found in.
pub file_name: String,
/// The score of the result. All values must be a floating point number between 0 and 1.
pub score: f32,
/// The content of the result that was found. The content is only included if requested via the include query parameter.
pub content: Option<Vec<RunStepDetailsToolCallsFileSearchResultObjectContent>>,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct RunStepDetailsToolCallsFileSearchResultObjectContent {
// note: type is text hence omitted from struct
/// The text content of the file.
pub text: Option<String>,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct RunStepDetailsToolCallsFunctionObject {
/// The ID of the tool call object.
pub id: String,
/// he definition of the function that was called.
pub function: RunStepFunctionObject,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct RunStepFunctionObject {
/// The name of the function.
pub name: String,
/// The arguments passed to the function.
pub arguments: String,
/// The output of the function. This will be `null` if the outputs have not been [submitted](https://platform.openai.com/docs/api-reference/runs/submitToolOutputs) yet.
pub output: Option<String>,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct RunStepFunctionObjectDelta {
/// The name of the function.
pub name: Option<String>,
/// The arguments passed to the function.
pub arguments: Option<String>,
/// The output of the function. This will be `null` if the outputs have not been [submitted](https://platform.openai.com/docs/api-reference/runs/submitToolOutputs) yet.
pub output: Option<String>,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct ListRunStepsResponse {
pub object: String,
pub data: Vec<RunStepObject>,
pub first_id: Option<String>,
pub last_id: Option<String>,
pub has_more: bool,
}
/// Represents a run step delta i.e. any changed fields on a run step during streaming.
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct RunStepDeltaObject {
/// The identifier of the run step, which can be referenced in API endpoints.
pub id: String,
/// The object type, which is always `thread.run.step.delta`.
pub object: String,
/// The delta containing the fields that have changed on the run step.
pub delta: RunStepDelta,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct RunStepDelta {
pub step_details: DeltaStepDetails,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
#[serde(tag = "type")]
#[serde(rename_all = "snake_case")]
pub enum DeltaStepDetails {
MessageCreation(RunStepDeltaStepDetailsMessageCreationObject),
ToolCalls(RunStepDeltaStepDetailsToolCallsObject),
}
/// Details of the message creation by the run step.
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct RunStepDeltaStepDetailsMessageCreationObject {
pub message_creation: Option<MessageCreation>,
}
/// Details of the tool call.
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct RunStepDeltaStepDetailsToolCallsObject {
/// An array of tool calls the run step was involved in. These can be associated with one of three types of tools: `code_interpreter`, `file_search`, or `function`.
pub tool_calls: Option<Vec<RunStepDeltaStepDetailsToolCalls>>,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
#[serde(tag = "type")]
#[serde(rename_all = "snake_case")]
pub enum RunStepDeltaStepDetailsToolCalls {
CodeInterpreter(RunStepDeltaStepDetailsToolCallsCodeObject),
FileSearch(RunStepDeltaStepDetailsToolCallsFileSearchObject),
Function(RunStepDeltaStepDetailsToolCallsFunctionObject),
}
/// Details of the Code Interpreter tool call the run step was involved in.
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct RunStepDeltaStepDetailsToolCallsCodeObject {
/// The index of the tool call in the tool calls array.
pub index: u32,
/// The ID of the tool call.
pub id: Option<String>,
/// The Code Interpreter tool call definition.
pub code_interpreter: Option<DeltaCodeInterpreter>,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct DeltaCodeInterpreter {
/// The input to the Code Interpreter tool call.
pub input: Option<String>,
/// The outputs from the Code Interpreter tool call. Code Interpreter can output one or more items, including text (`logs`) or images (`image`). Each of these are represented by a different object type.
pub outputs: Option<Vec<DeltaCodeInterpreterOutput>>,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
#[serde(tag = "type")]
#[serde(rename_all = "lowercase")]
pub enum DeltaCodeInterpreterOutput {
Logs(RunStepDeltaStepDetailsToolCallsCodeOutputLogsObject),
Image(RunStepDeltaStepDetailsToolCallsCodeOutputImageObject),
}
/// Text output from the Code Interpreter tool call as part of a run step.
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct RunStepDeltaStepDetailsToolCallsCodeOutputLogsObject {
/// The index of the output in the outputs array.
pub index: u32,
/// The text output from the Code Interpreter tool call.
pub logs: Option<String>,
}
/// Code interpreter image output
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct RunStepDeltaStepDetailsToolCallsCodeOutputImageObject {
/// The index of the output in the outputs array.
pub index: u32,
pub image: Option<ImageFile>,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct RunStepDeltaStepDetailsToolCallsFileSearchObject {
/// The index of the tool call in the tool calls array.
pub index: u32,
/// The ID of the tool call object.
pub id: Option<String>,
/// For now, this is always going to be an empty object.
pub file_search: Option<serde_json::Value>,
}
/// Function tool call
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct RunStepDeltaStepDetailsToolCallsFunctionObject {
/// The index of the tool call in the tool calls array.
pub index: u32,
/// The ID of the tool call object.
pub id: Option<String>,
/// The definition of the function that was called.
pub function: Option<RunStepFunctionObjectDelta>,
}
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Based on https://github.com/64bit/async-openai/ by Himanshu Neema
// Original Copyright (c) 2022 Himanshu Neema
// Licensed under MIT License (see ATTRIBUTIONS-Rust.md)
//
// Modifications Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES.
// Licensed under Apache 2.0
use std::collections::HashMap;
use derive_builder::Builder;
use serde::{Deserialize, Serialize};
use crate::error::OpenAIError;
use super::{
AssistantToolResources, AssistantTools, AssistantsApiResponseFormatOption,
AssistantsApiToolChoiceOption, CreateAssistantToolResources, CreateMessageRequest,
TruncationObject,
};
/// Represents a thread that contains [messages](https://platform.openai.com/docs/api-reference/messages).
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct ThreadObject {
/// The identifier, which can be referenced in API endpoints.
pub id: String,
/// The object type, which is always `thread`.
pub object: String,
/// The Unix timestamp (in seconds) for when the thread was created.
pub created_at: i32,
/// A set of resources that are made available to the assistant's tools in this thread. The resources are specific to the type of tool. For example, the `code_interpreter` tool requires a list of file IDs, while the `file_search` tool requires a list of vector store IDs.
pub tool_resources: Option<AssistantToolResources>,
pub metadata: Option<HashMap<String, serde_json::Value>>,
}
#[derive(Clone, Serialize, Default, Debug, Deserialize, Builder, PartialEq)]
#[builder(name = "CreateThreadRequestArgs")]
#[builder(pattern = "mutable")]
#[builder(setter(into, strip_option), default)]
#[builder(derive(Debug))]
#[builder(build_fn(error = "OpenAIError"))]
pub struct CreateThreadRequest {
/// A list of [messages](https://platform.openai.com/docs/api-reference/messages) to start the thread with.
#[serde(skip_serializing_if = "Option::is_none")]
pub messages: Option<Vec<CreateMessageRequest>>,
/// A set of resources that are made available to the assistant's tools in this thread. The resources are specific to the type of tool. For example, the `code_interpreter` tool requires a list of file IDs, while the `file_search` tool requires a list of vector store IDs.
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_resources: Option<CreateAssistantToolResources>,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<HashMap<String, serde_json::Value>>,
}
#[derive(Clone, Serialize, Default, Debug, Deserialize, PartialEq)]
pub struct ModifyThreadRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<HashMap<String, serde_json::Value>>,
/// A set of resources that are made available to the assistant's tools in this thread. The resources are specific to the type of tool. For example, the `code_interpreter` tool requires a list of file IDs, while the `file_search` tool requires a list of vector store IDs.
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_resources: Option<AssistantToolResources>,
}
#[derive(Clone, Serialize, Default, Debug, Deserialize, PartialEq)]
pub struct DeleteThreadResponse {
pub id: String,
pub deleted: bool,
pub object: String,
}
#[derive(Clone, Serialize, Default, Debug, Deserialize, Builder, PartialEq)]
#[builder(name = "CreateThreadAndRunRequestArgs")]
#[builder(pattern = "mutable")]
#[builder(setter(into, strip_option), default)]
#[builder(derive(Debug))]
#[builder(build_fn(error = "OpenAIError"))]
pub struct CreateThreadAndRunRequest {
/// The ID of the [assistant](https://platform.openai.com/docs/api-reference/assistants) to use to execute this run.
pub assistant_id: String,
/// If no thread is provided, an empty thread will be created.
#[serde(skip_serializing_if = "Option::is_none")]
pub thread: Option<CreateThreadRequest>,
/// The ID of the [Model](https://platform.openai.com/docs/api-reference/models) to be used to execute this run. If a value is provided here, it will override the model associated with the assistant. If not, the model associated with the assistant will be used.
#[serde(skip_serializing_if = "Option::is_none")]
pub model: Option<String>,
/// Override the default system message of the assistant. This is useful for modifying the behavior on a per-run basis.
#[serde(skip_serializing_if = "Option::is_none")]
pub instructions: Option<String>,
/// Override the tools the assistant can use for this run. This is useful for modifying the behavior on a per-run basis.
#[serde(skip_serializing_if = "Option::is_none")]
pub tools: Option<Vec<AssistantTools>>,
/// A set of resources that are used by the assistant's tools. The resources are specific to the type of tool. For example, the `code_interpreter` tool requires a list of file IDs, while the `file_search` tool requires a list of vector store IDs.
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_resources: Option<AssistantToolResources>,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<HashMap<String, serde_json::Value>>,
/// What sampling temperature to use, between 0 and 2. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic.
#[serde(skip_serializing_if = "Option::is_none")]
pub temperature: Option<f32>,
/// An alternative to sampling with temperature, called nucleus sampling, where the model considers the results of the tokens with top_p probability mass. So 0.1 means only the tokens comprising the top 10% probability mass are considered.
///
/// We generally recommend altering this or temperature but not both.
#[serde(skip_serializing_if = "Option::is_none")]
pub top_p: Option<f32>,
/// If `true`, returns a stream of events that happen during the Run as server-sent events, terminating when the Run enters a terminal state with a `data: [DONE]` message.
#[serde(skip_serializing_if = "Option::is_none")]
pub stream: Option<bool>,
/// The maximum number of prompt tokens that may be used over the course of the run. The run will make a best effort to use only the number of prompt tokens specified, across multiple turns of the run. If the run exceeds the number of prompt tokens specified, the run will end with status `incomplete`. See `incomplete_details` for more info.
#[serde(skip_serializing_if = "Option::is_none")]
pub max_prompt_tokens: Option<u32>,
/// The maximum number of completion tokens that may be used over the course of the run. The run will make a best effort to use only the number of completion tokens specified, across multiple turns of the run. If the run exceeds the number of completion tokens specified, the run will end with status `incomplete`. See `incomplete_details` for more info.
#[serde(skip_serializing_if = "Option::is_none")]
pub max_completion_tokens: Option<u32>,
/// Controls for how a thread will be truncated prior to the run. Use this to control the intial context window of the run.
#[serde(skip_serializing_if = "Option::is_none")]
pub truncation_strategy: Option<TruncationObject>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_choice: Option<AssistantsApiToolChoiceOption>,
/// Whether to enable [parallel function calling](https://platform.openai.com/docs/guides/function-calling/parallel-function-calling) during tool use.
#[serde(skip_serializing_if = "Option::is_none")]
pub parallel_tool_calls: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub response_format: Option<AssistantsApiResponseFormatOption>,
}
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Based on https://github.com/64bit/async-openai/ by Himanshu Neema
// Original Copyright (c) 2022 Himanshu Neema
// Licensed under MIT License (see ATTRIBUTIONS-Rust.md)
//
// Modifications Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES.
// Licensed under Apache 2.0
use crate::error::OpenAIError;
use derive_builder::Builder;
use serde::{Deserialize, Serialize};
use super::{InputSource, OpenAIFile};
/// Request to create an upload object that can accept byte chunks in the form of Parts.
#[derive(Clone, Serialize, Default, Debug, Deserialize, Builder, PartialEq)]
#[builder(name = "CreateUploadRequestArgs")]
#[builder(pattern = "mutable")]
#[builder(setter(into, strip_option), default)]
#[builder(derive(Debug))]
#[builder(build_fn(error = "OpenAIError"))]
pub struct CreateUploadRequest {
/// The name of the file to upload.
pub filename: String,
/// The intended purpose of the uploaded file.
///
/// See the [documentation on File purposes](https://platform.openai.com/docs/api-reference/files/create#files-create-purpose).
pub purpose: UploadPurpose,
/// The number of bytes in the file you are uploading.
pub bytes: u64,
/// The MIME type of the file.
///
/// This must fall within the supported MIME types for your file purpose. See the supported MIME
/// types for assistants and vision.
pub mime_type: String,
}
/// The intended purpose of the uploaded file.
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
#[serde(rename_all = "snake_case")]
pub enum UploadPurpose {
/// For use with Assistants and Message files
Assistants,
/// For Assistants image file inputs
Vision,
/// For use with the Batch API
Batch,
/// For use with Fine-tuning
#[default]
FineTune,
}
/// The Upload object can accept byte chunks in the form of Parts.
#[derive(Debug, Serialize, Deserialize)]
pub struct Upload {
/// The Upload unique identifier, which can be referenced in API endpoints
pub id: String,
/// The Unix timestamp (in seconds) for when the Upload was created
pub created_at: u32,
/// The name of the file to be uploaded
pub filename: String,
/// The intended number of bytes to be uploaded
pub bytes: u64,
/// The intended purpose of the file. [Pelase refer here]([Please refer here](/docs/api-reference/files/object#files/object-purpose) for acceptable values.)
pub purpose: UploadPurpose,
/// The status of the Upload.
pub status: UploadStatus,
/// The Unix timestamp (in seconds) for when the Upload was created
pub expires_at: u32,
/// The object type, which is always "upload"
pub object: String,
/// The ready File object after the Upload is completed
#[serde(skip_serializing_if = "Option::is_none")]
pub file: Option<OpenAIFile>,
}
/// The status of an upload
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum UploadStatus {
/// Upload is pending
Pending,
/// Upload has completed successfully
Completed,
/// Upload was cancelled
Cancelled,
/// Upload has expired
Expired,
}
/// The upload Part represents a chunk of bytes we can add to an Upload object.
#[derive(Debug, Serialize, Deserialize)]
pub struct UploadPart {
/// The upload Part unique identifier, which can be referenced in API endpoints
pub id: String,
/// The Unix timestamp (in seconds) for when the Part was created
pub created_at: u32,
/// The ID of the Upload object that this Part was added to
pub upload_id: String,
/// The object type, which is always `upload.part`
pub object: String,
}
/// Request parameters for adding a part to an Upload
#[derive(Debug, Clone)]
pub struct AddUploadPartRequest {
/// The chunk of bytes for this Part
pub data: InputSource,
}
/// Request parameters for completing an Upload
#[derive(Debug, Serialize)]
pub struct CompleteUploadRequest {
/// The ordered list of Part IDs
pub part_ids: Vec<String>,
/// The optional md5 checksum for the file contents to verify if the bytes uploaded matches what you expect
#[serde(skip_serializing_if = "Option::is_none")]
pub md5: Option<String>,
}
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Based on https://github.com/64bit/async-openai/ by Himanshu Neema
// Original Copyright (c) 2022 Himanshu Neema
// Licensed under MIT License (see ATTRIBUTIONS-Rust.md)
//
// Modifications Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES.
// Licensed under Apache 2.0
use crate::types::OpenAIError;
use derive_builder::Builder;
use serde::{Deserialize, Serialize};
use super::OrganizationRole;
/// Represents an individual `user` within an organization.
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct User {
/// The object type, which is always `organization.user`
pub object: String,
/// The identifier, which can be referenced in API endpoints
pub id: String,
/// The name of the user
pub name: String,
/// The email address of the user
pub email: String,
/// `owner` or `reader`
pub role: OrganizationRole,
/// The Unix timestamp (in seconds) of when the users was added.
pub added_at: u32,
}
/// A list of `User` objects.
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct UserListResponse {
pub object: String,
pub data: Vec<User>,
pub first_id: String,
pub last_id: String,
pub has_more: bool,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Builder)]
#[builder(name = "UserRoleUpdateRequestArgs")]
#[builder(pattern = "mutable")]
#[builder(setter(into, strip_option))]
#[builder(derive(Debug))]
#[builder(build_fn(error = "OpenAIError"))]
pub struct UserRoleUpdateRequest {
/// `owner` or `reader`
pub role: OrganizationRole,
}
/// Confirmation of the deleted user
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct UserDeleteResponse {
pub object: String,
pub id: String,
pub deleted: bool,
}
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Based on https://github.com/64bit/async-openai/ by Himanshu Neema
// Original Copyright (c) 2022 Himanshu Neema
// Licensed under MIT License (see ATTRIBUTIONS-Rust.md)
//
// Modifications Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES.
// Licensed under Apache 2.0
use std::collections::HashMap;
use derive_builder::Builder;
use serde::{Deserialize, Serialize};
use crate::error::OpenAIError;
use super::StaticChunkingStrategy;
#[derive(Debug, Serialize, Deserialize, Default, Clone, Builder, PartialEq)]
#[builder(name = "CreateVectorStoreRequestArgs")]
#[builder(pattern = "mutable")]
#[builder(setter(into, strip_option), default)]
#[builder(derive(Debug))]
#[builder(build_fn(error = "OpenAIError"))]
pub struct CreateVectorStoreRequest {
/// 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.
#[serde(skip_serializing_if = "Option::is_none")]
pub file_ids: Option<Vec<String>>,
/// The name of the vector store.
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
/// The expiration policy for a vector store.
#[serde(skip_serializing_if = "Option::is_none")]
pub expires_after: Option<VectorStoreExpirationAfter>,
/// 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.
#[serde(skip_serializing_if = "Option::is_none")]
pub chunking_strategy: Option<VectorStoreChunkingStrategy>,
/// 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. Keys can be a maximum of 64 characters long and values can be a maximum of 512 characters long.
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<HashMap<String, serde_json::Value>>,
}
#[derive(Debug, Serialize, Deserialize, Default, Clone, PartialEq)]
#[serde(tag = "type")]
pub enum VectorStoreChunkingStrategy {
/// The default strategy. This strategy currently uses a `max_chunk_size_tokens` of `800` and `chunk_overlap_tokens` of `400`.
#[default]
#[serde(rename = "auto")]
Auto,
#[serde(rename = "static")]
Static {
#[serde(rename = "static")]
config: StaticChunkingStrategy,
},
}
/// Vector store expiration policy
#[derive(Debug, Serialize, Deserialize, Default, Clone, PartialEq)]
pub struct VectorStoreExpirationAfter {
/// Anchor timestamp after which the expiration policy applies. Supported anchors: `last_active_at`.
pub anchor: String,
/// The number of days after the anchor time that the vector store will expire.
pub days: u16, // min: 1, max: 365
}
/// A vector store is a collection of processed files can be used by the `file_search` tool.
#[derive(Debug, Deserialize, Clone, PartialEq, Serialize)]
pub struct VectorStoreObject {
/// The identifier, which can be referenced in API endpoints.
pub id: String,
/// The object type, which is always `vector_store`.
pub object: String,
/// The Unix timestamp (in seconds) for when the vector store was created.
pub created_at: u32,
/// The name of the vector store.
pub name: Option<String>,
/// The total number of bytes used by the files in the vector store.
pub usage_bytes: u64,
pub file_counts: VectorStoreFileCounts,
/// The status of the vector store, which can be either `expired`, `in_progress`, or `completed`. A status of `completed` indicates that the vector store is ready for use.
pub status: VectorStoreStatus,
pub expires_after: Option<VectorStoreExpirationAfter>,
/// The Unix timestamp (in seconds) for when the vector store will expire.
pub expires_at: Option<u32>,
/// The Unix timestamp (in seconds) for when the vector store was last active.
pub last_active_at: Option<u32>,
/// 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. Keys can be a maximum of 64 characters long and values can be a maximum of 512 characters long.
pub metadata: Option<HashMap<String, serde_json::Value>>,
}
#[derive(Debug, Deserialize, Clone, PartialEq, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum VectorStoreStatus {
Expired,
InProgress,
Completed,
}
#[derive(Debug, Deserialize, Clone, PartialEq, Serialize)]
pub struct VectorStoreFileCounts {
/// The number of files that are currently being processed.
pub in_progress: u32,
/// The number of files that have been successfully processed.
pub completed: u32,
/// The number of files that have failed to process.
pub failed: u32,
/// The number of files that were cancelled.
pub cancelled: u32,
/// The total number of files.
pub total: u32,
}
#[derive(Debug, Deserialize, Clone, PartialEq, Serialize)]
pub struct ListVectorStoresResponse {
pub object: String,
pub data: Vec<VectorStoreObject>,
pub first_id: Option<String>,
pub last_id: Option<String>,
pub has_more: bool,
}
#[derive(Debug, Deserialize, Clone, PartialEq, Serialize)]
pub struct DeleteVectorStoreResponse {
pub id: String,
pub object: String,
pub deleted: bool,
}
#[derive(Debug, Serialize, Deserialize, Default, Clone, Builder, PartialEq)]
#[builder(name = "UpdateVectorStoreRequestArgs")]
#[builder(pattern = "mutable")]
#[builder(setter(into, strip_option), default)]
#[builder(derive(Debug))]
#[builder(build_fn(error = "OpenAIError"))]
pub struct UpdateVectorStoreRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub expires_after: Option<VectorStoreExpirationAfter>,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<HashMap<String, serde_json::Value>>,
}
#[derive(Debug, Deserialize, Clone, PartialEq, Serialize)]
pub struct ListVectorStoreFilesResponse {
pub object: String,
pub data: Vec<VectorStoreFileObject>,
pub first_id: Option<String>,
pub last_id: Option<String>,
pub has_more: bool,
}
#[derive(Debug, Deserialize, Clone, PartialEq, Serialize)]
pub struct VectorStoreFileObject {
/// The identifier, which can be referenced in API endpoints.
pub id: String,
/// The object type, which is always `vector_store.file`.
pub object: String,
/// The total vector store usage in bytes. Note that this may be different from the original file size.
pub usage_bytes: u64,
/// The Unix timestamp (in seconds) for when the vector store file was created.
pub created_at: u32,
/// The ID of the [vector store](https://platform.openai.com/docs/api-reference/vector-stores/object) that the [File](https://platform.openai.com/docs/api-reference/files) is attached to.
pub vector_store_id: String,
/// The status of the vector store file, which can be either `in_progress`, `completed`, `cancelled`, or `failed`. The status `completed` indicates that the vector store file is ready for use.
pub status: VectorStoreFileStatus,
/// The last error associated with this vector store file. Will be `null` if there are no errors.
pub last_error: Option<VectorStoreFileError>,
/// The strategy used to chunk the file.
pub chunking_strategy: Option<VectorStoreFileObjectChunkingStrategy>,
}
#[derive(Debug, Deserialize, Clone, PartialEq, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum VectorStoreFileStatus {
InProgress,
Completed,
Cancelled,
Failed,
}
#[derive(Debug, Deserialize, Clone, PartialEq, Serialize)]
pub struct VectorStoreFileError {
pub code: VectorStoreFileErrorCode,
/// A human-readable description of the error.
pub message: String,
}
#[derive(Debug, Deserialize, Clone, PartialEq, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum VectorStoreFileErrorCode {
ServerError,
UnsupportedFile,
InvalidFile,
}
#[derive(Debug, Deserialize, Clone, PartialEq, Serialize)]
#[serde(tag = "type")]
#[serde(rename_all = "lowercase")]
pub enum VectorStoreFileObjectChunkingStrategy {
/// This is returned when the chunking strategy is unknown. Typically, this is because the file was indexed before the `chunking_strategy` concept was introduced in the API.
Other,
Static {
r#static: StaticChunkingStrategy,
},
}
#[derive(Debug, Serialize, Deserialize, Default, Clone, Builder, PartialEq)]
#[builder(name = "CreateVectorStoreFileRequestArgs")]
#[builder(pattern = "mutable")]
#[builder(setter(into, strip_option), default)]
#[builder(derive(Debug))]
#[builder(build_fn(error = "OpenAIError"))]
pub struct CreateVectorStoreFileRequest {
/// 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.
pub file_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub chunking_strategy: Option<VectorStoreChunkingStrategy>,
#[serde(skip_serializing_if = "Option::is_none")]
pub attributes: Option<HashMap<String, AttributeValue>>,
}
#[derive(Debug, Deserialize, Clone, PartialEq, Serialize)]
pub struct DeleteVectorStoreFileResponse {
pub id: String,
pub object: String,
pub deleted: bool,
}
#[derive(Debug, Serialize, Default, Clone, Builder, PartialEq, Deserialize)]
#[builder(name = "CreateVectorStoreFileBatchRequestArgs")]
#[builder(pattern = "mutable")]
#[builder(setter(into, strip_option), default)]
#[builder(derive(Debug))]
#[builder(build_fn(error = "OpenAIError"))]
pub struct CreateVectorStoreFileBatchRequest {
/// 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.
pub file_ids: Vec<String>, // minItems: 1, maxItems: 500
pub chunking_strategy: Option<VectorStoreChunkingStrategy>,
}
#[derive(Debug, Deserialize, Clone, PartialEq, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum VectorStoreFileBatchStatus {
InProgress,
Completed,
Cancelled,
Failed,
}
#[derive(Debug, Deserialize, Clone, PartialEq, Serialize)]
pub struct VectorStoreFileBatchCounts {
/// The number of files that are currently being processed.
pub in_progress: u32,
/// The number of files that have been successfully processed.
pub completed: u32,
/// The number of files that have failed to process.
pub failed: u32,
/// The number of files that were cancelled.
pub cancelled: u32,
/// The total number of files.
pub total: u32,
}
/// A batch of files attached to a vector store.
#[derive(Debug, Deserialize, Clone, PartialEq, Serialize)]
pub struct VectorStoreFileBatchObject {
/// The identifier, which can be referenced in API endpoints.
pub id: String,
/// The object type, which is always `vector_store.file_batch`.
pub object: String,
/// The Unix timestamp (in seconds) for when the vector store files batch was created.
pub created_at: u32,
/// The ID of the [vector store](https://platform.openai.com/docs/api-reference/vector-stores/object) that the [File](https://platform.openai.com/docs/api-reference/files) is attached to.
pub vector_store_id: String,
/// The status of the vector store files batch, which can be either `in_progress`, `completed`, `cancelled` or `failed`.
pub status: VectorStoreFileBatchStatus,
pub file_counts: VectorStoreFileBatchCounts,
}
/// Represents the parsed content of a vector store file.
#[derive(Debug, Deserialize, Clone, PartialEq, Serialize)]
pub struct VectorStoreFileContentResponse {
/// The object type, which is always `vector_store.file_content.page`
pub object: String,
/// Parsed content of the file.
pub data: Vec<VectorStoreFileContentObject>,
/// Indicates if there are more content pages to fetch.
pub has_more: bool,
/// The token for the next page, if any.
pub next_page: Option<String>,
}
/// Represents the parsed content of a vector store file.
#[derive(Debug, Deserialize, Clone, PartialEq, Serialize)]
pub struct VectorStoreFileContentObject {
/// The content type (currently only `"text"`)
pub r#type: String,
/// The text content
pub text: String,
}
#[derive(Debug, Serialize, Default, Clone, Builder, PartialEq, Deserialize)]
#[builder(name = "VectorStoreSearchRequestArgs")]
#[builder(pattern = "mutable")]
#[builder(setter(into, strip_option), default)]
#[builder(derive(Debug))]
#[builder(build_fn(error = "OpenAIError"))]
pub struct VectorStoreSearchRequest {
/// A query string for a search.
pub query: VectorStoreSearchQuery,
/// Whether to rewrite the natural language query for vector search.
#[serde(skip_serializing_if = "Option::is_none")]
pub rewrite_query: Option<bool>,
/// The maximum number of results to return. This number should be between 1 and 50 inclusive.
#[serde(skip_serializing_if = "Option::is_none")]
pub max_num_results: Option<u8>,
/// A filter to apply based on file attributes.
#[serde(skip_serializing_if = "Option::is_none")]
pub filters: Option<VectorStoreSearchFilter>,
/// Ranking options for search.
#[serde(skip_serializing_if = "Option::is_none")]
pub ranking_options: Option<RankingOptions>,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
#[serde(untagged)]
pub enum VectorStoreSearchQuery {
/// A single query to search for.
Text(String),
/// A list of queries to search for.
Array(Vec<String>),
}
impl Default for VectorStoreSearchQuery {
fn default() -> Self {
Self::Text(String::new())
}
}
impl From<String> for VectorStoreSearchQuery {
fn from(query: String) -> Self {
Self::Text(query)
}
}
impl From<&str> for VectorStoreSearchQuery {
fn from(query: &str) -> Self {
Self::Text(query.to_string())
}
}
impl From<Vec<String>> for VectorStoreSearchQuery {
fn from(query: Vec<String>) -> Self {
Self::Array(query)
}
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
#[serde(untagged)]
pub enum VectorStoreSearchFilter {
Comparison(ComparisonFilter),
Compound(CompoundFilter),
}
impl From<ComparisonFilter> for VectorStoreSearchFilter {
fn from(filter: ComparisonFilter) -> Self {
Self::Comparison(filter)
}
}
impl From<CompoundFilter> for VectorStoreSearchFilter {
fn from(filter: CompoundFilter) -> Self {
Self::Compound(filter)
}
}
/// A filter used to compare a specified attribute key to a given value using a defined comparison operation.
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct ComparisonFilter {
/// Specifies the comparison operator: `eq`, `ne`, `gt`, `gte`, `lt`, `lte`.
pub r#type: ComparisonType,
/// The key to compare against the value.
pub key: String,
/// The value to compare against the attribute key; supports string, number, or boolean types.
pub value: AttributeValue,
}
/// Specifies the comparison operator: `eq`, `ne`, `gt`, `gte`, `lt`, `lte`.
#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum ComparisonType {
Eq,
Ne,
Gt,
Gte,
Lt,
Lte,
}
/// The value to compare against the attribute key; supports string, number, or boolean types.
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
#[serde(untagged)]
pub enum AttributeValue {
String(String),
Number(i64),
Boolean(bool),
}
impl From<String> for AttributeValue {
fn from(value: String) -> Self {
Self::String(value)
}
}
impl From<i64> for AttributeValue {
fn from(value: i64) -> Self {
Self::Number(value)
}
}
impl From<bool> for AttributeValue {
fn from(value: bool) -> Self {
Self::Boolean(value)
}
}
impl From<&str> for AttributeValue {
fn from(value: &str) -> Self {
Self::String(value.to_string())
}
}
/// Ranking options for search.
#[derive(Debug, Serialize, Default, Deserialize, Clone, PartialEq)]
pub struct RankingOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub ranker: Option<Ranker>,
#[serde(skip_serializing_if = "Option::is_none")]
pub score_threshold: Option<f32>,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub enum Ranker {
#[serde(rename = "auto")]
Auto,
#[serde(rename = "default-2024-11-15")]
Default20241115,
}
/// Combine multiple filters using `and` or `or`.
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct CompoundFilter {
/// Type of operation: `and` or `or`.
pub r#type: CompoundFilterType,
/// Array of filters to combine. Items can be `ComparisonFilter` or `CompoundFilter`
pub filters: Vec<VectorStoreSearchFilter>,
}
/// Type of operation: `and` or `or`.
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum CompoundFilterType {
And,
Or,
}
#[derive(Debug, Deserialize, Clone, PartialEq, Serialize)]
pub struct VectorStoreSearchResultsPage {
/// The object type, which is always `vector_store.search_results.page`.
pub object: String,
/// The query used for this search.
pub search_query: Vec<String>,
/// The list of search result items.
pub data: Vec<VectorStoreSearchResultItem>,
/// Indicates if there are more results to fetch.
pub has_more: bool,
/// The token for the next page, if any.
pub next_page: Option<String>,
}
#[derive(Debug, Deserialize, Clone, PartialEq, Serialize)]
pub struct VectorStoreSearchResultItem {
/// The ID of the vector store file.
pub file_id: String,
/// The name of the vector store file.
pub filename: String,
/// The similarity score for the result.
pub score: f32, // minimum: 0, maximum: 1
/// Attributes of the vector store file.
pub attributes: HashMap<String, AttributeValue>,
/// Content chunks from the file.
pub content: Vec<VectorStoreSearchResultContentObject>,
}
#[derive(Debug, Deserialize, Clone, PartialEq, Serialize)]
pub struct VectorStoreSearchResultContentObject {
/// The type of content
pub r#type: String,
/// The text content returned from search.
pub text: String,
}
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Based on https://github.com/64bit/async-openai/ by Himanshu Neema
// Original Copyright (c) 2022 Himanshu Neema
// Licensed under MIT License (see ATTRIBUTIONS-Rust.md)
//
// Modifications Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES.
// Licensed under Apache 2.0
use crate::{
Client,
config::Config,
error::OpenAIError,
types::{AddUploadPartRequest, CompleteUploadRequest, CreateUploadRequest, Upload, UploadPart},
};
/// Allows you to upload large files in multiple parts.
pub struct Uploads<'c, C: Config> {
client: &'c Client<C>,
}
impl<'c, C: Config> Uploads<'c, C> {
pub fn new(client: &'c Client<C>) -> Self {
Self { client }
}
/// Creates an intermediate [Upload](https://platform.openai.com/docs/api-reference/uploads/object) object that
/// you can add [Parts](https://platform.openai.com/docs/api-reference/uploads/part-object) to. Currently,
/// an Upload can accept at most 8 GB in total and expires after an hour after you create it.
///
/// Once you complete the Upload, we will create a [File](https://platform.openai.com/docs/api-reference/files/object)
/// object that contains all the parts you uploaded. This File is usable in the rest of our platform as a regular File object.
///
/// For certain `purpose`s, the correct `mime_type` must be specified. Please refer to documentation for the
/// supported MIME types for your use case:
/// - [Assistants](https://platform.openai.com/docs/assistants/tools/file-search/supported-files)
///
/// For guidance on the proper filename extensions for each purpose, please follow the documentation on
/// [creating a File](https://platform.openai.com/docs/api-reference/files/create).
#[crate::byot(T0 = serde::Serialize, R = serde::de::DeserializeOwned)]
pub async fn create(&self, request: CreateUploadRequest) -> Result<Upload, OpenAIError> {
self.client.post("/uploads", request).await
}
/// Adds a [Part](https://platform.openai.com/docs/api-reference/uploads/part-object) to an
/// [Upload](https://platform.openai.com/docs/api-reference/uploads/object) object.
/// A Part represents a chunk of bytes from the file you are trying to upload.
///
/// Each Part can be at most 64 MB, and you can add Parts until you hit the Upload maximum of 8 GB.
///
/// It is possible to add multiple Parts in parallel. You can decide the intended order of the Parts
/// when you [complete the Upload](https://platform.openai.com/docs/api-reference/uploads/complete).
#[crate::byot(
T0 = std::fmt::Display,
T1 = Clone,
R = serde::de::DeserializeOwned,
where_clause = "reqwest::multipart::Form: crate::traits::AsyncTryFrom<T1, Error = OpenAIError>")]
pub async fn add_part(
&self,
upload_id: &str,
request: AddUploadPartRequest,
) -> Result<UploadPart, OpenAIError> {
self.client
.post_form(&format!("/uploads/{upload_id}/parts"), request)
.await
}
/// Completes the [Upload](https://platform.openai.com/docs/api-reference/uploads/object).
///
/// Within the returned Upload object, there is a nested [File](https://platform.openai.com/docs/api-reference/files/object)
/// object that is ready to use in the rest of the platform.
///
/// You can specify the order of the Parts by passing in an ordered list of the Part IDs.
///
/// The number of bytes uploaded upon completion must match the number of bytes initially specified
/// when creating the Upload object. No Parts may be added after an Upload is completed.
#[crate::byot(T0 = std::fmt::Display, T1 = serde::Serialize, R = serde::de::DeserializeOwned)]
pub async fn complete(
&self,
upload_id: &str,
request: CompleteUploadRequest,
) -> Result<Upload, OpenAIError> {
self.client
.post(&format!("/uploads/{upload_id}/complete"), request)
.await
}
/// Cancels the Upload. No Parts may be added after an Upload is cancelled.
#[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
pub async fn cancel(&self, upload_id: &str) -> Result<Upload, OpenAIError> {
self.client
.post(
&format!("/uploads/{upload_id}/cancel"),
serde_json::json!({}),
)
.await
}
}
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Based on https://github.com/64bit/async-openai/ by Himanshu Neema
// Original Copyright (c) 2022 Himanshu Neema
// Licensed under MIT License (see ATTRIBUTIONS-Rust.md)
//
// Modifications Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES.
// Licensed under Apache 2.0
use serde::Serialize;
use crate::{
Client,
config::Config,
error::OpenAIError,
types::{User, UserDeleteResponse, UserListResponse, UserRoleUpdateRequest},
};
/// Manage users and their role in an organization. Users will be automatically added to the Default project.
pub struct Users<'c, C: Config> {
client: &'c Client<C>,
}
impl<'c, C: Config> Users<'c, C> {
pub fn new(client: &'c Client<C>) -> Self {
Self { client }
}
/// Lists all of the users in the organization.
#[crate::byot(T0 = serde::Serialize, R = serde::de::DeserializeOwned)]
pub async fn list<Q>(&self, query: &Q) -> Result<UserListResponse, OpenAIError>
where
Q: Serialize + ?Sized,
{
self.client
.get_with_query("/organization/users", &query)
.await
}
/// Modifies a user's role in the organization.
#[crate::byot(T0 = std::fmt::Display, T1 = serde::Serialize, R = serde::de::DeserializeOwned)]
pub async fn modify(
&self,
user_id: &str,
request: UserRoleUpdateRequest,
) -> Result<User, OpenAIError> {
self.client
.post(format!("/organization/users/{user_id}").as_str(), request)
.await
}
/// Retrieve a user by their identifier
#[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
pub async fn retrieve(&self, user_id: &str) -> Result<User, OpenAIError> {
self.client
.get(format!("/organization/users/{user_id}").as_str())
.await
}
/// Deletes a user from the organization.
#[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
pub async fn delete(&self, user_id: &str) -> Result<UserDeleteResponse, OpenAIError> {
self.client
.delete(format!("/organizations/users/{user_id}").as_str())
.await
}
}
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Based on https://github.com/64bit/async-openai/ by Himanshu Neema
// Original Copyright (c) 2022 Himanshu Neema
// Licensed under MIT License (see ATTRIBUTIONS-Rust.md)
//
// Modifications Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES.
// Licensed under Apache 2.0
use std::path::Path;
use reqwest::Body;
use tokio::fs::File;
use tokio_util::codec::{BytesCodec, FramedRead};
use crate::error::OpenAIError;
use crate::types::InputSource;
pub(crate) async fn file_stream_body(source: InputSource) -> Result<Body, OpenAIError> {
let body = match source {
InputSource::Path { path } => {
let file = File::open(path)
.await
.map_err(|e| OpenAIError::FileReadError(e.to_string()))?;
let stream = FramedRead::new(file, BytesCodec::new());
Body::wrap_stream(stream)
}
_ => {
return Err(OpenAIError::FileReadError(
"Cannot create stream from non-file source".to_string(),
));
}
};
Ok(body)
}
/// Creates the part for the given file for multipart upload.
pub(crate) async fn create_file_part(
source: InputSource,
) -> Result<reqwest::multipart::Part, OpenAIError> {
let (stream, file_name) = match source {
InputSource::Path { path } => {
let file_name = path
.file_name()
.ok_or_else(|| {
OpenAIError::FileReadError(format!(
"cannot extract file name from {}",
path.display()
))
})?
.to_str()
.unwrap()
.to_string();
(
file_stream_body(InputSource::Path { path }).await?,
file_name,
)
}
InputSource::Bytes { filename, bytes } => (Body::from(bytes), filename),
InputSource::VecU8 { filename, vec } => (Body::from(vec), filename),
};
let file_part = reqwest::multipart::Part::stream(stream).file_name(file_name);
Ok(file_part)
}
pub(crate) fn create_all_dir<P: AsRef<Path>>(dir: P) -> Result<(), OpenAIError> {
let exists = match Path::try_exists(dir.as_ref()) {
Ok(exists) => exists,
Err(e) => return Err(OpenAIError::FileSaveError(e.to_string())),
};
if !exists {
std::fs::create_dir_all(dir.as_ref())
.map_err(|e| OpenAIError::FileSaveError(e.to_string()))?;
}
Ok(())
}
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Based on https://github.com/64bit/async-openai/ by Himanshu Neema
// Original Copyright (c) 2022 Himanshu Neema
// Licensed under MIT License (see ATTRIBUTIONS-Rust.md)
//
// Modifications Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES.
// Licensed under Apache 2.0
use serde::Serialize;
use crate::{
Client,
config::Config,
error::OpenAIError,
types::{
CreateVectorStoreFileBatchRequest, ListVectorStoreFilesResponse, VectorStoreFileBatchObject,
},
};
/// Vector store file batches represent operations to add multiple files to a vector store.
///
/// Related guide: [File Search](https://platform.openai.com/docs/assistants/tools/file-search)
pub struct VectorStoreFileBatches<'c, C: Config> {
client: &'c Client<C>,
pub vector_store_id: String,
}
impl<'c, C: Config> VectorStoreFileBatches<'c, C> {
pub fn new(client: &'c Client<C>, vector_store_id: &str) -> Self {
Self {
client,
vector_store_id: vector_store_id.into(),
}
}
/// Create vector store file batch
#[crate::byot(T0 = serde::Serialize, R = serde::de::DeserializeOwned)]
pub async fn create(
&self,
request: CreateVectorStoreFileBatchRequest,
) -> Result<VectorStoreFileBatchObject, OpenAIError> {
self.client
.post(
&format!("/vector_stores/{}/file_batches", &self.vector_store_id),
request,
)
.await
}
/// Retrieves a vector store file batch.
#[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
pub async fn retrieve(
&self,
batch_id: &str,
) -> Result<VectorStoreFileBatchObject, OpenAIError> {
self.client
.get(&format!(
"/vector_stores/{}/file_batches/{batch_id}",
&self.vector_store_id
))
.await
}
/// Cancel a vector store file batch. This attempts to cancel the processing of files in this batch as soon as possible.
#[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
pub async fn cancel(&self, batch_id: &str) -> Result<VectorStoreFileBatchObject, OpenAIError> {
self.client
.post(
&format!(
"/vector_stores/{}/file_batches/{batch_id}/cancel",
&self.vector_store_id
),
serde_json::json!({}),
)
.await
}
/// Returns a list of vector store files in a batch.
#[crate::byot(T0 = std::fmt::Display, T1 = serde::Serialize, R = serde::de::DeserializeOwned)]
pub async fn list<Q>(
&self,
batch_id: &str,
query: &Q,
) -> Result<ListVectorStoreFilesResponse, OpenAIError>
where
Q: Serialize + ?Sized,
{
self.client
.get_with_query(
&format!(
"/vector_stores/{}/file_batches/{batch_id}/files",
&self.vector_store_id
),
&query,
)
.await
}
}
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Based on https://github.com/64bit/async-openai/ by Himanshu Neema
// Original Copyright (c) 2022 Himanshu Neema
// Licensed under MIT License (see ATTRIBUTIONS-Rust.md)
//
// Modifications Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES.
// Licensed under Apache 2.0
use serde::Serialize;
use crate::{
Client,
config::Config,
error::OpenAIError,
types::{
CreateVectorStoreFileRequest, DeleteVectorStoreFileResponse, ListVectorStoreFilesResponse,
VectorStoreFileContentResponse, VectorStoreFileObject,
},
};
/// Vector store files represent files inside a vector store.
///
/// Related guide: [File Search](https://platform.openai.com/docs/assistants/tools/file-search)
pub struct VectorStoreFiles<'c, C: Config> {
client: &'c Client<C>,
pub vector_store_id: String,
}
impl<'c, C: Config> VectorStoreFiles<'c, C> {
pub fn new(client: &'c Client<C>, vector_store_id: &str) -> Self {
Self {
client,
vector_store_id: vector_store_id.into(),
}
}
/// Create a vector store file by attaching a [File](https://platform.openai.com/docs/api-reference/files) to a [vector store](https://platform.openai.com/docs/api-reference/vector-stores/object).
#[crate::byot(T0 = serde::Serialize, R = serde::de::DeserializeOwned)]
pub async fn create(
&self,
request: CreateVectorStoreFileRequest,
) -> Result<VectorStoreFileObject, OpenAIError> {
self.client
.post(
&format!("/vector_stores/{}/files", &self.vector_store_id),
request,
)
.await
}
/// Retrieves a vector store file.
#[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
pub async fn retrieve(&self, file_id: &str) -> Result<VectorStoreFileObject, OpenAIError> {
self.client
.get(&format!(
"/vector_stores/{}/files/{file_id}",
&self.vector_store_id
))
.await
}
/// Delete a vector store file. This will remove the file from the vector store but the file itself will not be deleted. To delete the file, use the [delete file](https://platform.openai.com/docs/api-reference/files/delete) endpoint.
#[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
pub async fn delete(
&self,
file_id: &str,
) -> Result<DeleteVectorStoreFileResponse, OpenAIError> {
self.client
.delete(&format!(
"/vector_stores/{}/files/{file_id}",
&self.vector_store_id
))
.await
}
/// Returns a list of vector store files.
#[crate::byot(T0 = serde::Serialize, R = serde::de::DeserializeOwned)]
pub async fn list<Q>(&self, query: &Q) -> Result<ListVectorStoreFilesResponse, OpenAIError>
where
Q: Serialize + ?Sized,
{
self.client
.get_with_query(
&format!("/vector_stores/{}/files", &self.vector_store_id),
&query,
)
.await
}
/// Retrieve the parsed contents of a vector store file.
#[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
pub async fn retrieve_file_content(
&self,
file_id: &str,
) -> Result<VectorStoreFileContentResponse, OpenAIError> {
self.client
.get(&format!(
"/vector_stores/{}/files/{file_id}/content",
&self.vector_store_id
))
.await
}
}
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Based on https://github.com/64bit/async-openai/ by Himanshu Neema
// Original Copyright (c) 2022 Himanshu Neema
// Licensed under MIT License (see ATTRIBUTIONS-Rust.md)
//
// Modifications Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES.
// Licensed under Apache 2.0
use serde::Serialize;
use crate::{
Client, VectorStoreFiles,
config::Config,
error::OpenAIError,
types::{
CreateVectorStoreRequest, DeleteVectorStoreResponse, ListVectorStoresResponse,
UpdateVectorStoreRequest, VectorStoreObject, VectorStoreSearchRequest,
VectorStoreSearchResultsPage,
},
vector_store_file_batches::VectorStoreFileBatches,
};
pub struct VectorStores<'c, C: Config> {
client: &'c Client<C>,
}
impl<'c, C: Config> VectorStores<'c, C> {
pub fn new(client: &'c Client<C>) -> Self {
Self { client }
}
/// [VectorStoreFiles] API group
pub fn files(&self, vector_store_id: &str) -> VectorStoreFiles<C> {
VectorStoreFiles::new(self.client, vector_store_id)
}
/// [VectorStoreFileBatches] API group
pub fn file_batches(&self, vector_store_id: &str) -> VectorStoreFileBatches<C> {
VectorStoreFileBatches::new(self.client, vector_store_id)
}
/// Create a vector store.
#[crate::byot(T0 = serde::Serialize, R = serde::de::DeserializeOwned)]
pub async fn create(
&self,
request: CreateVectorStoreRequest,
) -> Result<VectorStoreObject, OpenAIError> {
self.client.post("/vector_stores", request).await
}
/// Retrieves a vector store.
#[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
pub async fn retrieve(&self, vector_store_id: &str) -> Result<VectorStoreObject, OpenAIError> {
self.client
.get(&format!("/vector_stores/{vector_store_id}"))
.await
}
/// Returns a list of vector stores.
#[crate::byot(T0 = serde::Serialize, R = serde::de::DeserializeOwned)]
pub async fn list<Q>(&self, query: &Q) -> Result<ListVectorStoresResponse, OpenAIError>
where
Q: Serialize + ?Sized,
{
self.client.get_with_query("/vector_stores", &query).await
}
/// Delete a vector store.
#[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
pub async fn delete(
&self,
vector_store_id: &str,
) -> Result<DeleteVectorStoreResponse, OpenAIError> {
self.client
.delete(&format!("/vector_stores/{vector_store_id}"))
.await
}
/// Modifies a vector store.
#[crate::byot(T0 = std::fmt::Display, T1 = serde::Serialize, R = serde::de::DeserializeOwned)]
pub async fn update(
&self,
vector_store_id: &str,
request: UpdateVectorStoreRequest,
) -> Result<VectorStoreObject, OpenAIError> {
self.client
.post(&format!("/vector_stores/{vector_store_id}"), request)
.await
}
/// Searches a vector store.
#[crate::byot(T0 = std::fmt::Display, T1 = serde::Serialize, R = serde::de::DeserializeOwned)]
pub async fn search(
&self,
vector_store_id: &str,
request: VectorStoreSearchRequest,
) -> Result<VectorStoreSearchResultsPage, OpenAIError> {
self.client
.post(&format!("/vector_stores/{vector_store_id}/search"), request)
.await
}
}
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Based on https://github.com/64bit/async-openai/ by Himanshu Neema
// Original Copyright (c) 2022 Himanshu Neema
// Licensed under MIT License (see ATTRIBUTIONS-Rust.md)
//
// Modifications Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES.
// Licensed under Apache 2.0
#![allow(dead_code)]
//! The purpose of this test to make sure that all _byot methods compiles with custom types.
use std::pin::Pin;
use dynamo_protocols::{Client, error::OpenAIError};
use futures::Stream;
use serde_json::{Value, json};
impl dynamo_protocols::traits::AsyncTryFrom<MyJson> for reqwest::multipart::Form {
type Error = OpenAIError;
async fn try_from(_value: MyJson) -> Result<Self, Self::Error> {
Ok(reqwest::multipart::Form::new())
}
}
#[derive(Clone)]
pub struct MyJson(Value);
type MyStreamingType = Pin<Box<dyn Stream<Item = Result<Value, OpenAIError>> + Send>>;
#[tokio::test]
async fn test_byot_files() {
let client = Client::new();
let _r: Result<Value, OpenAIError> = client.files().create_byot(MyJson(json!({}))).await;
let _r: Result<Value, OpenAIError> = client.files().list_byot([("limit", "2")]).await;
let _r: Result<Value, OpenAIError> = client.files().retrieve_byot("file_id").await;
let _r: Result<Value, OpenAIError> = client.files().delete_byot("file_id").await;
}
#[tokio::test]
async fn test_byot_assistants() {
let client = Client::new();
let _r: Result<Value, OpenAIError> = client.assistants().create_byot(json!({})).await;
let _r: Result<Value, OpenAIError> = client.assistants().retrieve_byot("aid").await;
let _r: Result<Value, OpenAIError> = client.assistants().update_byot("aid", json!({})).await;
let _r: Result<Value, OpenAIError> = client.assistants().list_byot([("limit", 2)]).await;
}
#[tokio::test]
async fn test_byot_models() {
let client = Client::new();
let _r: Result<Value, OpenAIError> = client.models().list_byot().await;
let _r: Result<Value, OpenAIError> = client.models().retrieve_byot("").await;
let _r: Result<Value, OpenAIError> = client.models().delete_byot(String::new()).await;
}
#[tokio::test]
async fn test_byot_moderations() {
let client = Client::new();
let _r: Result<Value, OpenAIError> = client.moderations().create_byot(json!({})).await;
}
#[tokio::test]
async fn test_byot_images() {
let client = Client::new();
let _r: Result<Value, OpenAIError> = client.images().create_byot(json!({})).await;
let _r: Result<Value, OpenAIError> = client.images().create_edit_byot(MyJson(json!({}))).await;
let _r: Result<Value, OpenAIError> = client
.images()
.create_variation_byot(MyJson(json!({})))
.await;
}
#[tokio::test]
async fn test_byot_chat() {
let client = Client::new();
let _r: Result<Value, OpenAIError> = client.chat().create_byot(json!({})).await;
let _r: Result<MyStreamingType, OpenAIError> =
client.chat().create_stream_byot(json!({})).await;
}
#[tokio::test]
async fn test_byot_completions() {
let client = Client::new();
let _r: Result<Value, OpenAIError> = client.completions().create_byot(json!({})).await;
let _r: Result<MyStreamingType, OpenAIError> =
client.completions().create_stream_byot(json!({})).await;
}
#[tokio::test]
async fn test_byot_audio() {
let client = Client::new();
let _r: Result<Value, OpenAIError> = client.audio().transcribe_byot(MyJson(json!({}))).await;
let _r: Result<Value, OpenAIError> = client
.audio()
.transcribe_verbose_json_byot(MyJson(json!({})))
.await;
let _r: Result<Value, OpenAIError> = client.audio().translate_byot(MyJson(json!({}))).await;
let _r: Result<Value, OpenAIError> = client
.audio()
.translate_verbose_json_byot(MyJson(json!({})))
.await;
}
#[tokio::test]
async fn test_byot_embeddings() {
let client = Client::new();
let _r: Result<Value, OpenAIError> = client.embeddings().create_byot(json!({})).await;
let _r: Result<Value, OpenAIError> = client.embeddings().create_base64_byot(json!({})).await;
}
#[tokio::test]
async fn test_byot_fine_tunning() {
let client = Client::new();
let _r: Result<Value, OpenAIError> = client.fine_tuning().create_byot(json!({})).await;
let _r: Result<Value, OpenAIError> = client
.fine_tuning()
.list_paginated_byot([("limit", "2")])
.await;
let _r: Result<Value, OpenAIError> = client
.fine_tuning()
.retrieve_byot("fine_tunning_job_id")
.await;
let _r: Result<Value, OpenAIError> =
client.fine_tuning().cancel_byot("fine_tuning_job_id").await;
let _r: Result<Value, OpenAIError> = client
.fine_tuning()
.list_events_byot("fine_tuning_job_id", [("limit", "2")])
.await;
let _r: Result<Value, OpenAIError> = client
.fine_tuning()
.list_checkpoints_byot("fine_tuning_job_id", [("limit", "2")])
.await;
}
#[derive(Clone, serde::Deserialize)]
pub struct MyThreadJson(Value);
impl TryFrom<eventsource_stream::Event> for MyThreadJson {
type Error = OpenAIError;
fn try_from(_value: eventsource_stream::Event) -> Result<Self, Self::Error> {
Ok(MyThreadJson(json!({})))
}
}
type MyThreadStreamingType = Pin<Box<dyn Stream<Item = Result<MyThreadJson, OpenAIError>> + Send>>;
#[tokio::test]
async fn test_byot_threads() {
let client = Client::new();
let _r: Result<Value, OpenAIError> = client.threads().create_and_run_byot(json!({})).await;
let _r: Result<MyThreadStreamingType, OpenAIError> =
client.threads().create_and_run_stream_byot(json!({})).await;
let _r: Result<Value, OpenAIError> = client.threads().create_byot(json!({})).await;
let _r: Result<Value, OpenAIError> = client.threads().retrieve_byot("thread_id").await;
let _r: Result<Value, OpenAIError> = client.threads().update_byot("thread_id", json!({})).await;
let _r: Result<Value, OpenAIError> = client.threads().delete_byot("thread_id").await;
}
#[tokio::test]
async fn test_byot_messages() {
let client = Client::new();
let _r: Result<Value, OpenAIError> = client
.threads()
.messages("thread_id")
.create_byot(json!({}))
.await;
let _r: Result<Value, OpenAIError> = client
.threads()
.messages("thread_id")
.retrieve_byot("message_id")
.await;
let _r: Result<Value, OpenAIError> = client
.threads()
.messages("thread_id")
.update_byot("message_id", json!({}))
.await;
let _r: Result<Value, OpenAIError> = client
.threads()
.messages("thread_id")
.list_byot([("limit", "2")])
.await;
let _r: Result<Value, OpenAIError> = client
.threads()
.messages("thread_id")
.delete_byot("message_id")
.await;
}
#[tokio::test]
async fn test_byot_runs() {
let client = Client::new();
let _r: Result<Value, OpenAIError> = client
.threads()
.runs("thread_id")
.create_byot(json!({}))
.await;
let _r: Result<MyThreadStreamingType, OpenAIError> = client
.threads()
.runs("thread_id")
.create_stream_byot(json!({}))
.await;
let _r: Result<Value, OpenAIError> = client
.threads()
.runs("thread_id")
.retrieve_byot("run_id")
.await;
let _r: Result<Value, OpenAIError> = client
.threads()
.runs("thread_id")
.update_byot("run_id", json!({}))
.await;
let _r: Result<Value, OpenAIError> = client
.threads()
.runs("thread_id")
.list_byot([("limit", "2")])
.await;
let _r: Result<Value, OpenAIError> = client
.threads()
.runs("thread_id")
.submit_tool_outputs_byot("run_id", json!({}))
.await;
let _r: Result<MyThreadStreamingType, OpenAIError> = client
.threads()
.runs("thread_id")
.submit_tool_outputs_stream_byot("run_id", json!({}))
.await;
let _r: Result<Value, OpenAIError> = client
.threads()
.runs("thread_id")
.cancel_byot("run_id")
.await;
}
#[tokio::test]
async fn test_byot_run_steps() {
let client = Client::new();
let _r: Result<Value, OpenAIError> = client
.threads()
.runs("thread_id")
.steps("run_id")
.retrieve_byot("step_id")
.await;
let _r: Result<Value, OpenAIError> = client
.threads()
.runs("thread_id")
.steps("run_id")
.list_byot([("limit", "2")])
.await;
}
#[tokio::test]
async fn test_byot_vector_store_files() {
let client = Client::new();
let _r: Result<Value, OpenAIError> = client
.vector_stores()
.files("vector_store_id")
.create_byot(json!({}))
.await;
let _r: Result<Value, OpenAIError> = client
.vector_stores()
.files("vector_store_id")
.retrieve_byot("file_id")
.await;
let _r: Result<Value, OpenAIError> = client
.vector_stores()
.files("vector_store_id")
.delete_byot("file_id")
.await;
let _r: Result<Value, OpenAIError> = client
.vector_stores()
.files("vector_store_id")
.list_byot([("limit", "2")])
.await;
}
#[tokio::test]
async fn test_byot_vector_store_file_batches() {
let client = Client::new();
let _r: Result<Value, OpenAIError> = client
.vector_stores()
.file_batches("vector_store_id")
.create_byot(json!({}))
.await;
let _r: Result<Value, OpenAIError> = client
.vector_stores()
.file_batches("vector_store_id")
.retrieve_byot("file_id")
.await;
let _r: Result<Value, OpenAIError> = client
.vector_stores()
.file_batches("vector_store_id")
.cancel_byot("file_id")
.await;
let _r: Result<Value, OpenAIError> = client
.vector_stores()
.file_batches("vector_store_id")
.list_byot("batch_id", [("limit", "2")])
.await;
}
#[tokio::test]
async fn test_byot_batches() {
let client = Client::new();
let _r: Result<Value, OpenAIError> = client.batches().create_byot(json!({})).await;
let _r: Result<Value, OpenAIError> = client.batches().list_byot([("limit", "2")]).await;
let _r: Result<Value, OpenAIError> = client.batches().retrieve_byot("batch_id").await;
let _r: Result<Value, OpenAIError> = client.batches().cancel_byot("batch_id").await;
}
#[tokio::test]
async fn test_byot_audit_logs() {
let client = Client::new();
let _r: Result<Value, OpenAIError> = client.audit_logs().get_byot([("limit", "2")]).await;
}
#[tokio::test]
async fn test_byot_invites() {
let client = Client::new();
let _r: Result<Value, OpenAIError> = client.invites().create_byot(json!({})).await;
let _r: Result<Value, OpenAIError> = client.invites().retrieve_byot("invite_id").await;
let _r: Result<Value, OpenAIError> = client.invites().delete_byot("invite_id").await;
let _r: Result<Value, OpenAIError> = client.invites().list_byot([("limit", "2")]).await;
}
#[tokio::test]
async fn test_byot_projects() {
let client = Client::new();
let _r: Result<Value, OpenAIError> = client.projects().list_byot([("limit", "2")]).await;
let _r: Result<Value, OpenAIError> = client.projects().create_byot(json!({})).await;
let _r: Result<Value, OpenAIError> = client.projects().retrieve_byot("project_id").await;
let _r: Result<Value, OpenAIError> =
client.projects().modify_byot("project_id", json!({})).await;
let _r: Result<Value, OpenAIError> = client.projects().archive_byot("project_id").await;
}
#[tokio::test]
async fn test_byot_project_api_keys() {
let client = Client::new();
let _r: Result<Value, OpenAIError> = client
.projects()
.api_keys("project_id")
.list_byot([("query", "2")])
.await;
let _r: Result<Value, OpenAIError> = client
.projects()
.api_keys("project_id")
.retrieve_byot("api_key")
.await;
let _r: Result<Value, OpenAIError> = client
.projects()
.api_keys("project_id")
.delete_byot("api_key")
.await;
}
#[tokio::test]
async fn test_byot_project_service_accounts() {
let client = Client::new();
let _r: Result<Value, OpenAIError> = client
.projects()
.service_accounts("project_id")
.create_byot(json!({}))
.await;
let _r: Result<Value, OpenAIError> = client
.projects()
.service_accounts("project_id")
.delete_byot("service_account_id")
.await;
let _r: Result<Value, OpenAIError> = client
.projects()
.service_accounts("project_id")
.retrieve_byot("service_account_id")
.await;
let _r: Result<Value, OpenAIError> = client
.projects()
.service_accounts("project_id")
.list_byot([("limit", "2")])
.await;
}
#[tokio::test]
async fn test_byot_project_users() {
let client = Client::new();
let _r: Result<Value, OpenAIError> = client
.projects()
.users("project_id")
.create_byot(json!({}))
.await;
let _r: Result<Value, OpenAIError> = client
.projects()
.users("project_id")
.delete_byot("user_id")
.await;
let _r: Result<Value, OpenAIError> = client
.projects()
.users("project_id")
.list_byot([("limit", "2")])
.await;
let _r: Result<Value, OpenAIError> = client
.projects()
.users("project_id")
.retrieve_byot("user_id")
.await;
}
#[tokio::test]
async fn test_byot_uploads() {
let client = Client::new();
let _r: Result<Value, OpenAIError> = client.uploads().create_byot(json!({})).await;
let _r: Result<Value, OpenAIError> = client
.uploads()
.add_part_byot("upload_id", MyJson(json!({})))
.await;
let _r: Result<Value, OpenAIError> =
client.uploads().complete_byot("upload_id", json!({})).await;
let _r: Result<Value, OpenAIError> = client.uploads().cancel_byot("upload_id").await;
}
#[tokio::test]
async fn test_byot_users() {
let client = Client::new();
let _r: Result<Value, OpenAIError> = client.users().list_byot([("limit", "2")]).await;
let _r: Result<Value, OpenAIError> = client.users().modify_byot("user_id", json!({})).await;
let _r: Result<Value, OpenAIError> = client.users().retrieve_byot("user_id").await;
let _r: Result<Value, OpenAIError> = client.users().delete_byot("user_id").await;
}
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Based on https://github.com/64bit/async-openai/ by Himanshu Neema
// Original Copyright (c) 2022 Himanshu Neema
// Licensed under MIT License (see ATTRIBUTIONS-Rust.md)
//
// Modifications Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES.
// Licensed under Apache 2.0
use dynamo_protocols::types::CreateTranslationRequestArgs;
use dynamo_protocols::{Client, types::CreateTranscriptionRequestArgs};
use tokio_test::assert_err;
#[tokio::test]
async fn transcribe_test() {
let client = Client::new();
let request = CreateTranscriptionRequestArgs::default().build().unwrap();
let response = client.audio().transcribe(request).await;
assert_err!(response); // FileReadError("cannot extract file name from ")
}
#[tokio::test]
async fn transcribe_sendable_test() {
let client = Client::new();
// https://github.com/64bit/async-openai/issues/140
let transcribe = tokio::spawn(async move {
let request = CreateTranscriptionRequestArgs::default().build().unwrap();
client.audio().transcribe(request).await
});
let response = transcribe.await.unwrap();
assert_err!(response); // FileReadError("cannot extract file name from ")
}
#[tokio::test]
async fn translate_test() {
let client = Client::new();
let request = CreateTranslationRequestArgs::default().build().unwrap();
let response = client.audio().translate(request).await;
assert_err!(response); // FileReadError("cannot extract file name from ")
}
#[tokio::test]
async fn translate_sendable_test() {
let client = Client::new();
// https://github.com/64bit/async-openai/issues/140
let translate = tokio::spawn(async move {
let request = CreateTranslationRequestArgs::default().build().unwrap();
client.audio().translate(request).await
});
let response = translate.await.unwrap();
assert_err!(response); // FileReadError("cannot extract file name from ")
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment