Skip to main content

jules_core/message/
mod.rs

1//! Message module.
2
3use serde::{Deserialize, Serialize};
4
5/// The role of the entity that generated a message.
6#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
7#[serde(rename_all = "lowercase")]
8pub enum Role {
9    /// System messages provide instructions and context to the model.
10    System,
11    /// User messages are the prompts provided by the user.
12    #[default]
13    User,
14    /// Assistant messages are the responses generated by the model.
15    Assistant,
16    /// Tool messages provide the results of a tool call.
17    Tool,
18}
19
20/// A single message in a conversation.
21#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
22pub struct Message {
23    role: Role,
24    content: String,
25    #[cfg(feature = "tools")]
26    #[serde(skip_serializing_if = "Option::is_none")]
27    tool_calls: Option<Vec<crate::tool::ToolCall>>,
28    #[cfg(feature = "tools")]
29    #[serde(skip_serializing_if = "Option::is_none")]
30    tool_call_id: Option<String>,
31}
32
33impl Message {
34    /// Creates a new [`Message`] with the specified role and content.
35    #[must_use]
36    pub fn new(role: Role, content: impl Into<String>) -> Self {
37        Self {
38            role,
39            content: content.into(),
40            #[cfg(feature = "tools")]
41            tool_calls: None,
42            #[cfg(feature = "tools")]
43            tool_call_id: None,
44        }
45    }
46
47    /// Adds tool calls to this message.
48    #[cfg(feature = "tools")]
49    #[must_use]
50    pub fn with_tool_calls(mut self, tool_calls: Vec<crate::tool::ToolCall>) -> Self {
51        self.tool_calls = Some(tool_calls);
52        self
53    }
54
55    /// Sets the tool call ID for this message.
56    #[cfg(feature = "tools")]
57    #[must_use]
58    pub fn with_tool_call_id(mut self, tool_call_id: impl Into<String>) -> Self {
59        self.tool_call_id = Some(tool_call_id.into());
60        self
61    }
62
63    /// Returns the tool calls associated with this message, if any.
64    #[cfg(feature = "tools")]
65    #[must_use]
66    pub fn tool_calls(&self) -> Option<&[crate::tool::ToolCall]> {
67        self.tool_calls.as_deref()
68    }
69
70    /// Returns the tool call ID associated with this message, if any.
71    #[cfg(feature = "tools")]
72    #[must_use]
73    pub fn tool_call_id(&self) -> Option<&str> {
74        self.tool_call_id.as_deref()
75    }
76
77    /// Returns the role of the message.
78    #[must_use]
79    pub fn role(&self) -> &Role {
80        &self.role
81    }
82
83    /// Returns the content of the message.
84    #[must_use]
85    pub fn content(&self) -> &str {
86        &self.content
87    }
88}
89
90#[cfg(test)]
91mod tests {
92    use super::*;
93
94    #[test]
95    fn test_message_creation() {
96        let msg = Message::new(Role::User, "Hello");
97        assert_eq!(*msg.role(), Role::User);
98        assert_eq!(msg.content(), "Hello");
99    }
100}