use serde::{Deserialize, Serialize};
use ts_rs::TS;
use crate::content::ContentPart;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default, TS)]
#[serde(rename_all = "lowercase")]
#[ts(export)]
pub enum Role {
System,
#[default]
User,
Assistant,
Tool,
}
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[serde(untagged)]
#[ts(export)]
pub enum MessageContent {
Text(String),
Parts(Vec<ContentPart>),
}
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[ts(export)]
pub struct ModelMessage {
pub role: Role,
pub content: MessageContent,
}
impl ModelMessage {
pub fn text(role: Role, text: impl Into<String>) -> Self {
Self {
role,
content: MessageContent::Text(text.into()),
}
}
pub fn system(text: impl Into<String>) -> Self {
Self::text(Role::System, text)
}
pub fn user(text: impl Into<String>) -> Self {
Self::text(Role::User, text)
}
pub fn assistant(text: impl Into<String>) -> Self {
Self::text(Role::Assistant, text)
}
#[must_use]
pub fn user_parts(parts: Vec<ContentPart>) -> Self {
Self {
role: Role::User,
content: MessageContent::Parts(parts),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[serde(untagged)]
#[ts(export)]
pub enum ModelPrompt {
Text(String),
Messages(Vec<ModelMessage>),
}
impl From<String> for ModelPrompt {
fn from(s: String) -> Self {
ModelPrompt::Text(s)
}
}
impl From<&str> for ModelPrompt {
fn from(s: &str) -> Self {
ModelPrompt::Text(s.to_string())
}
}
impl From<Vec<ModelMessage>> for ModelPrompt {
fn from(msgs: Vec<ModelMessage>) -> Self {
ModelPrompt::Messages(msgs)
}
}