Unverified Commit 8cb47d04 authored by MatejKosec's avatar MatejKosec Committed by GitHub
Browse files

feat: responses API compliance with upstream type alignment (#6089)


Signed-off-by: default avatarMatej Kosec <mkosec@nvidia.com>
Co-authored-by: default avatarIshan Dhanani <ishandhanani@gmail.com>
parent f8d0a9f9
#!/bin/bash
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
# Setup cleanup trap
cleanup() {
echo "Cleaning up background processes..."
kill $DYNAMO_PID 2>/dev/null || true
wait $DYNAMO_PID 2>/dev/null || true
echo "Cleanup complete."
}
trap cleanup EXIT INT TERM
# Default values
MODEL="Qwen/Qwen3-VL-8B-Instruct"
CHAT_TEMPLATE=""
ENABLE_OTEL=false
# Parse command line arguments
EXTRA_ARGS=()
while [[ $# -gt 0 ]]; do
case $1 in
--model-path)
MODEL="$2"
shift 2
;;
--chat-template)
CHAT_TEMPLATE="$2"
shift 2
;;
--enable-otel)
ENABLE_OTEL=true
shift
;;
-h|--help)
echo "Usage: $0 [OPTIONS]"
echo "Options:"
echo " --model-path <name> Specify model (default: $MODEL)"
echo " --chat-template <name> Specify SGLang chat template (default: $CHAT_TEMPLATE)"
echo " --enable-otel Enable OpenTelemetry tracing"
echo " -h, --help Show this help message"
echo ""
echo "Additional SGLang/Dynamo flags can be passed and will be forwarded"
echo "Note: System metrics are enabled by default on port 8081 (worker)"
exit 0
;;
*)
EXTRA_ARGS+=("$1")
shift
;;
esac
done
# Enable tracing if requested
TRACE_ARGS=()
if [ "$ENABLE_OTEL" = true ]; then
export DYN_LOGGING_JSONL=true
export OTEL_EXPORT_ENABLED=1
export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=${OTEL_EXPORTER_OTLP_TRACES_ENDPOINT:-http://localhost:4317}
TRACE_ARGS+=(--enable-trace --otlp-traces-endpoint localhost:4317)
fi
# run ingress
# dynamo.frontend accepts either --http-port flag or DYN_HTTP_PORT env var (defaults to 8000)
OTEL_SERVICE_NAME=dynamo-frontend \
python3 -m dynamo.frontend &
DYNAMO_PID=$!
# Build chat template args (only if explicitly set)
TEMPLATE_ARGS=()
if [ -n "$CHAT_TEMPLATE" ]; then
TEMPLATE_ARGS+=(--chat-template "$CHAT_TEMPLATE")
fi
# run worker with vision model (SGLang auto-detects chat template from HF tokenizer)
OTEL_SERVICE_NAME=dynamo-worker DYN_SYSTEM_PORT=${DYN_SYSTEM_PORT:-8081} \
python3 -m dynamo.sglang \
--model-path "$MODEL" \
--served-model-name "$MODEL" \
"${TEMPLATE_ARGS[@]}" \
--page-size 16 \
--tp 1 \
--trust-remote-code \
--skip-tokenizer-init \
--enable-metrics \
"${TRACE_ARGS[@]}" \
"${EXTRA_ARGS[@]}"
......@@ -24,23 +24,58 @@ use crate::{
use bytes::Bytes;
use super::{
AddUploadPartRequest, AudioInput, AudioResponseFormat, AudioUrl, ChatCompletionFunctionCall,
ChatCompletionFunctions, ChatCompletionNamedToolChoice, ChatCompletionRequestAssistantMessage,
ChatCompletionRequestAssistantMessageContent, ChatCompletionRequestDeveloperMessage,
ChatCompletionRequestDeveloperMessageContent, ChatCompletionRequestFunctionMessage,
ChatCompletionRequestMessage, ChatCompletionRequestMessageContentPartAudio,
ChatCompletionRequestMessageContentPartAudioUrl, ChatCompletionRequestMessageContentPartImage,
ChatCompletionRequestMessageContentPartText, ChatCompletionRequestMessageContentPartVideo,
ChatCompletionRequestSystemMessage, ChatCompletionRequestSystemMessageContent,
ChatCompletionRequestToolMessage, ChatCompletionRequestToolMessageContent,
ChatCompletionRequestUserMessage, ChatCompletionRequestUserMessageContent,
ChatCompletionRequestUserMessageContentPart, ChatCompletionToolChoiceOption, CreateFileRequest,
CreateImageEditRequest, CreateImageVariationRequest, CreateMessageRequestContent,
CreateSpeechResponse, CreateTranscriptionRequest, CreateTranslationRequest, DallE2ImageSize,
EmbeddingInput, FileInput, FilePurpose, FunctionName, Image, ImageInput, ImageModel,
ImageResponseFormat, ImageSize, ImageUrl, ImagesResponse, ModerationInput, Prompt, Role, Stop,
TimestampGranularity, VideoUrl,
responses::{CodeInterpreterContainer, Input, InputContent, Role as ResponsesRole},
AddUploadPartRequest,
AudioInput,
AudioResponseFormat,
AudioUrl,
ChatCompletionFunctionCall,
ChatCompletionFunctions,
ChatCompletionNamedToolChoice,
ChatCompletionRequestAssistantMessage,
ChatCompletionRequestAssistantMessageContent,
ChatCompletionRequestDeveloperMessage,
ChatCompletionRequestDeveloperMessageContent,
ChatCompletionRequestFunctionMessage,
ChatCompletionRequestMessage,
ChatCompletionRequestMessageContentPartAudio,
ChatCompletionRequestMessageContentPartAudioUrl,
ChatCompletionRequestMessageContentPartImage,
ChatCompletionRequestMessageContentPartText,
ChatCompletionRequestMessageContentPartVideo,
ChatCompletionRequestSystemMessage,
ChatCompletionRequestSystemMessageContent,
ChatCompletionRequestToolMessage,
ChatCompletionRequestToolMessageContent,
ChatCompletionRequestUserMessage,
ChatCompletionRequestUserMessageContent,
ChatCompletionRequestUserMessageContentPart,
ChatCompletionToolChoiceOption,
CreateFileRequest,
CreateImageEditRequest,
CreateImageVariationRequest,
CreateMessageRequestContent,
CreateSpeechResponse,
CreateTranscriptionRequest,
CreateTranslationRequest,
DallE2ImageSize,
EmbeddingInput,
FileInput,
FilePurpose,
FunctionName,
Image,
ImageInput,
ImageModel,
ImageResponseFormat,
ImageSize,
ImageUrl,
ImagesResponse,
ModerationInput,
Prompt,
Role,
Stop,
TimestampGranularity,
VideoUrl,
// responses types now have their own impls in responses/impls.rs
};
/// for `impl_from!(T, Enum)`, implements
......@@ -1056,50 +1091,4 @@ impl AsyncTryFrom<AddUploadPartRequest> for reqwest::multipart::Form {
// end: types to multipart form
impl Default for Input {
fn default() -> Self {
Self::Text("".to_string())
}
}
impl Default for InputContent {
fn default() -> Self {
Self::TextInput("".to_string())
}
}
impl From<String> for Input {
fn from(value: String) -> Self {
Input::Text(value)
}
}
impl From<&str> for Input {
fn from(value: &str) -> Self {
Input::Text(value.to_owned())
}
}
impl Default for ResponsesRole {
fn default() -> Self {
Self::User
}
}
impl From<String> for InputContent {
fn from(value: String) -> Self {
Self::TextInput(value)
}
}
impl From<&str> for InputContent {
fn from(value: &str) -> Self {
Self::TextInput(value.to_owned())
}
}
impl Default for CodeInterpreterContainer {
fn default() -> Self {
CodeInterpreterContainer::Id("".to_string())
}
}
// Responses API impls are now in responses/impls.rs
// SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
use crate::types::mcp::{
MCPToolAllowedTools, MCPToolApprovalFilter, MCPToolApprovalSetting, MCPToolFilter,
MCPToolRequireApproval,
};
// MCPToolRequireApproval ergonomics
impl From<MCPToolApprovalSetting> for MCPToolRequireApproval {
fn from(setting: MCPToolApprovalSetting) -> Self {
MCPToolRequireApproval::ApprovalSetting(setting)
}
}
impl From<MCPToolApprovalFilter> for MCPToolRequireApproval {
fn from(filter: MCPToolApprovalFilter) -> Self {
MCPToolRequireApproval::Filter(filter)
}
}
// MCPToolAllowedTools ergonomics
impl From<MCPToolFilter> for MCPToolAllowedTools {
fn from(filter: MCPToolFilter) -> Self {
MCPToolAllowedTools::Filter(filter)
}
}
impl From<Vec<String>> for MCPToolAllowedTools {
fn from(tools: Vec<String>) -> Self {
MCPToolAllowedTools::List(tools)
}
}
impl From<Vec<&str>> for MCPToolAllowedTools {
fn from(tools: Vec<&str>) -> Self {
MCPToolAllowedTools::List(tools.into_iter().map(|s| s.to_string()).collect())
}
}
impl From<&[&str]> for MCPToolAllowedTools {
fn from(tools: &[&str]) -> Self {
MCPToolAllowedTools::List(tools.iter().map(|s| s.to_string()).collect())
}
}
impl<const N: usize> From<[&str; N]> for MCPToolAllowedTools {
fn from(tools: [&str; N]) -> Self {
MCPToolAllowedTools::List(tools.iter().map(|s| s.to_string()).collect())
}
}
impl From<&Vec<String>> for MCPToolAllowedTools {
fn from(tools: &Vec<String>) -> Self {
MCPToolAllowedTools::List(tools.clone())
}
}
impl From<&Vec<&str>> for MCPToolAllowedTools {
fn from(tools: &Vec<&str>) -> Self {
MCPToolAllowedTools::List(tools.iter().map(|s| s.to_string()).collect())
}
}
impl From<&str> for MCPToolAllowedTools {
fn from(tool: &str) -> Self {
MCPToolAllowedTools::List(vec![tool.to_string()])
}
}
impl From<String> for MCPToolAllowedTools {
fn from(tool: String) -> Self {
MCPToolAllowedTools::List(vec![tool])
}
}
// SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
use derive_builder::Builder;
use serde::{Deserialize, Serialize};
use utoipa::ToSchema;
use crate::error::OpenAIError;
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum McpToolConnectorId {
ConnectorDropbox,
ConnectorGmail,
ConnectorGooglecalendar,
ConnectorGoogledrive,
ConnectorMicrosoftteams,
ConnectorOutlookcalendar,
ConnectorOutlookemail,
ConnectorSharepoint,
}
#[derive(Debug, Serialize, Deserialize, Clone, Builder, PartialEq, Default, ToSchema)]
#[builder(
name = "MCPToolArgs",
pattern = "mutable",
setter(into, strip_option),
default
)]
#[builder(build_fn(error = "OpenAIError"))]
pub struct MCPTool {
/// A label for this MCP server, used to identify it in tool calls.
pub server_label: String,
/// List of allowed tool names or a filter object.
#[serde(skip_serializing_if = "Option::is_none")]
pub allowed_tools: Option<MCPToolAllowedTools>,
/// An OAuth access token that can be used with a remote MCP server, either with a custom MCP
/// server URL or a service connector. Your application must handle the OAuth authorization
/// flow and provide the token here.
#[serde(skip_serializing_if = "Option::is_none")]
pub authorization: Option<String>,
/// Identifier for service connectors, like those available in ChatGPT. One of `server_url` or
/// `connector_id` must be provided. Learn more about service connectors [here](https://platform.openai.com/docs/guides/tools-remote-mcp#connectors).
///
/// Currently supported `connector_id` values are:
/// - Dropbox: `connector_dropbox`
/// - Gmail: `connector_gmail`
/// - Google Calendar: `connector_googlecalendar`
/// - Google Drive: `connector_googledrive`
/// - Microsoft Teams: `connector_microsoftteams`
/// - Outlook Calendar: `connector_outlookcalendar`
/// - Outlook Email: `connector_outlookemail`
/// - SharePoint: `connector_sharepoint`
#[serde(skip_serializing_if = "Option::is_none")]
pub connector_id: Option<McpToolConnectorId>,
/// Optional HTTP headers to send to the MCP server. Use for authentication or other purposes.
#[serde(skip_serializing_if = "Option::is_none")]
pub headers: Option<serde_json::Value>,
/// Specify which of the MCP server's tools require approval.
#[serde(skip_serializing_if = "Option::is_none")]
pub require_approval: Option<MCPToolRequireApproval>,
/// Optional description of the MCP server, used to provide more context.
#[serde(skip_serializing_if = "Option::is_none")]
pub server_description: Option<String>,
/// The URL for the MCP server. One of `server_url` or `connector_id` must be provided.
#[serde(skip_serializing_if = "Option::is_none")]
pub server_url: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, ToSchema)]
#[serde(untagged)]
pub enum MCPToolAllowedTools {
/// A string array of allowed tool names
List(Vec<String>),
/// A filter object to specify which tools are allowed.
Filter(MCPToolFilter),
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, ToSchema)]
pub struct MCPToolFilter {
/// Indicates whether or not a tool modifies data or is read-only.
/// If an MCP server is annotated with [readOnlyHint](https://modelcontextprotocol.io/specification/2025-06-18/schema#toolannotations-readonlyhint),
/// it will match this filter.
#[serde(skip_serializing_if = "Option::is_none")]
pub read_only: Option<bool>,
/// List of allowed tool names.
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_names: Option<Vec<String>>,
}
/// Approval policy or filter for MCP tools.
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, ToSchema)]
#[serde(untagged)]
pub enum MCPToolRequireApproval {
/// Specify which of the MCP server's tools require approval. Can be
/// `always`, `never`, or a filter object associated with tools
/// that require approval.
Filter(MCPToolApprovalFilter),
/// Specify a single approval policy for all tools. One of `always` or
/// `never`. When set to `always`, all tools will require approval. When
/// set to `never`, all tools will not require approval.
ApprovalSetting(MCPToolApprovalSetting),
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, ToSchema)]
#[serde(rename_all = "lowercase")]
pub enum MCPToolApprovalSetting {
Always,
Never,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, ToSchema)]
pub struct MCPToolApprovalFilter {
/// A list of tools that always require approval.
#[serde(skip_serializing_if = "Option::is_none")]
pub always: Option<MCPToolFilter>,
/// A list of tools that never require approval.
#[serde(skip_serializing_if = "Option::is_none")]
pub never: Option<MCPToolFilter>,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, ToSchema)]
pub struct MCPListToolsTool {
/// The JSON schema describing the tool's input.
pub input_schema: serde_json::Value,
/// The name of the tool.
pub name: String,
/// Additional annotations about the tool.
#[serde(skip_serializing_if = "Option::is_none")]
pub annotations: Option<serde_json::Value>,
/// The description of the tool.
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
}
// SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
mod impls;
mod mcp_;
pub use mcp_::*;
......@@ -24,6 +24,7 @@ mod file;
mod fine_tuning;
mod image;
mod invites;
pub mod mcp;
mod message;
mod model;
mod moderation;
......@@ -36,6 +37,7 @@ mod projects;
pub mod realtime;
pub mod responses;
mod run;
pub mod shared;
mod step;
mod thread;
mod upload;
......
This diff is collapsed.
// 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;
use crate::types::responses::{IncludeParam, ListOrder};
/// Query parameters for listing conversation items.
#[derive(Clone, Serialize, Default, Debug, Deserialize, Builder, PartialEq, ToSchema)]
#[builder(name = "ListConversationItemsQueryArgs")]
#[builder(pattern = "mutable")]
#[builder(setter(into, strip_option), default)]
#[builder(derive(Debug))]
#[builder(build_fn(error = "OpenAIError"))]
pub struct ListConversationItemsQuery {
/// A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 20.
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
/// The order to return the input items in. Default is `desc`.
#[serde(skip_serializing_if = "Option::is_none")]
pub order: Option<ListOrder>,
/// An item ID to list items after, used in pagination.
#[serde(skip_serializing_if = "Option::is_none")]
pub after: Option<String>,
/// Specify additional output data to include in the model response.
#[serde(skip_serializing_if = "Option::is_none")]
pub include: Option<Vec<IncludeParam>>,
}
/// Query parameters for getting a response.
#[derive(Debug, Serialize, Deserialize, Default, Clone, Builder, PartialEq, ToSchema)]
#[builder(name = "GetResponseQueryArgs")]
#[builder(pattern = "mutable")]
#[builder(setter(into, strip_option), default)]
#[builder(derive(Debug))]
#[builder(build_fn(error = "OpenAIError"))]
pub struct GetResponseQuery {
/// Additional fields to include in the response.
#[serde(skip_serializing_if = "Option::is_none")]
pub include: Option<Vec<String>>,
/// If set to true, the model response data will be streamed to the client as it is generated using server-sent events.
#[serde(skip_serializing_if = "Option::is_none")]
pub stream: Option<bool>,
/// The sequence number of the event after which to start streaming.
#[serde(skip_serializing_if = "Option::is_none")]
pub starting_after: Option<u32>,
/// When true, stream obfuscation will be enabled.
#[serde(skip_serializing_if = "Option::is_none")]
pub include_obfuscation: Option<bool>,
}
/// Query parameters for listing input items.
#[derive(Debug, Serialize, Deserialize, Default, Clone, Builder, PartialEq, ToSchema)]
#[builder(name = "ListInputItemsQueryArgs")]
#[builder(pattern = "mutable")]
#[builder(setter(into, strip_option), default)]
#[builder(derive(Debug))]
#[builder(build_fn(error = "OpenAIError"))]
pub struct ListInputItemsQuery {
/// A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 20.
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
/// The order to return the input items in. Default is `desc`.
#[serde(skip_serializing_if = "Option::is_none")]
pub order: Option<ListOrder>,
/// An item ID to list items after, used in pagination.
#[serde(skip_serializing_if = "Option::is_none")]
pub after: Option<String>,
/// Additional fields to include in the response.
#[serde(skip_serializing_if = "Option::is_none")]
pub include: Option<Vec<String>>,
}
/// Query parameters for getting a conversation item.
#[derive(Debug, Serialize, Deserialize, Default, Clone, Builder, PartialEq, ToSchema)]
#[builder(name = "GetConversationItemQueryArgs")]
#[builder(pattern = "mutable")]
#[builder(setter(into, strip_option), default)]
#[builder(derive(Debug))]
#[builder(build_fn(error = "OpenAIError"))]
pub struct GetConversationItemQuery {
/// Additional fields to include in the response.
#[serde(skip_serializing_if = "Option::is_none")]
pub include: Option<Vec<IncludeParam>>,
}
/// Query parameters for creating conversation items.
#[derive(Debug, Serialize, Deserialize, Default, Clone, Builder, PartialEq, ToSchema)]
#[builder(name = "CreateConversationItemsQueryArgs")]
#[builder(pattern = "mutable")]
#[builder(setter(into, strip_option), default)]
#[builder(derive(Debug))]
#[builder(build_fn(error = "OpenAIError"))]
pub struct CreateConversationItemsQuery {
/// Additional fields to include in the response.
#[serde(skip_serializing_if = "Option::is_none")]
pub include: Option<Vec<IncludeParam>>,
}
// SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
use derive_builder::Builder;
use serde::{Deserialize, Serialize};
use utoipa::ToSchema;
use crate::{
error::OpenAIError,
types::responses::{
AnyItemReference, CodeInterpreterToolCall, ComputerToolCall, CustomToolCall,
CustomToolCallOutput, FileSearchToolCall, ImageGenToolCall, InputFileContent,
InputImageContent, InputItem, InputTextContent, LocalShellToolCall,
LocalShellToolCallOutput, MCPApprovalRequest, MCPApprovalResponse, MCPListTools,
MCPToolCall, OutputTextContent, ReasoningItem, ReasoningTextContent, RefusalContent,
WebSearchToolCall,
},
};
/// Represents a conversation object.
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq, ToSchema)]
pub struct ConversationResource {
/// The unique ID of the conversation.
pub id: String,
/// The object type, which is always `conversation`.
pub object: String,
/// Set of 16 key-value pairs that can be attached to an object.
#[schema(value_type = Object)]
pub metadata: Option<serde_json::Value>,
/// The time at which the conversation was created, measured in seconds since the Unix epoch.
pub created_at: u64,
}
/// Request to create a conversation.
/// openapi spec type: CreateConversationBody
#[derive(Clone, Serialize, Default, Debug, Deserialize, Builder, PartialEq, ToSchema)]
#[builder(name = "CreateConversationRequestArgs")]
#[builder(pattern = "mutable")]
#[builder(setter(into, strip_option), default)]
#[builder(derive(Debug))]
#[builder(build_fn(error = "OpenAIError"))]
pub struct CreateConversationRequest {
/// Set of 16 key-value pairs that can be attached to an object.
#[serde(skip_serializing_if = "Option::is_none")]
#[schema(value_type = Object)]
pub metadata: Option<serde_json::Value>,
/// Initial items to include in the conversation context. You may add up to 20 items at a time.
#[serde(skip_serializing_if = "Option::is_none")]
pub items: Option<Vec<InputItem>>,
}
/// Request to update a conversation.
#[derive(Clone, Serialize, Default, Debug, Deserialize, Builder, PartialEq, ToSchema)]
#[builder(name = "UpdateConversationRequestArgs")]
#[builder(pattern = "mutable")]
#[builder(setter(into, strip_option), default)]
#[builder(derive(Debug))]
#[builder(build_fn(error = "OpenAIError"))]
pub struct UpdateConversationRequest {
/// Set of 16 key-value pairs that can be attached to an object.
#[schema(value_type = Object)]
pub metadata: Option<serde_json::Value>,
}
/// Represents a deleted conversation.
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq, ToSchema)]
pub struct DeleteConversationResponse {
/// The unique ID of the deleted conversation.
pub id: String,
/// The object type, which is always `conversation.deleted`.
pub object: String,
/// Whether the conversation was successfully deleted.
pub deleted: bool,
}
/// Request to create conversation items.
#[derive(Clone, Serialize, Default, Debug, Deserialize, Builder, PartialEq, ToSchema)]
#[builder(name = "CreateConversationItemsRequestArgs")]
#[builder(pattern = "mutable")]
#[builder(setter(into, strip_option), default)]
#[builder(derive(Debug))]
#[builder(build_fn(error = "OpenAIError"))]
pub struct CreateConversationItemsRequest {
/// The items to add to the conversation. You may add up to 20 items at a time.
pub items: Vec<InputItem>,
}
/// A list of Conversation items.
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq, ToSchema)]
pub struct ConversationItemList {
/// The type of object returned, must be `list`.
pub object: String,
/// A list of conversation items.
pub data: Vec<ConversationItem>,
/// Whether there are more items available.
pub has_more: bool,
/// The ID of the first item in the list.
pub first_id: Option<String>,
/// The ID of the last item in the list.
pub last_id: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum MessageStatus {
InProgress,
Incomplete,
Completed,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum MessageRole {
Unknown,
User,
Assistant,
System,
Critic,
Discriminator,
Developer,
Tool,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, ToSchema)]
pub struct TextContent {
pub text: String,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, ToSchema)]
pub struct SummaryTextContent {
/// A summary of the reasoning output from the model so far.
pub text: String,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, ToSchema)]
pub struct ComputerScreenContent {
/// The URL of the screenshot image.
pub image_url: Option<String>,
/// The identifier of an uploaded file that contains the screenshot.
pub file_id: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, ToSchema)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum MessageContent {
InputText(InputTextContent),
OutputText(OutputTextContent),
Text(TextContent),
SummaryText(SummaryTextContent),
ReasoningText(ReasoningTextContent),
Refusal(RefusalContent),
InputImage(InputImageContent),
ComputerScreen(ComputerScreenContent),
InputFile(InputFileContent),
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, ToSchema)]
pub struct Message {
/// The unique ID of the message.
pub id: String,
/// The status of item. One of `in_progress`, `completed`, or `incomplete`. Populated when items are
/// returned via API.
pub status: MessageStatus,
/// The role of the message. One of `unknown`, `user`, `assistant`, `system`, `critic`,
/// `discriminator`, `developer`, or `tool`.
pub role: MessageRole,
/// The content of the message.
pub content: Vec<MessageContent>,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, ToSchema)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ConversationItem {
Message(Message),
FileSearchCall(FileSearchToolCall),
WebSearchCall(WebSearchToolCall),
ImageGenerationCall(ImageGenToolCall),
ComputerCall(ComputerToolCall),
Reasoning(ReasoningItem),
CodeInterpreterCall(CodeInterpreterToolCall),
LocalShellCall(LocalShellToolCall),
LocalShellCallOutput(LocalShellToolCallOutput),
McpListTools(MCPListTools),
McpApprovalRequest(MCPApprovalRequest),
McpApprovalResponse(MCPApprovalResponse),
McpCall(MCPToolCall),
CustomToolCall(CustomToolCall),
CustomToolCallOutput(CustomToolCallOutput),
#[serde(untagged)]
ItemReference(AnyItemReference),
}
/// Additional fields to include in the response.
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum IncludeParam {
/// Include the sources of the web search tool call.
#[serde(rename = "web_search_call.action.sources")]
WebSearchCallActionSources,
/// Include the outputs of python code execution in code interpreter tool call items.
#[serde(rename = "code_interpreter_call.outputs")]
CodeInterpreterCallOutputs,
/// Include image urls from the computer call output.
#[serde(rename = "computer_call_output.output.image_url")]
ComputerCallOutputOutputImageUrl,
/// Include the search results of the file search tool call.
#[serde(rename = "file_search_call.results")]
FileSearchCallResults,
/// Include image urls from the input message.
#[serde(rename = "message.input_image.image_url")]
MessageInputImageImageUrl,
/// Include logprobs with assistant messages.
#[serde(rename = "message.output_text.logprobs")]
MessageOutputTextLogprobs,
/// Include an encrypted version of reasoning tokens in reasoning item outputs.
#[serde(rename = "reasoning.encrypted_content")]
ReasoningEncryptedContent,
}
/// The order to return items in.
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq, ToSchema)]
#[serde(rename_all = "lowercase")]
pub enum ListOrder {
/// Return items in ascending order.
Asc,
/// Return items in descending order.
Desc,
}
// SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
use crate::types::mcp::MCPTool;
use crate::types::responses::{
ApplyPatchToolCallItemParam, ApplyPatchToolCallOutputItemParam, CodeInterpreterContainerAuto,
CodeInterpreterTool, CodeInterpreterToolCall, CodeInterpreterToolContainer,
ComputerCallOutputItemParam, ComputerToolCall, ComputerUsePreviewTool, ConversationParam,
CustomToolCall, CustomToolCallOutput, CustomToolParam, EasyInputContent, EasyInputMessage,
FileSearchTool, FileSearchToolCall, FunctionCallOutput, FunctionCallOutputItemParam,
FunctionShellCallItemParam, FunctionShellCallOutputItemParam, FunctionTool, FunctionToolCall,
ImageGenTool, ImageGenToolCall, InputContent, InputFileContent, InputImageContent, InputItem,
InputMessage, InputParam, InputTextContent, Item, ItemReference, ItemReferenceType,
LocalShellToolCall, LocalShellToolCallOutput, MCPApprovalRequest, MCPApprovalResponse,
MCPListTools, MCPToolCall, MessageItem, MessageType, OutputMessage, OutputMessageContent,
OutputTextContent, Prompt, Reasoning, ReasoningEffort, ReasoningItem, ReasoningSummary,
RefusalContent, ResponseFormatJsonSchema, ResponsePromptVariables, ResponseStreamOptions,
ResponseTextParam, Role, TextResponseFormatConfiguration, Tool, ToolChoiceCustom,
ToolChoiceFunction, ToolChoiceMCP, ToolChoiceOptions, ToolChoiceParam, ToolChoiceTypes,
WebSearchTool, WebSearchToolCall,
};
impl<S: Into<String>> From<S> for EasyInputMessage {
fn from(value: S) -> Self {
EasyInputMessage {
r#type: MessageType::Message,
role: Role::User,
content: EasyInputContent::Text(value.into()),
}
}
}
impl From<EasyInputMessage> for InputItem {
fn from(msg: EasyInputMessage) -> Self {
InputItem::EasyMessage(msg)
}
}
// InputItem ergonomics
impl From<InputMessage> for InputItem {
fn from(msg: InputMessage) -> Self {
InputItem::Item(Item::Message(MessageItem::Input(msg)))
}
}
impl From<Item> for InputItem {
fn from(item: Item) -> Self {
InputItem::Item(item)
}
}
impl From<ItemReference> for InputItem {
fn from(item: ItemReference) -> Self {
InputItem::ItemReference(item)
}
}
// InputParam ergonomics: from InputItem
impl From<InputItem> for InputParam {
fn from(item: InputItem) -> Self {
InputParam::Items(vec![item])
}
}
impl From<Item> for InputParam {
fn from(item: Item) -> Self {
InputParam::Items(vec![InputItem::Item(item)])
}
}
impl From<MessageItem> for InputParam {
fn from(item: MessageItem) -> Self {
InputParam::Items(vec![InputItem::Item(Item::Message(item))])
}
}
impl From<InputMessage> for InputParam {
fn from(msg: InputMessage) -> Self {
InputParam::Items(vec![InputItem::Item(Item::Message(MessageItem::Input(
msg,
)))])
}
}
impl<I: Into<InputItem>> From<Vec<I>> for InputParam {
fn from(items: Vec<I>) -> Self {
InputParam::Items(items.into_iter().map(|item| item.into()).collect())
}
}
impl<I: Into<InputItem>, const N: usize> From<[I; N]> for InputParam {
fn from(items: [I; N]) -> Self {
InputParam::Items(items.into_iter().map(|item| item.into()).collect())
}
}
// InputParam ergonomics: from string "family"
impl From<&str> for InputParam {
fn from(value: &str) -> Self {
InputParam::Text(value.into())
}
}
impl From<String> for InputParam {
fn from(value: String) -> Self {
InputParam::Text(value)
}
}
impl From<&String> for InputParam {
fn from(value: &String) -> Self {
InputParam::Text(value.clone())
}
}
// InputParam ergonomics: from vector family
macro_rules! impl_inputparam_easy_from_collection {
// Vec<T>
($t:ty, $map:expr, $clone:expr) => {
impl From<Vec<$t>> for InputParam {
fn from(values: Vec<$t>) -> Self {
InputParam::Items(
values
.into_iter()
.map(|value| {
InputItem::EasyMessage(EasyInputMessage {
r#type: MessageType::Message,
role: Role::User,
content: EasyInputContent::Text($map(value)),
})
})
.collect(),
)
}
}
// &[T; N]
impl<const N: usize> From<[$t; N]> for InputParam {
fn from(values: [$t; N]) -> Self {
InputParam::Items(
values
.into_iter()
.map(|value| {
InputItem::EasyMessage(EasyInputMessage {
r#type: MessageType::Message,
role: Role::User,
content: EasyInputContent::Text($map(value)),
})
})
.collect(),
)
}
}
// &Vec<T>
impl From<&Vec<$t>> for InputParam {
fn from(values: &Vec<$t>) -> Self {
InputParam::Items(
values
.iter()
.map(|value| {
InputItem::EasyMessage(EasyInputMessage {
r#type: MessageType::Message,
role: Role::User,
content: EasyInputContent::Text($clone(value)),
})
})
.collect(),
)
}
}
};
}
// Apply for &str
impl_inputparam_easy_from_collection!(&str, |v: &str| v.to_string(), |v: &str| v.to_string());
// Apply for String
impl_inputparam_easy_from_collection!(String, |v: String| v, |v: &String| v.clone());
// Apply for &String
impl_inputparam_easy_from_collection!(&String, |v: &String| v.clone(), |v: &String| v.clone());
// ConversationParam ergonomics
impl<S: Into<String>> From<S> for ConversationParam {
fn from(id: S) -> Self {
ConversationParam::ConversationID(id.into())
}
}
// ToolChoiceParam ergonomics
impl From<ToolChoiceOptions> for ToolChoiceParam {
fn from(mode: ToolChoiceOptions) -> Self {
ToolChoiceParam::Mode(mode)
}
}
impl From<ToolChoiceTypes> for ToolChoiceParam {
fn from(tool_type: ToolChoiceTypes) -> Self {
ToolChoiceParam::Hosted(tool_type)
}
}
impl<S: Into<String>> From<S> for ToolChoiceParam {
fn from(name: S) -> Self {
ToolChoiceParam::Function(ToolChoiceFunction { name: name.into() })
}
}
impl From<ToolChoiceFunction> for ToolChoiceParam {
fn from(function: ToolChoiceFunction) -> Self {
ToolChoiceParam::Function(function)
}
}
impl From<ToolChoiceMCP> for ToolChoiceParam {
fn from(mcp: ToolChoiceMCP) -> Self {
ToolChoiceParam::Mcp(mcp)
}
}
impl From<ToolChoiceCustom> for ToolChoiceParam {
fn from(custom: ToolChoiceCustom) -> Self {
ToolChoiceParam::Custom(custom)
}
}
// ResponseTextParam ergonomics
impl From<TextResponseFormatConfiguration> for ResponseTextParam {
fn from(format: TextResponseFormatConfiguration) -> Self {
ResponseTextParam {
format,
verbosity: None,
}
}
}
impl From<ResponseFormatJsonSchema> for ResponseTextParam {
fn from(schema: ResponseFormatJsonSchema) -> Self {
ResponseTextParam {
format: TextResponseFormatConfiguration::JsonSchema(schema),
verbosity: None,
}
}
}
// ResponseStreamOptions ergonomics
impl From<bool> for ResponseStreamOptions {
fn from(include_obfuscation: bool) -> Self {
ResponseStreamOptions {
include_obfuscation: Some(include_obfuscation),
}
}
}
// Reasoning ergonomics
impl From<ReasoningEffort> for Reasoning {
fn from(effort: ReasoningEffort) -> Self {
Reasoning {
effort: Some(effort),
summary: None,
}
}
}
impl From<ReasoningSummary> for Reasoning {
fn from(summary: ReasoningSummary) -> Self {
Reasoning {
effort: None,
summary: Some(summary),
}
}
}
// Prompt ergonomics
impl<S: Into<String>> From<S> for Prompt {
fn from(id: S) -> Self {
Prompt {
id: id.into(),
version: None,
variables: None,
}
}
}
// InputTextContent ergonomics
impl<S: Into<String>> From<S> for InputTextContent {
fn from(text: S) -> Self {
InputTextContent { text: text.into() }
}
}
// InputContent ergonomics
impl From<InputTextContent> for InputContent {
fn from(content: InputTextContent) -> Self {
InputContent::InputText(content)
}
}
impl From<InputImageContent> for InputContent {
fn from(content: InputImageContent) -> Self {
InputContent::InputImage(content)
}
}
impl From<InputFileContent> for InputContent {
fn from(content: InputFileContent) -> Self {
InputContent::InputFile(content)
}
}
impl<S: Into<String>> From<S> for InputContent {
fn from(text: S) -> Self {
InputContent::InputText(InputTextContent { text: text.into() })
}
}
// ResponsePromptVariables ergonomics
impl From<InputContent> for ResponsePromptVariables {
fn from(content: InputContent) -> Self {
ResponsePromptVariables::Content(content)
}
}
impl<S: Into<String>> From<S> for ResponsePromptVariables {
fn from(text: S) -> Self {
ResponsePromptVariables::String(text.into())
}
}
// MessageItem ergonomics
impl From<InputMessage> for MessageItem {
fn from(msg: InputMessage) -> Self {
MessageItem::Input(msg)
}
}
impl From<OutputMessage> for MessageItem {
fn from(msg: OutputMessage) -> Self {
MessageItem::Output(msg)
}
}
// FunctionCallOutput ergonomics
impl From<&str> for FunctionCallOutput {
fn from(text: &str) -> Self {
FunctionCallOutput::Text(text.to_string())
}
}
impl From<String> for FunctionCallOutput {
fn from(text: String) -> Self {
FunctionCallOutput::Text(text)
}
}
impl From<Vec<InputContent>> for FunctionCallOutput {
fn from(content: Vec<InputContent>) -> Self {
FunctionCallOutput::Content(content)
}
}
// RefusalContent ergonomics
impl<S: Into<String>> From<S> for RefusalContent {
fn from(refusal: S) -> Self {
RefusalContent {
refusal: refusal.into(),
}
}
}
// OutputMessageContent ergonomics
impl From<OutputTextContent> for OutputMessageContent {
fn from(content: OutputTextContent) -> Self {
OutputMessageContent::OutputText(content)
}
}
impl From<RefusalContent> for OutputMessageContent {
fn from(content: RefusalContent) -> Self {
OutputMessageContent::Refusal(content)
}
}
// Item ergonomics
impl From<MessageItem> for Item {
fn from(item: MessageItem) -> Self {
Item::Message(item)
}
}
impl From<FileSearchToolCall> for Item {
fn from(call: FileSearchToolCall) -> Self {
Item::FileSearchCall(call)
}
}
impl From<ComputerToolCall> for Item {
fn from(call: ComputerToolCall) -> Self {
Item::ComputerCall(call)
}
}
impl From<ComputerCallOutputItemParam> for Item {
fn from(output: ComputerCallOutputItemParam) -> Self {
Item::ComputerCallOutput(output)
}
}
impl From<WebSearchToolCall> for Item {
fn from(call: WebSearchToolCall) -> Self {
Item::WebSearchCall(call)
}
}
impl From<FunctionToolCall> for Item {
fn from(call: FunctionToolCall) -> Self {
Item::FunctionCall(call)
}
}
impl From<FunctionCallOutputItemParam> for Item {
fn from(output: FunctionCallOutputItemParam) -> Self {
Item::FunctionCallOutput(output)
}
}
impl From<ReasoningItem> for Item {
fn from(item: ReasoningItem) -> Self {
Item::Reasoning(item)
}
}
impl From<ImageGenToolCall> for Item {
fn from(call: ImageGenToolCall) -> Self {
Item::ImageGenerationCall(call)
}
}
impl From<CodeInterpreterToolCall> for Item {
fn from(call: CodeInterpreterToolCall) -> Self {
Item::CodeInterpreterCall(call)
}
}
impl From<LocalShellToolCall> for Item {
fn from(call: LocalShellToolCall) -> Self {
Item::LocalShellCall(call)
}
}
impl From<LocalShellToolCallOutput> for Item {
fn from(output: LocalShellToolCallOutput) -> Self {
Item::LocalShellCallOutput(output)
}
}
impl From<FunctionShellCallItemParam> for Item {
fn from(call: FunctionShellCallItemParam) -> Self {
Item::ShellCall(call)
}
}
impl From<FunctionShellCallOutputItemParam> for Item {
fn from(output: FunctionShellCallOutputItemParam) -> Self {
Item::ShellCallOutput(output)
}
}
impl From<ApplyPatchToolCallItemParam> for Item {
fn from(call: ApplyPatchToolCallItemParam) -> Self {
Item::ApplyPatchCall(call)
}
}
impl From<ApplyPatchToolCallOutputItemParam> for Item {
fn from(output: ApplyPatchToolCallOutputItemParam) -> Self {
Item::ApplyPatchCallOutput(output)
}
}
impl From<MCPListTools> for Item {
fn from(tools: MCPListTools) -> Self {
Item::McpListTools(tools)
}
}
impl From<MCPApprovalRequest> for Item {
fn from(request: MCPApprovalRequest) -> Self {
Item::McpApprovalRequest(request)
}
}
impl From<MCPApprovalResponse> for Item {
fn from(response: MCPApprovalResponse) -> Self {
Item::McpApprovalResponse(response)
}
}
impl From<MCPToolCall> for Item {
fn from(call: MCPToolCall) -> Self {
Item::McpCall(call)
}
}
impl From<CustomToolCallOutput> for Item {
fn from(output: CustomToolCallOutput) -> Self {
Item::CustomToolCallOutput(output)
}
}
impl From<CustomToolCall> for Item {
fn from(call: CustomToolCall) -> Self {
Item::CustomToolCall(call)
}
}
// Tool ergonomics
impl From<FunctionTool> for Tool {
fn from(tool: FunctionTool) -> Self {
Tool::Function(tool)
}
}
impl From<FileSearchTool> for Tool {
fn from(tool: FileSearchTool) -> Self {
Tool::FileSearch(tool)
}
}
impl From<ComputerUsePreviewTool> for Tool {
fn from(tool: ComputerUsePreviewTool) -> Self {
Tool::ComputerUsePreview(tool)
}
}
impl From<WebSearchTool> for Tool {
fn from(tool: WebSearchTool) -> Self {
Tool::WebSearch(tool)
}
}
impl From<MCPTool> for Tool {
fn from(tool: MCPTool) -> Self {
Tool::Mcp(tool)
}
}
impl From<CodeInterpreterTool> for Tool {
fn from(tool: CodeInterpreterTool) -> Self {
Tool::CodeInterpreter(tool)
}
}
impl From<ImageGenTool> for Tool {
fn from(tool: ImageGenTool) -> Self {
Tool::ImageGeneration(tool)
}
}
impl From<CustomToolParam> for Tool {
fn from(tool: CustomToolParam) -> Self {
Tool::Custom(tool)
}
}
// Vec<Tool> ergonomics
impl From<Tool> for Vec<Tool> {
fn from(tool: Tool) -> Self {
vec![tool]
}
}
impl From<FunctionTool> for Vec<Tool> {
fn from(tool: FunctionTool) -> Self {
vec![Tool::Function(tool)]
}
}
impl From<FileSearchTool> for Vec<Tool> {
fn from(tool: FileSearchTool) -> Self {
vec![Tool::FileSearch(tool)]
}
}
impl From<ComputerUsePreviewTool> for Vec<Tool> {
fn from(tool: ComputerUsePreviewTool) -> Self {
vec![Tool::ComputerUsePreview(tool)]
}
}
impl From<WebSearchTool> for Vec<Tool> {
fn from(tool: WebSearchTool) -> Self {
vec![Tool::WebSearch(tool)]
}
}
impl From<MCPTool> for Vec<Tool> {
fn from(tool: MCPTool) -> Self {
vec![Tool::Mcp(tool)]
}
}
impl From<CodeInterpreterTool> for Vec<Tool> {
fn from(tool: CodeInterpreterTool) -> Self {
vec![Tool::CodeInterpreter(tool)]
}
}
impl From<ImageGenTool> for Vec<Tool> {
fn from(tool: ImageGenTool) -> Self {
vec![Tool::ImageGeneration(tool)]
}
}
impl From<CustomToolParam> for Vec<Tool> {
fn from(tool: CustomToolParam) -> Self {
vec![Tool::Custom(tool)]
}
}
// EasyInputContent ergonomics
impl Default for EasyInputContent {
fn default() -> Self {
Self::Text("".to_string())
}
}
impl From<String> for EasyInputContent {
fn from(value: String) -> Self {
Self::Text(value)
}
}
impl From<&str> for EasyInputContent {
fn from(value: &str) -> Self {
Self::Text(value.to_owned())
}
}
// Defaults
impl Default for CodeInterpreterToolContainer {
fn default() -> Self {
Self::Auto(CodeInterpreterContainerAuto::default())
}
}
impl Default for InputParam {
fn default() -> Self {
Self::Text(String::new())
}
}
impl ItemReference {
/// Create a new item reference with the given ID.
pub fn new(id: impl Into<String>) -> Self {
Self {
r#type: Some(ItemReferenceType::ItemReference),
id: id.into(),
}
}
}
// SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
mod api;
mod conversation;
mod impls;
mod response;
mod sdk;
mod stream;
pub use api::*;
pub use conversation::*;
pub use response::*;
pub use stream::*;
// Re-export shared types used by responses
pub use crate::types::shared::ComparisonFilter;
pub use crate::types::shared::ComparisonType;
pub use crate::types::shared::CompoundFilter;
pub use crate::types::shared::CompoundType;
pub use crate::types::shared::CustomGrammarFormatParam;
pub use crate::types::shared::Filter;
pub use crate::types::shared::GrammarSyntax;
pub use crate::types::shared::InputTokenDetails;
pub use crate::types::shared::OutputTokenDetails;
pub use crate::types::shared::ResponseUsage;
// Re-export types from parent module that response.rs imports via `crate::types::responses::`
pub use crate::types::ImageDetail;
pub use crate::types::ReasoningEffort;
pub use crate::types::ResponseFormatJsonSchema;
/// Stream of response events
pub type ResponseStream = std::pin::Pin<
Box<dyn futures::Stream<Item = Result<ResponseStreamEvent, crate::error::OpenAIError>> + Send>,
>;
// Backward-compatible type aliases for Dynamo consumer code migration.
// These map old Dynamo type names to the upstream names.
// TODO: Remove these once all consumer code is fully migrated.
pub type Input = InputParam;
pub type PromptConfig = Prompt;
pub type TextConfig = ResponseTextParam;
pub type TextResponseFormat = TextResponseFormatConfiguration;
This diff is collapsed.
// SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
use crate::types::responses::{OutputItem, OutputMessageContent, Response};
impl Response {
/// SDK-only convenience property that contains the aggregated text output from all
/// `output_text` items in the `output` array, if any are present.
pub fn output_text(&self) -> Option<String> {
let output = self
.output
.iter()
.filter_map(|item| match item {
OutputItem::Message(msg) => Some(
msg.content
.iter()
.filter_map(|content| match content {
OutputMessageContent::OutputText(ot) => Some(ot.text.clone()),
_ => None,
})
.collect::<Vec<String>>(),
),
_ => None,
})
.flatten()
.collect::<Vec<String>>()
.join("");
if output.is_empty() {
None
} else {
Some(output)
}
}
}
This diff is collapsed.
// 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,
}
This diff is collapsed.
This diff is collapsed.
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