feat: openai decisions types

This commit is contained in:
2026-10-09 02:28:26 -04:00
parent f2108ae35a
commit 0a111172f5
2 changed files with 310 additions and 0 deletions

309
src/openai/decisions.rs Normal file
View File

@@ -0,0 +1,309 @@
use serde::{Deserialize, Serialize};
/// Represents the main request to the Decisions API
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct DecisionRequest<Model> {
/// The model that evaluates the request. Currently, only `gpt-6-luna` is supported.
pub model: Model,
/// The text or images to evaluate for every question.
/// Can be a simple string or an array of user messages containing text and images.
#[serde(flatten)]
pub input: DecisionInput,
/// Array of questions to evaluate against the input
#[serde(rename = "questions")]
pub questions: Vec<DecisionQuestion>,
}
/// Represents the input to be evaluated, which can be either a string or an array of messages
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum DecisionInput {
/// Simple text input
Text(String),
/// Array of user messages containing text and images
Messages(Vec<DecisionInputMessage>),
}
/// Represents a message in the input, typically from a user
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct DecisionInputMessage {
/// The role of the message sender (always "user" for decisions)
pub role: String,
/// The content of the message, which can be a string or an array of parts
#[serde(flatten)]
pub content: DecisionInputContent,
}
/// Represents the content of a message, which can be a string or an array of parts
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum DecisionInputContent {
/// Simple text content
Text(String),
/// Array of text and image parts
Parts(Vec<DecisionInputPart>),
}
/// Represents a part of a message, which can be text or an image
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(tag = "type")]
pub enum DecisionInputPart {
/// Text part of a message
#[serde(rename = "input_text")]
Text {
/// The text content
text: String,
},
/// Image part of a message
#[serde(rename = "input_image")]
Image {
/// The image URL (base64 data URL or HTTP(S) URL)
image_url: String,
/// Optional detail level for the image
#[serde(skip_serializing_if = "Option::is_none")]
detail: Option<ImageDetail>,
},
}
/// Represents the detail level for an image
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum ImageDetail {
/// Low detail
Low,
/// High detail
High,
/// Auto detail (default)
Auto,
/// Original detail
Original,
}
/// Represents a question in the Decisions API
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(tag = "type", rename_all = "lowercase")]
pub enum DecisionQuestion {
/// A predicate question checks a condition
Predicate(PredicateQuestion),
/// A choice question selects from fixed options
Choice(ChoiceQuestion),
/// A score question evaluates against ordered levels
Score(ScoreQuestion),
}
/// A predicate question checks a condition and returns a probability
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct PredicateQuestion {
/// Optional name to identify the question in the response
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
/// Instructions for evaluating the condition
pub instructions: String,
}
/// A choice question selects from fixed options
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ChoiceQuestion {
/// Optional name to identify the question in the response
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
/// Instructions for making the choice
pub instructions: String,
/// Array of available choices
pub choices: Vec<ChoiceOption>,
}
/// Represents a single choice option
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ChoiceOption {
/// The value of the choice
pub value: Choice,
/// Optional description of when this choice applies
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
}
/// A score question evaluates against ordered levels
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ScoreQuestion {
/// Optional name to identify the question in the response
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
/// Instructions for scoring
pub instructions: String,
/// Array of ordered levels for scoring
pub levels: Vec<ScoreLevel>,
}
/// Represents a single score level
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ScoreLevel {
/// The label for this level
pub label: String,
/// Optional description of this level
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
}
/// Represents the response from the Decisions API
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct DecisionResponse<Model> {
/// Array of answers to the questions
pub answers: Vec<DecisionAnswer>,
/// The model used for the decision
pub model: Model,
/// Token usage information
pub usage: TokenUsage,
}
/// Represents an answer to a question
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(tag = "type", rename_all = "lowercase")]
pub enum DecisionAnswer {
/// Answer to a predicate question
Predicate(PredicateAnswer),
/// Answer to a choice question
Choice(ChoiceAnswer),
/// Answer to a score question
Score(ScoreAnswer),
/// The model refused to answer this question
Refusal(RefusalAnswer),
}
/// Answer to a predicate question
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct PredicateAnswer {
/// Optional name of the question
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
/// Probability that the condition is true (0.0 to 1.0)
pub probability: f64,
}
/// Choice values are typed: a string and a boolean with the same text are distinct
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum Choice {
/// String
String(String),
/// Boolean
Boolean(bool),
}
/// Answer to a choice question
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ChoiceAnswer {
/// Optional name of the question
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
/// The selected choice value
pub choice: Choice,
/// Confidence score (0.0 to 1.0)
pub confidence: f64,
/// Probabilities for each choice option
pub probabilities: Vec<ChoiceProbability>,
}
/// Represents the probability distribution for a choice answer
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ChoiceProbability {
/// The choice value
pub value: Choice,
/// Probability of this choice (0.0 to 1.0)
pub probability: f64,
}
/// Answer to a score question
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ScoreAnswer {
/// Optional name of the question
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
/// The computed score (can be between level indices)
pub score: f64,
/// Confidence score (0.0 to 1.0)
pub confidence: f64,
/// Probabilities for each score level
pub probabilities: Vec<ScoreProbability>,
}
/// Represents the probability distribution for a score answer
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ScoreProbability {
/// The level index
pub value: i32,
/// The level label
pub label: String,
/// Probability of this level (0.0 to 1.0)
pub probability: f64,
}
/// Answer indicating the model refused to answer a question
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct RefusalAnswer {
/// Optional name of the question
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
}
/// Represents token usage information
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct TokenUsage {
/// Total number of input tokens
pub input_tokens: i32,
/// Details about input tokens
pub input_tokens_details: TokenUsageDetails,
/// Total number of output tokens
pub output_tokens: i32,
/// Details about output tokens
pub output_tokens_details: OutputTokenDetails,
/// Total number of tokens (input + output)
pub total_tokens: i32,
}
/// Represents details about input tokens
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct TokenUsageDetails {
/// Number of tokens written to cache
pub cache_write_tokens: i32,
/// Number of tokens read from cache
pub cached_tokens: i32,
}
/// Represents details about output tokens
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct OutputTokenDetails {
/// Number of reasoning tokens used
pub reasoning_tokens: i32,
}
/// Optional safety identifier provided by the caller
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct SafetyIdentifier(pub String);

View File

@@ -1,3 +1,4 @@
pub mod chat; pub mod chat;
pub mod decisions;
pub mod embeddings; pub mod embeddings;
pub mod models; pub mod models;