1use async_trait::async_trait;
9use serde::{Deserialize, Serialize};
10use std::collections::HashMap;
11use std::fmt;
12use std::sync::{Arc, RwLock};
13
14pub mod system_map;
16pub use system_map::*;
17
18pub mod federated_agent;
20pub use federated_agent::FederatedAgent;
21
22pub mod dao_agent;
23pub use dao_agent::DaoAgent;
24
25#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
33pub struct AgentId(pub String);
34
35impl fmt::Display for AgentId {
36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37 write!(f, "{}", self.0)
38 }
39}
40
41#[derive(Debug, Clone)]
43pub enum Observation {
44 Text(String),
46
47 Numeric(String, f64),
49
50 Json(serde_json::Value),
52
53 Custom(String, Vec<u8>),
55
56 SystemState(SystemStateRef),
58}
59
60#[derive(Debug, Clone)]
62pub struct SystemStateRef {
63 pub timestamp: u64,
65 pub state_id: String,
67}
68
69#[derive(Debug, Clone, Serialize, Deserialize)]
71pub enum Action {
72 Recommendation(String),
74
75 Notification(String, String), Json(serde_json::Value),
80
81 Custom(String, Vec<u8>),
83
84 SystemUpdate(SystemUpdateType, serde_json::Value),
86}
87
88#[derive(Debug, Clone, Serialize, Deserialize)]
90pub enum SystemUpdateType {
91 IndexUpdate,
93
94 MapUpdate,
96
97 ConfigUpdate,
99
100 AgentStateUpdate,
102}
103
104#[derive(Debug)]
106pub struct SystemState {
107 pub index: Option<SystemIndex>,
109 pub map: Option<SystemMap>,
111 pub timestamp: u64,
113}
114
115#[derive(Debug, Clone, Serialize, Deserialize)]
117pub struct Feedback {
118 pub score: f32,
120
121 pub description: Option<String>,
123
124 pub source: FeedbackSource,
126}
127
128#[derive(Debug, Clone, Serialize, Deserialize)]
130pub enum FeedbackSource {
131 Human,
133
134 Agent(AgentId),
136
137 System,
139}
140
141#[derive(Debug, Clone, Serialize, Deserialize, Default)]
143pub struct AgentMetrics {
144 pub observations_processed: u64,
146
147 pub actions_taken: u64,
149
150 pub average_feedback: f32,
152
153 pub avg_processing_time_ms: f64,
155
156 pub custom_metrics: HashMap<String, f64>,
158}
159
160#[derive(Debug, thiserror::Error)]
162pub enum AgentError {
163 #[error("Invalid observation: {0}")]
165 InvalidObservation(String),
166
167 #[error("Processing error: {0}")]
169 ProcessingError(String),
170
171 #[error("I/O error: {0}")]
173 IoError(#[from] std::io::Error),
174
175 #[error("Serialization error: {0}")]
177 SerializationError(#[from] serde_json::Error),
178
179 #[error("Internal error: {0}")]
181 InternalError(String),
182
183 #[error("Ethical compliance error: {0}")]
185 EthicalComplianceError(String),
186
187 #[error("System time error: {0}")]
189 SystemTimeError(#[from] std::time::SystemTimeError),
190
191 #[error("Version error: {0}")]
193 VersionError(#[from] semver::Error),
194}
195
196#[async_trait]
198pub trait Agent: Send + Sync {
199 fn id(&self) -> &AgentId;
201
202 fn agent_type(&self) -> &str;
204
205 async fn process(&self, observation: Observation) -> Result<Option<Action>, AgentError>;
207
208 async fn receive_feedback(&mut self, feedback: Feedback) -> Result<(), AgentError>;
210
211 fn metrics(&self) -> AgentMetrics;
213
214 fn ethical_compliance(&self) -> f32 {
216 0.8 }
218
219 async fn read_system_state(&self) -> Result<SystemState, AgentError> {
221 use crate::ml::agents::system_map::{system_index, system_map};
222
223 system_index().read_index().await?;
225 system_map().read_map().await?;
226
227 Ok(SystemState {
229 index: None, map: None, timestamp: std::time::SystemTime::now()
232 .duration_since(std::time::UNIX_EPOCH)
233 .unwrap_or_default()
234 .as_secs(),
235 })
236 }
237
238 async fn update_system_state(&self, updates: &[SystemUpdateType]) -> Result<(), AgentError> {
240 use crate::ml::agents::system_map::{system_index, system_map};
241
242 for update_type in updates {
243 match update_type {
244 SystemUpdateType::IndexUpdate => {
245 system_index().increment_version().await?;
246 }
247 SystemUpdateType::MapUpdate => {
248 system_map().update_map().await?;
249 }
250 _ => {} }
252 }
253 Ok(())
254 }
255}
256
257pub struct AgentSystem {
259 agents: RwLock<HashMap<AgentId, Arc<dyn Agent>>>,
261
262 config: RwLock<AgentSystemConfig>,
264
265 metrics: RwLock<AgentSystemMetrics>,
267}
268
269#[derive(Debug, Clone, Serialize, Deserialize)]
271pub struct AgentSystemConfig {
272 pub enforce_read_first: bool,
274
275 pub min_ethical_compliance: f32,
277
278 pub max_agents: usize,
280
281 pub default_timeout_ms: u64,
283}
284
285impl Default for AgentSystemConfig {
286 fn default() -> Self {
287 Self {
288 enforce_read_first: true, min_ethical_compliance: 0.7,
290 max_agents: 100,
291 default_timeout_ms: 5000,
292 }
293 }
294}
295
296#[derive(Debug, Default, Clone, Serialize, Deserialize)]
298pub struct AgentSystemMetrics {
299 pub total_observations: u64,
301
302 pub total_actions: u64,
304
305 pub total_errors: u64,
307
308 pub avg_processing_time_ms: f64,
310
311 pub uptime_seconds: u64,
313}
314
315impl AgentSystem {
316 pub fn new() -> Self {
318 Self {
319 agents: RwLock::new(HashMap::new()),
320 config: RwLock::new(AgentSystemConfig::default()),
321 metrics: RwLock::new(AgentSystemMetrics::default()),
322 }
323 }
324
325 pub fn with_config(config: AgentSystemConfig) -> Self {
327 Self {
328 agents: RwLock::new(HashMap::new()),
329 config: RwLock::new(config),
330 metrics: RwLock::new(AgentSystemMetrics::default()),
331 }
332 }
333
334 pub async fn register_agent(&self, agent: Arc<dyn Agent>) -> Result<(), AgentError> {
336 let agent_id = agent.id().clone();
337 let config = self.config.read().map_err(|_| {
338 AgentError::InternalError("Failed to acquire read lock on config".to_string())
339 })?;
340
341 let compliance = agent.ethical_compliance();
343 if compliance < config.min_ethical_compliance {
344 return Err(AgentError::EthicalComplianceError(format!(
345 "Agent {} has insufficient ethical compliance score: {} < {}",
346 agent_id, compliance, config.min_ethical_compliance
347 )));
348 }
349
350 let mut agents = self.agents.write().map_err(|_| {
352 AgentError::InternalError("Failed to acquire write lock on agents".to_string())
353 })?;
354
355 if agents.len() >= config.max_agents {
356 return Err(AgentError::ProcessingError(format!(
357 "Maximum number of agents ({}) reached",
358 config.max_agents
359 )));
360 }
361
362 agents.insert(agent_id, agent);
363
364 Ok(())
365 }
366
367 pub async fn unregister_agent(&self, agent_id: &AgentId) -> Result<(), AgentError> {
369 let mut agents = self.agents.write().map_err(|_| {
370 AgentError::InternalError("Failed to acquire write lock on agents".to_string())
371 })?;
372
373 if agents.remove(agent_id).is_none() {
374 return Err(AgentError::ProcessingError(format!(
375 "Agent {agent_id} not found"
376 )));
377 }
378
379 Ok(())
380 }
381
382 pub async fn process_with_agent(
384 &self,
385 agent_id: &AgentId,
386 observation: Observation,
387 ) -> Result<Option<Action>, AgentError> {
388 let (agent, enforce_read_first) = {
390 let agents = self.agents.read().map_err(|_| {
392 AgentError::InternalError("Failed to acquire read lock on agents".to_string())
393 })?;
394
395 let agent = agents
396 .get(agent_id)
397 .ok_or_else(|| AgentError::ProcessingError(format!("Agent {agent_id} not found")))?
398 .clone();
399
400 let config = self.config.read().map_err(|_| {
402 AgentError::InternalError("Failed to acquire read lock on config".to_string())
403 })?;
404
405 (agent, config.enforce_read_first)
406 };
407
408 if enforce_read_first {
410 let _system_state = agent.read_system_state().await?;
412
413 let combined_observation = match observation {
415 Observation::SystemState(_) => observation,
416 _ => Observation::SystemState(SystemStateRef {
417 timestamp: chrono::Utc::now().timestamp() as u64,
418 state_id: format!("state_{}", chrono::Utc::now().timestamp()),
419 }),
420 };
421
422 let start_time = std::time::Instant::now();
423 let result = agent.process(combined_observation).await;
424 let processing_time = start_time.elapsed();
425
426 {
428 let mut metrics = self.metrics.write().map_err(|_| {
429 AgentError::InternalError("Failed to acquire write lock on metrics".to_string())
430 })?;
431
432 metrics.total_observations += 1;
433 if result.is_ok() && result.as_ref().unwrap().is_some() {
434 metrics.total_actions += 1;
435 }
436 if result.is_err() {
437 metrics.total_errors += 1;
438 }
439
440 let current_avg = metrics.avg_processing_time_ms;
442 let current_count = metrics.total_observations;
443 metrics.avg_processing_time_ms = (current_avg * (current_count - 1) as f64
444 + processing_time.as_millis() as f64)
445 / current_count as f64;
446 }
447
448 if let Ok(Some(_)) = &result {
450 agent
451 .update_system_state(&[
452 SystemUpdateType::IndexUpdate,
453 SystemUpdateType::MapUpdate,
454 ])
455 .await?;
456 }
457
458 result
459 } else {
460 agent.process(observation).await
462 }
463 }
464
465 pub async fn broadcast(
467 &self,
468 observation: Observation,
469 ) -> HashMap<AgentId, Result<Option<Action>, AgentError>> {
470 let agent_ids = {
472 let agents = match self.agents.read() {
473 Ok(agents) => agents,
474 Err(_) => return HashMap::new(),
475 };
476
477 agents.keys().cloned().collect::<Vec<_>>()
479 };
480
481 let mut results = HashMap::new();
482
483 for agent_id in agent_ids {
484 let result = self
485 .process_with_agent(&agent_id, observation.clone())
486 .await;
487 results.insert(agent_id, result);
488 }
489
490 results
491 }
492
493 pub fn config(&self) -> Result<AgentSystemConfig, AgentError> {
495 self.config.read().map(|c| c.clone()).map_err(|_| {
496 AgentError::InternalError("Failed to acquire read lock on config".to_string())
497 })
498 }
499
500 pub fn update_config(&self, config: AgentSystemConfig) -> Result<(), AgentError> {
502 let mut current_config = self.config.write().map_err(|_| {
503 AgentError::InternalError("Failed to acquire write lock on config".to_string())
504 })?;
505
506 *current_config = config;
507
508 Ok(())
509 }
510
511 pub fn metrics(&self) -> Result<AgentSystemMetrics, AgentError> {
513 self.metrics.read().map(|m| m.clone()).map_err(|_| {
514 AgentError::InternalError("Failed to acquire read lock on metrics".to_string())
515 })
516 }
517}
518
519impl Default for AgentSystem {
520 fn default() -> Self {
521 Self::new()
522 }
523}
524
525#[allow(dead_code)]
526pub struct MLAgentCoordinator {
527 agents: Vec<Box<dyn Agent>>,
528 }
530
531#[allow(dead_code)]
533pub struct ResourcePool {
534 capacity: usize,
535}
536
537#[allow(dead_code)]
539pub struct HealthMonitor {
540 is_healthy: bool,
541}
542
543#[cfg(test)]
544mod tests {
545 #[tokio::test]
546 async fn test_agent_system_registration() {
547 }
549
550 #[tokio::test]
551 async fn test_read_first_principle() {
552 }
554
555 #[tokio::test]
556 async fn test_ethical_compliance() {
557 }
559}