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