ceylon_core/message.rs
1//! Message types for inter-agent communication.
2
3use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5use uuid::Uuid;
6
7/// A message for inter-agent communication.
8///
9/// Messages carry binary payloads between agents in a mesh.
10///
11/// # Example
12///
13/// ```rust
14/// use ceylon_core::Message;
15///
16/// // Create a message
17/// let msg = Message::new("greeting", b"Hello!".to_vec(), "sender-agent");
18///
19/// // Access message properties
20/// println!("Topic: {}", msg.topic);
21/// println!("From: {}", msg.sender);
22/// ```
23#[derive(Debug, Clone, Serialize, Deserialize)]
24pub struct Message {
25 /// Unique message identifier (auto-generated UUID).
26 pub id: String,
27 /// Message topic/type for routing or categorization.
28 pub topic: String,
29 /// Binary payload data.
30 pub payload: Vec<u8>,
31 /// Name of the sending agent.
32 pub sender: String,
33 /// Arbitrary metadata key-value pairs.
34 pub metadata: HashMap<String, String>,
35 /// Creation timestamp in microseconds since epoch.
36 pub created_at: i64,
37}
38
39impl Message {
40 /// Create a new message.
41 ///
42 /// # Arguments
43 /// * `topic` - Message topic for routing
44 /// * `payload` - Binary payload
45 /// * `sender` - Name of the sending agent
46 pub fn new(topic: impl Into<String>, payload: Vec<u8>, sender: impl Into<String>) -> Self {
47 Self {
48 id: Uuid::new_v4().to_string(),
49 topic: topic.into(),
50 payload,
51 sender: sender.into(),
52 metadata: HashMap::new(),
53 created_at: chrono::Utc::now().timestamp_micros(),
54 }
55 }
56
57 /// Get the correlation ID for request/response tracking.
58 pub fn correlation_id(&self) -> Option<String> {
59 self.metadata.get("correlation_id").cloned()
60 }
61
62 /// Set a correlation ID for request/response tracking.
63 pub fn set_correlation_id(&mut self, id: &str) {
64 self.metadata
65 .insert("correlation_id".to_string(), id.to_string());
66 }
67}
68
69/// A simple string-based message for text communication.
70///
71/// Use this for simpler text-based interactions instead of binary [`Message`].
72#[derive(Debug, Clone, Serialize, Deserialize)]
73pub struct GenericMessage {
74 /// The message content.
75 pub content: String,
76 /// Optional metadata.
77 pub metadata: std::collections::HashMap<String, String>,
78}
79
80impl GenericMessage {
81 /// Create a new generic message.
82 pub fn new(content: impl Into<String>) -> Self {
83 Self {
84 content: content.into(),
85 metadata: std::collections::HashMap::new(),
86 }
87 }
88}
89
90/// Response to a [`GenericMessage`].
91#[derive(Debug, Clone, Serialize, Deserialize)]
92pub struct GenericResponse {
93 /// The response content.
94 pub content: String,
95}
96
97impl GenericResponse {
98 /// Create a new generic response.
99 pub fn new(content: impl Into<String>) -> Self {
100 Self {
101 content: content.into(),
102 }
103 }
104}
105
106/// Envelope wrapping a message with routing information.
107///
108/// Used internally for message delivery across mesh boundaries.
109#[derive(Debug, Clone, Serialize, Deserialize)]
110pub struct Envelope {
111 /// The wrapped message.
112 pub message: Message,
113 /// Target agent name (within a node).
114 pub target_agent: Option<String>,
115 /// Target node ID (for distributed meshes).
116 pub target_node: Option<String>,
117}