use crate::openai::types::{FunctionCall, ToolCall};
use serde::Serialize;
#[derive(Debug, Clone, Serialize, PartialEq, Eq)]
pub struct ModelList {
pub object: &'static str,
pub data: Vec<ModelObject>,
}
#[derive(Debug, Clone, Serialize, PartialEq, Eq)]
pub struct ModelObject {
pub id: String,
pub object: &'static str,
pub owned_by: &'static str,
}
#[derive(Debug, Clone, Serialize, PartialEq)]
pub struct ChatCompletionResponse {
pub id: String,
pub object: &'static str,
pub created: i64,
pub model: String,
pub choices: Vec<ChatChoice>,
#[serde(skip_serializing_if = "Option::is_none")]
pub usage: Option<Usage>,
}
#[derive(Debug, Clone, Serialize, PartialEq)]
pub struct ChatChoice {
pub index: u32,
pub message: AssistantMessage,
pub finish_reason: String,
}
#[derive(Debug, Clone, Serialize, PartialEq)]
pub struct AssistantMessage {
pub role: &'static str,
pub content: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_calls: Option<Vec<ToolCall>>,
}
#[derive(Debug, Clone, Serialize, PartialEq, Eq)]
pub struct Usage {
pub prompt_tokens: u32,
pub completion_tokens: u32,
pub total_tokens: u32,
}
#[derive(Debug, Clone, Serialize, PartialEq)]
pub struct ChatCompletionChunk {
pub id: String,
pub object: &'static str,
pub created: i64,
pub model: String,
pub choices: Vec<ChunkChoice>,
}
#[derive(Debug, Clone, Serialize, PartialEq)]
pub struct ChunkChoice {
pub index: u32,
pub delta: DeltaMessage,
#[serde(skip_serializing_if = "Option::is_none")]
pub finish_reason: Option<String>,
}
#[derive(Debug, Clone, Serialize, PartialEq)]
pub struct DeltaMessage {
#[serde(skip_serializing_if = "Option::is_none")]
pub role: Option<&'static str>,
#[serde(skip_serializing_if = "Option::is_none")]
pub content: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_calls: Option<Vec<ToolCallDelta>>,
}
#[derive(Debug, Clone, Serialize, PartialEq)]
pub struct ToolCallDelta {
pub index: u32,
pub id: String,
#[serde(rename = "type")]
pub kind: &'static str,
pub function: FunctionCall,
}
impl ModelList {
pub fn from_ids(ids: impl IntoIterator<Item = impl AsRef<str>>) -> Self {
Self {
object: "list",
data: ids
.into_iter()
.map(|id| ModelObject {
id: id.as_ref().to_owned(),
object: "model",
owned_by: "openai-codex",
})
.collect(),
}
}
}
pub fn chunk_with_role(id: &str, created: i64, model: &str) -> ChatCompletionChunk {
ChatCompletionChunk {
id: id.to_owned(),
object: "chat.completion.chunk",
created,
model: model.to_owned(),
choices: vec![ChunkChoice {
index: 0,
delta: DeltaMessage {
role: Some("assistant"),
content: None,
tool_calls: None,
},
finish_reason: None,
}],
}
}
pub fn chunk_with_content(
id: &str,
created: i64,
model: &str,
content: String,
) -> ChatCompletionChunk {
ChatCompletionChunk {
id: id.to_owned(),
object: "chat.completion.chunk",
created,
model: model.to_owned(),
choices: vec![ChunkChoice {
index: 0,
delta: DeltaMessage {
role: None,
content: Some(content),
tool_calls: None,
},
finish_reason: None,
}],
}
}
pub fn chunk_with_tool_call(
id: &str,
created: i64,
model: &str,
index: u32,
tool_call: ToolCall,
) -> ChatCompletionChunk {
ChatCompletionChunk {
id: id.to_owned(),
object: "chat.completion.chunk",
created,
model: model.to_owned(),
choices: vec![ChunkChoice {
index: 0,
delta: DeltaMessage {
role: None,
content: None,
tool_calls: Some(vec![ToolCallDelta {
index,
id: tool_call.id,
kind: "function",
function: tool_call.function,
}]),
},
finish_reason: None,
}],
}
}
pub fn chunk_finished(id: &str, created: i64, model: &str, reason: &str) -> ChatCompletionChunk {
ChatCompletionChunk {
id: id.to_owned(),
object: "chat.completion.chunk",
created,
model: model.to_owned(),
choices: vec![ChunkChoice {
index: 0,
delta: DeltaMessage {
role: None,
content: None,
tool_calls: None,
},
finish_reason: Some(reason.to_owned()),
}],
}
}