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 126 127 128 129 130
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(PartialEq, Eq, 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>,
pub images: Option<Vec<String>>,
}
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,
images: 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,
images: 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,
images: 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,
images: 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())
}
pub fn messages_to_string(messages: &[Message]) -> String {
messages
.iter()
.map(|m| format!("{:?}: {}", m.message_type, m.content))
.collect::<Vec<String>>()
.join("\n")
}
}