langchain_rust/schemas/
messages.rs

1use serde::Deserialize;
2use serde::Serialize;
3use serde_json::Value;
4
5/// Enum `MessageType` represents the type of a message.
6/// It can be a `SystemMessage`, `AIMessage`, or `HumanMessage`.
7///
8/// # Usage
9/// ```rust,ignore
10/// let system_message_type = MessageType::SystemMessage;
11/// let ai_message_type = MessageType::AIMessage;
12/// let human_message_type = MessageType::HumanMessage;
13/// ```
14#[derive(PartialEq, Eq, Serialize, Deserialize, Debug, Clone)]
15pub enum MessageType {
16    #[serde(rename = "system")]
17    SystemMessage,
18    #[serde(rename = "ai")]
19    AIMessage,
20    #[serde(rename = "human")]
21    HumanMessage,
22    #[serde(rename = "tool")]
23    ToolMessage,
24}
25
26impl Default for MessageType {
27    fn default() -> Self {
28        Self::SystemMessage
29    }
30}
31
32impl MessageType {
33    pub fn to_string(&self) -> String {
34        match self {
35            MessageType::SystemMessage => "system".to_owned(),
36            MessageType::AIMessage => "ai".to_owned(),
37            MessageType::HumanMessage => "human".to_owned(),
38            MessageType::ToolMessage => "tool".to_owned(),
39        }
40    }
41}
42
43/// Struct `ImageContent` represents an image provided to an LLM.
44#[derive(Serialize, Deserialize, Debug, Default, Clone)]
45pub struct ImageContent {
46    pub image_url: String,
47    pub detail: Option<String>,
48}
49
50impl<S: AsRef<str>> From<S> for ImageContent {
51    fn from(image_url: S) -> Self {
52        ImageContent {
53            image_url: image_url.as_ref().into(),
54            detail: None,
55        }
56    }
57}
58
59/// Struct `Message` represents a message with its content and type.
60///
61/// # Usage
62/// ```rust,ignore
63/// let human_message = Message::new_human_message("Hello");
64/// let system_message = Message::new_system_message("System Alert");
65/// let ai_message = Message::new_ai_message("AI Response");
66/// ```
67#[derive(Serialize, Deserialize, Debug, Default, Clone)]
68pub struct Message {
69    pub content: String,
70    pub message_type: MessageType,
71    pub id: Option<String>,
72    pub tool_calls: Option<Value>,
73    pub images: Option<Vec<ImageContent>>,
74}
75
76impl Message {
77    // Function to create a new Human message with a generic type that implements Display
78    pub fn new_human_message<T: std::fmt::Display>(content: T) -> Self {
79        Message {
80            content: content.to_string(),
81            message_type: MessageType::HumanMessage,
82            id: None,
83            tool_calls: None,
84            images: None,
85        }
86    }
87
88    pub fn new_human_message_with_images<T: Into<ImageContent>>(images: Vec<T>) -> Self {
89        Message {
90            content: String::default(),
91            message_type: MessageType::HumanMessage,
92            id: None,
93            tool_calls: None,
94            images: Some(images.into_iter().map(|i| i.into()).collect()),
95        }
96    }
97
98    // Function to create a new System message with a generic type that implements Display
99    pub fn new_system_message<T: std::fmt::Display>(content: T) -> Self {
100        Message {
101            content: content.to_string(),
102            message_type: MessageType::SystemMessage,
103            id: None,
104            tool_calls: None,
105            images: None,
106        }
107    }
108
109    // Function to create a new AI message with a generic type that implements Display
110    pub fn new_ai_message<T: std::fmt::Display>(content: T) -> Self {
111        Message {
112            content: content.to_string(),
113            message_type: MessageType::AIMessage,
114            id: None,
115            tool_calls: None,
116            images: None,
117        }
118    }
119
120    // Function to create a new Tool message with a generic type that implements Display
121    pub fn new_tool_message<T: std::fmt::Display, S: Into<String>>(content: T, id: S) -> Self {
122        Message {
123            content: content.to_string(),
124            message_type: MessageType::ToolMessage,
125            id: Some(id.into()),
126            tool_calls: None,
127            images: None,
128        }
129    }
130
131    /// Sets the tool calls for the OpenAI-like API call.
132    ///
133    /// Use this method when you need to specify tool calls in the configuration.
134    /// This is particularly useful in scenarios where interactions with specific
135    /// tools are required for operation.
136    ///
137    /// # Arguments
138    ///
139    /// * `tool_calls` - A `serde_json::Value` representing the tool call configurations.
140    pub fn with_tool_calls(mut self, tool_calls: Value) -> Self {
141        self.tool_calls = Some(tool_calls);
142        self
143    }
144
145    pub fn messages_from_value(value: &Value) -> Result<Vec<Message>, serde_json::error::Error> {
146        serde_json::from_value(value.clone())
147    }
148
149    pub fn messages_to_string(messages: &[Message]) -> String {
150        messages
151            .iter()
152            .map(|m| format!("{:?}: {}", m.message_type, m.content))
153            .collect::<Vec<String>>()
154            .join("\n")
155    }
156}