feagi_services/traits/
agent_service.rs1use async_trait::async_trait;
11use serde::{Deserialize, Serialize};
12use std::collections::HashMap;
13
14#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
15#[serde(rename_all = "snake_case")]
16pub enum ManualStimulationMode {
17 #[default]
18 Candidate,
19 ForceFire,
20}
21
22pub type AgentResult<T> = Result<T, AgentError>;
24
25#[derive(Debug, thiserror::Error)]
27pub enum AgentError {
28 #[error("Agent not found: {0}")]
29 NotFound(String),
30
31 #[error("Registration service unavailable: {0}")]
32 ServiceUnavailable(String),
33
34 #[error("Registration failed: {0}")]
35 RegistrationFailed(String),
36
37 #[error("Invalid agent data: {0}")]
38 InvalidData(String),
39
40 #[error("Internal error: {0}")]
41 Internal(String),
42}
43
44#[derive(Debug, Clone, Serialize, Deserialize)]
46pub struct AgentRegistration {
47 pub agent_id: String,
48 pub agent_type: String,
49 pub agent_data_port: u16,
50 pub agent_version: String,
51 pub controller_version: String,
52 pub agent_ip: Option<String>,
53 pub capabilities: HashMap<String, serde_json::Value>,
54 pub metadata: Option<HashMap<String, serde_json::Value>>,
55 #[serde(skip_serializing_if = "Option::is_none")]
56 pub chosen_transport: Option<String>, }
58
59#[derive(Debug, Clone, Serialize, Deserialize)]
61pub struct TransportConfig {
62 pub transport_type: String,
63 pub enabled: bool,
64 pub ports: HashMap<String, u16>,
65 pub host: String,
66}
67
68#[derive(Debug, Clone, Serialize, Deserialize)]
70pub struct AgentRegistrationResponse {
71 pub status: String,
72 pub message: String,
73 pub success: bool,
74 #[serde(skip_serializing_if = "Option::is_none")]
75 pub transport: Option<HashMap<String, serde_json::Value>>,
76 #[serde(skip_serializing_if = "Option::is_none")]
77 pub rates: Option<HashMap<String, HashMap<String, f64>>>,
78 #[serde(skip_serializing_if = "Option::is_none")]
80 pub transports: Option<Vec<TransportConfig>>,
81 #[serde(skip_serializing_if = "Option::is_none")]
82 pub recommended_transport: Option<String>,
83 #[serde(skip_serializing_if = "Option::is_none")]
84 pub shm_paths: Option<HashMap<String, String>>,
85 pub cortical_areas: serde_json::Value,
87}
88
89#[derive(Debug, Clone, Serialize, Deserialize)]
91pub struct AgentProperties {
92 pub agent_type: String,
93 pub agent_ip: String,
94 pub agent_data_port: u16,
95 pub agent_router_address: String,
96 pub agent_version: String,
97 pub controller_version: String,
98 pub capabilities: HashMap<String, serde_json::Value>,
99 #[serde(skip_serializing_if = "Option::is_none")]
100 pub chosen_transport: Option<String>, }
102
103#[derive(Debug, Clone, Serialize, Deserialize)]
105pub struct HeartbeatRequest {
106 pub agent_id: String,
107}
108
109#[async_trait]
111pub trait AgentService: Send + Sync {
112 async fn register_agent(
114 &self,
115 registration: AgentRegistration,
116 ) -> AgentResult<AgentRegistrationResponse>;
117
118 async fn heartbeat(&self, request: HeartbeatRequest) -> AgentResult<()>;
120
121 async fn list_agents(&self) -> AgentResult<Vec<String>>;
123
124 async fn get_agent_properties(&self, agent_id: &str) -> AgentResult<AgentProperties>;
126
127 async fn get_shared_memory_info(
129 &self,
130 ) -> AgentResult<HashMap<String, HashMap<String, serde_json::Value>>>;
131
132 async fn deregister_agent(&self, agent_id: &str) -> AgentResult<()>;
134
135 async fn manual_stimulation(
137 &self,
138 stimulation_payload: HashMap<String, Vec<Vec<i32>>>,
139 mode: ManualStimulationMode,
140 ) -> AgentResult<HashMap<String, serde_json::Value>>;
141
142 fn try_set_runtime_service(
145 &self,
146 _runtime_service: std::sync::Arc<dyn crate::traits::RuntimeService + Send + Sync>,
147 ) {
148 }
150}