Skip to main content

reagent_rs/services/llm/models/
message.rs

1use serde::{Deserialize, Serialize};
2use uuid::Uuid;
3
4use crate::{Role, ToolCall};
5
6#[derive(Serialize, Deserialize, Debug, Clone)]
7pub struct Message {
8    #[serde(default = "new_uuid", skip_serializing)]
9    pub id: String,
10    pub role: Role,
11    #[serde(default, skip_serializing_if = "Option::is_none")]
12    pub content: Option<String>,
13    #[serde(default, skip_serializing_if = "Option::is_none")]
14    pub thinking: Option<String>,
15    #[serde(skip_serializing_if = "Option::is_none")]
16    pub images: Option<Vec<String>>,
17    #[serde(default, skip_serializing_if = "Option::is_none")]
18    pub tool_calls: Option<Vec<ToolCall>>,
19    #[serde(skip_serializing_if = "Option::is_none")]
20    pub tool_call_id: Option<String>,
21}
22
23impl Message {
24    fn new(role: Role, content: String, tool_call_id: Option<String>) -> Self {
25        Self {
26            id: new_uuid(),
27            role,
28            content: Some(content),
29            thinking: None,
30            images: None,
31            tool_calls: None,
32            tool_call_id,
33        }
34    }
35
36    pub fn system<T: Into<String>>(content: T) -> Self {
37        Self::new(Role::System, content.into(), None)
38    }
39    pub fn developer<T: Into<String>>(content: T) -> Self {
40        Self::new(Role::Developer, content.into(), None)
41    }
42    pub fn user<T: Into<String>>(content: T) -> Self {
43        Self::new(Role::User, content.into(), None)
44    }
45    pub fn assistant<T: Into<String>>(content: T) -> Self {
46        Self::new(Role::Assistant, content.into(), None)
47    }
48    pub fn tool<T, S>(content: T, tool_call_id: S) -> Self
49    where
50        T: Into<String>,
51        S: Into<String>,
52    {
53        Self::new(Role::Tool, content.into(), Some(tool_call_id.into()))
54    }
55
56    pub fn with_image<T: Into<String>>(mut self, base64: T) -> Self {
57        match self.images {
58            Some(_) => todo!(),
59            None => self.images = Some(vec![base64.into()]),
60        }
61        self
62    }
63
64    pub fn with_images<T: Into<String>>(mut self, base64: Vec<T>) -> Self {
65        for image in base64 {
66            self = self.with_image(image)
67        }
68        self
69    }
70}
71
72fn new_uuid() -> String {
73    Uuid::new_v4().to_string()
74}