feat: openai decisions types
This commit is contained in:
309
src/openai/decisions.rs
Normal file
309
src/openai/decisions.rs
Normal 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);
|
||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user