1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3use std::time::{SystemTime, UNIX_EPOCH};
4
5#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
7pub struct I2IMessage {
8 pub sender: String,
10 pub recipient: String,
12 pub msg_type: String,
14 pub content: String,
16 #[serde(default = "default_priority")]
18 pub priority: String,
19 #[serde(default = "current_timestamp")]
21 pub timestamp: f64,
22 #[serde(default = "HashMap::new")]
24 pub metadata: HashMap<String, serde_json::Value>,
25}
26
27fn default_priority() -> String {
28 "P2".to_string()
29}
30
31fn current_timestamp() -> f64 {
32 SystemTime::now()
33 .duration_since(UNIX_EPOCH)
34 .unwrap_or_default()
35 .as_secs_f64()
36}
37
38impl I2IMessage {
39 pub fn new(
41 sender: impl Into<String>,
42 recipient: impl Into<String>,
43 msg_type: impl Into<String>,
44 content: impl Into<String>,
45 ) -> Self {
46 Self {
47 sender: sender.into(),
48 recipient: recipient.into(),
49 msg_type: msg_type.into(),
50 content: content.into(),
51 priority: default_priority(),
52 timestamp: current_timestamp(),
53 metadata: HashMap::new(),
54 }
55 }
56
57 pub fn with_priority(
59 sender: impl Into<String>,
60 recipient: impl Into<String>,
61 msg_type: impl Into<String>,
62 content: impl Into<String>,
63 priority: impl Into<String>,
64 ) -> Self {
65 Self {
66 sender: sender.into(),
67 recipient: recipient.into(),
68 msg_type: msg_type.into(),
69 content: content.into(),
70 priority: priority.into(),
71 timestamp: current_timestamp(),
72 metadata: HashMap::new(),
73 }
74 }
75}
76
77pub struct I2IProtocol;
79
80impl I2IProtocol {
81 pub fn format_message(
83 sender: impl Into<String>,
84 recipient: impl Into<String>,
85 msg_type: impl Into<String>,
86 content: impl Into<String>,
87 priority: impl Into<String>,
88 ) -> I2IMessage {
89 I2IMessage::with_priority(sender, recipient, msg_type, content, priority)
90 }
91
92 pub fn parse_message(raw: &str) -> Result<I2IMessage, String> {
97 if !raw.starts_with("[I2I:") {
98 return Err("Message must start with '[I2I:'".to_string());
99 }
100
101 let type_end = raw[5..].find(']').ok_or("Missing closing ']' for message type")? + 5;
102 let msg_type = raw[5..type_end].trim().to_string();
103 let remainder = raw[type_end + 1..].trim();
104
105 let arrow = remainder.find("->").ok_or("Missing '->' separator")?;
106 let sender = remainder[..arrow].trim().to_string();
107 let after_arrow = remainder[arrow + 2..].trim();
108
109 let em_dash = after_arrow.find('—');
110 let (recipient, content) = match em_dash {
111 Some(idx) => (
112 after_arrow[..idx].trim().to_string(),
113 after_arrow[idx + 1..].trim().to_string(),
114 ),
115 None => {
116 let fallback = after_arrow.find("- ").ok_or("Missing '—' content separator")?;
117 (
118 after_arrow[..fallback].trim().to_string(),
119 after_arrow[fallback + 1..].trim().to_string(),
120 )
121 }
122 };
123
124 Ok(I2IMessage {
125 sender,
126 recipient,
127 msg_type,
128 content,
129 priority: default_priority(),
130 timestamp: current_timestamp(),
131 metadata: HashMap::new(),
132 })
133 }
134
135 pub fn serialize(message: &I2IMessage) -> String {
137 serde_json::to_string(message).unwrap_or_default()
138 }
139
140 pub fn deserialize(raw: &str) -> Result<I2IMessage, String> {
145 let payload: serde_json::Value = serde_json::from_str(raw).map_err(|e| format!("Invalid JSON: {e}"))?;
146
147 let required = ["sender", "recipient", "msg_type", "content"];
148 for key in &required {
149 if payload.get(key).is_none() {
150 return Err(format!("Missing required field: {key}"));
151 }
152 }
153
154 let message: I2IMessage = serde_json::from_value(payload)
155 .map_err(|e| format!("Invalid message structure: {e}"))?;
156 Ok(message)
157 }
158
159 pub fn validate(message: &I2IMessage) -> bool {
163 !message.sender.trim().is_empty()
164 && !message.recipient.trim().is_empty()
165 && !message.msg_type.trim().is_empty()
166 && !message.content.trim().is_empty()
167 }
168
169 pub fn priority_gate(message: &I2IMessage, min_priority: &str) -> bool {
173 let rank = |p: &str| match p {
174 "P0" => 0,
175 "P1" => 1,
176 "P2" => 2,
177 _ => 99,
178 };
179 rank(&message.priority) <= rank(min_priority)
180 }
181}
182
183#[derive(Debug, Clone, Default)]
187pub struct TrustRouter {
188 trust: HashMap<String, f64>,
189}
190
191impl TrustRouter {
192 pub fn new() -> Self {
194 Self {
195 trust: HashMap::new(),
196 }
197 }
198
199 pub fn add_trust(&mut self, agent_id: impl Into<String>, trust_level: f64) -> Result<(), String> {
204 if !(0.0..=1.0).contains(&trust_level) {
205 return Err("trust_level must be between 0.0 and 1.0".to_string());
206 }
207 self.trust.insert(agent_id.into(), trust_level);
208 Ok(())
209 }
210
211 pub fn get_trust(&self, agent_id: &str) -> f64 {
215 self.trust.get(agent_id).copied().unwrap_or(0.0)
216 }
217
218 pub fn route(&self, _message: &I2IMessage, available_agents: &[String]) -> Option<String> {
223 if available_agents.is_empty() {
224 return None;
225 }
226
227 let mut best_agent: Option<String> = None;
228 let mut best_score = -1.0;
229
230 for agent in available_agents {
231 let score = self.get_trust(agent);
232 if score > best_score {
233 best_score = score;
234 best_agent = Some(agent.clone());
235 }
236 }
237
238 if best_score <= 0.0 {
239 return None;
240 }
241
242 best_agent
243 }
244
245 pub fn is_trusted(&self, agent_id: &str, min_trust: f64) -> bool {
247 self.get_trust(agent_id) >= min_trust
248 }
249
250 pub fn stats(&self) -> HashMap<String, serde_json::Value> {
252 let mut result = HashMap::new();
253 if self.trust.is_empty() {
254 result.insert("count".to_string(), serde_json::json!(0));
255 result.insert("average_trust".to_string(), serde_json::json!(0.0));
256 result.insert("max_trust".to_string(), serde_json::json!(0.0));
257 result.insert("min_trust".to_string(), serde_json::json!(0.0));
258 return result;
259 }
260
261 let values: Vec<f64> = self.trust.values().copied().collect();
262 let count = values.len() as i64;
263 let sum: f64 = values.iter().sum();
264 let avg = sum / values.len() as f64;
265 let max = values.iter().fold(f64::NEG_INFINITY, |a, &b| a.max(b));
266 let min = values.iter().fold(f64::INFINITY, |a, &b| a.min(b));
267
268 result.insert("count".to_string(), serde_json::json!(count));
269 result.insert("average_trust".to_string(), serde_json::json!(avg));
270 result.insert("max_trust".to_string(), serde_json::json!(max));
271 result.insert("min_trust".to_string(), serde_json::json!(min));
272 result
273 }
274}