ambi 0.1.4

A flexible, multi-backend, customizable AI agent framework, entirely based on Rust.
Documentation
use serde::{Deserialize, Serialize};

#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
#[serde(tag = "type", rename_all = "lowercase")]
pub enum ContentPart {
    Text { text: String },
    Image { url: String },
}

#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
pub enum Message {
    System { content: String },
    User { content: Vec<ContentPart> },
    Tool { content: String },
    Assistant { content: String },
}

impl Message {
    pub fn text_len(&self) -> usize {
        match self {
            Message::System { content } => content.len(),
            Message::User { content } => content
                .iter()
                .map(|p| match p {
                    ContentPart::Text { text } => text.len(),
                    _ => 0,
                })
                .sum(),
            Message::Tool { content } => content.len(),
            Message::Assistant { content } => content.len(),
        }
    }
    
    pub fn write_text_to(&self, buf: &mut String) {
        match self {
            Message::System { content } => buf.push_str(content),
            Message::User { content } => {
                for part in content {
                    if let ContentPart::Text { text: t } = part {
                        buf.push_str(t);
                    }
                }
            }
            Message::Tool { content } => buf.push_str(content),
            Message::Assistant { content } => buf.push_str(content),
        }
    }
    
    pub fn user_text(text: &str) -> Self {
        Self::User {
            content: vec![ContentPart::Text {
                text: text.to_string(),
            }],
        }
    }

    pub fn get_text_content(&self) -> String {
        match self {
            Message::System { content } => content.clone(),
            Message::User { content } => {
                let mut text = String::new();
                for part in content {
                    if let ContentPart::Text { text: t } = part {
                        text.push_str(t);
                    }
                }
                text
            }
            Message::Tool { content } => content.clone(),
            Message::Assistant { content } => content.clone(),
        }
    }
}