#chat-bot #ai #agents #langchain #llm #macro-derive

messageforge

messageforge is a lightweight Rust library for creating structured messages in chat systems, including HumanMessage, AiMessage, SystemMessage, and more. It supports easy extensibility through macros, Serde-based serialization, and customizable fields, making it ideal for chatbots, AI agents, and messaging platforms.

13 releases

0.1.13 Oct 5, 2024
0.1.12 Oct 1, 2024
0.1.11 Sep 25, 2024

#71 in Procedural macros


Used in 3 crates

Apache-2.0

83KB
2K SLoC

Messageforge

Messageforge is a Rust library designed to facilitate the creation and management of structured messages for chat-based systems. This library is inspired by and ports the core message functionalities from the LangChain Messages library into Rust, providing an efficient way to build conversational agents, chatbots, and messaging platforms in Rust.

Features

  • Ported from LangChain: messageforge brings core concepts from LangChain's message system to Rust, allowing seamless integration for developers familiar with LangChain.
  • Multiple Message Types: Supports a variety of message types including AiMessage, HumanMessage, SystemMessage, ChatMessage, and ToolMessage.
  • Macro-based Extensibility: Easily define new message types using the BaseMessage derive macro.
  • Serialization & Deserialization: Full support for JSON serialization/deserialization via Serde for easy API integration.
  • Customizable Fields: Add additional fields like metadata, response details, and more to your messages.

Getting Started

To start using messageforge in your project, add the following to your Cargo.toml:

[dependencies]
messageforge = "0.1.0"

Example Usage

Here's a quick guide on how to use the various message types supported by the library.

1. HumanMessage

The HumanMessage type represents a message sent by a human user.

use messageforge::{HumanMessage, BaseMessage};

fn main() {
    let human_msg = HumanMessage::new("Hello, how can I help you?", false);
    
    // Access the message content
    println!("Message content: {}", human_msg.content());

    // Check the message type
    assert_eq!(human_msg.message_type(), MessageType::Human);
    
    // Access additional metadata
    assert_eq!(human_msg.is_example(), false);
}

2. AiMessage

The AiMessage type represents a message generated by an AI or system.

use messageforge::{AiMessage, BaseMessage};

fn main() {
    let ai_msg = AiMessage::new("I am here to assist you.", false);

    // Access the message content
    println!("AI Message content: {}", ai_msg.content());

    // Check the message type
    assert_eq!(ai_msg.message_type(), MessageType::Ai);
}

3. SystemMessage

The SystemMessage type represents messages originating from a system or backend process.

use messageforge::{SystemMessage, BaseMessage};

fn main() {
    let system_msg = SystemMessage::new("System is being rebooted.", false);

    // Access the message content
    println!("System Message content: {}", system_msg.content());

    // Check the message type
    assert_eq!(system_msg.message_type(), MessageType::System);
}

4. ChatMessage

The ChatMessage type represents a general chat message, where the role of the speaker can be arbitrary (e.g., a user, bot, or system).

use messageforge::{ChatMessage, BaseMessage};

fn main() {
    let chat_msg = ChatMessage::new("How are you today?", "user".to_string());

    // Access the message content
    println!("Chat Message content: {}", chat_msg.content());

    // Check the message type
    assert_eq!(chat_msg.message_type(), MessageType::Chat);
    
    // Access the role
    println!("Role: {}", chat_msg.role);
}

5. ToolMessage

The ToolMessage type represents the result of a tool invocation or external process.

use messageforge::{ToolMessage, BaseMessage, ToolStatus};

fn main() {
    let tool_msg = ToolMessage::new(
        "tool_123".to_string(),          // tool_call_id
        Some("artifact_456".to_string()), // artifact (optional)
        ToolStatus::Success,             // status
    );

    println!("Tool Message content: {}", tool_msg.content());
    assert_eq!(tool_msg.message_type(), MessageType::Tool);
    
    println!("Tool Call ID: {}", tool_msg.tool_call_id);
    if let Some(artifact) = &tool_msg.artifact {
        println!("Artifact: {}", artifact);
    }

    println!("Status: {:?}", tool_msg.status);
}

Contributing

We welcome contributions from the community! If you're interested in contributing to messageforge, please follow these steps:

  1. Fork the Repository: Create a personal fork of the repository on GitHub.
  2. Clone Your Fork: Clone your fork locally to start working on changes.
    git clone https://github.com/yourusername/messageforge.git
    cd messageforge
    
  3. Create a Branch: Create a new branch to make your changes.
    git checkout -b feature/your-feature-name
    
  4. Make Your Changes: Make the necessary changes and ensure the code is properly formatted.
  5. Test Your Changes: Run tests to ensure your changes work as expected.
    cargo test
    
  6. Submit a Pull Request: Once your changes are ready, submit a pull request to the main repository.

Guidelines

  • Follow the Rust community's style guidelines and make sure your code is properly formatted.
  • Add tests for any new functionality.
  • Ensure all tests pass before submitting a PR.

License

This project is licensed under the MIT License. See the LICENSE file for details.


Acknowledgments

messageforge is based on the core messaging concepts from the LangChain Messages library. Special thanks to the LangChain team for providing the original inspiration and structure for this library.


Contact

If you have any questions or need further assistance, feel free to open an issue or contact us via GitHub.


Happy coding with messageforge!


Dependencies

~0.7–1.6MB
~34K SLoC