use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum InputItem {
#[serde(rename = "message")]
Message { role: String, content: String },
#[serde(rename = "tool_result")]
ToolResult {
tool_call_id: String,
content: String,
},
}
impl InputItem {
pub fn user_message(content: impl Into<String>) -> Self {
InputItem::Message {
role: "user".to_string(),
content: content.into(),
}
}
pub fn assistant_message(content: impl Into<String>) -> Self {
InputItem::Message {
role: "assistant".to_string(),
content: content.into(),
}
}
pub fn system_message(content: impl Into<String>) -> Self {
InputItem::Message {
role: "system".to_string(),
content: content.into(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum RunItem {
#[serde(rename = "message")]
Message { role: String, content: String },
#[serde(rename = "tool_call")]
ToolCall {
id: String,
name: String,
arguments: String,
},
#[serde(rename = "tool_result")]
ToolResult {
tool_call_id: String,
content: String,
},
}
impl RunItem {
pub fn to_input_item(&self) -> InputItem {
match self {
RunItem::Message { role, content } => InputItem::Message {
role: role.clone(),
content: content.clone(),
},
RunItem::ToolResult {
tool_call_id,
content,
} => InputItem::ToolResult {
tool_call_id: tool_call_id.clone(),
content: content.clone(),
},
RunItem::ToolCall { .. } => {
InputItem::assistant_message("")
}
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ModelResponse {
pub output: Vec<RunItem>,
pub usage: Usage,
pub id: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct Usage {
pub requests: usize,
pub input_tokens: usize,
pub output_tokens: usize,
pub total_tokens: usize,
}
impl Usage {
pub fn add(&mut self, other: &Usage) {
self.requests += other.requests;
self.input_tokens += other.input_tokens;
self.output_tokens += other.output_tokens;
self.total_tokens += other.total_tokens;
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ModelSettings {
#[serde(skip_serializing_if = "Option::is_none")]
pub temperature: Option<f32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub top_p: Option<f32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_tokens: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub stop: Option<Vec<String>>,
}
impl Default for ModelSettings {
fn default() -> Self {
Self {
temperature: None,
top_p: None,
max_tokens: None,
stop: None,
}
}
}