reagent-rs 0.2.10

A Rust library for building AI agents with MCP, custom tools and skills
Documentation
use serde::{Deserialize, Serialize};
use uuid::Uuid;

use crate::{Role, ToolCall};

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Message {
    #[serde(default = "new_uuid", skip_serializing)]
    pub id: String,
    pub role: Role,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub content: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub thinking: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub images: Option<Vec<String>>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub tool_calls: Option<Vec<ToolCall>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub tool_call_id: Option<String>,
}

impl Message {
    fn new(role: Role, content: String, tool_call_id: Option<String>) -> Self {
        Self {
            id: new_uuid(),
            role,
            content: Some(content),
            thinking: None,
            images: None,
            tool_calls: None,
            tool_call_id,
        }
    }

    pub fn system<T: Into<String>>(content: T) -> Self {
        Self::new(Role::System, content.into(), None)
    }
    pub fn developer<T: Into<String>>(content: T) -> Self {
        Self::new(Role::Developer, content.into(), None)
    }
    pub fn user<T: Into<String>>(content: T) -> Self {
        Self::new(Role::User, content.into(), None)
    }
    pub fn assistant<T: Into<String>>(content: T) -> Self {
        Self::new(Role::Assistant, content.into(), None)
    }
    pub fn tool<T, S>(content: T, tool_call_id: S) -> Self
    where
        T: Into<String>,
        S: Into<String>,
    {
        Self::new(Role::Tool, content.into(), Some(tool_call_id.into()))
    }

    pub fn with_image<T: Into<String>>(mut self, base64: T) -> Self {
        match self.images {
            Some(_) => todo!(),
            None => self.images = Some(vec![base64.into()]),
        }
        self
    }

    pub fn with_images<T: Into<String>>(mut self, base64: Vec<T>) -> Self {
        for image in base64 {
            self = self.with_image(image)
        }
        self
    }
}

fn new_uuid() -> String {
    Uuid::new_v4().to_string()
}