Skip to main content

feagi_services/traits/
runtime_service.rs

1// Copyright 2025 Neuraville Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4/*!
5Runtime control service trait.
6
7Defines the stable interface for controlling the FEAGI burst engine runtime.
8
9Copyright 2025 Neuraville Inc.
10Licensed under the Apache License, Version 2.0
11*/
12
13use crate::types::*;
14use async_trait::async_trait;
15
16/// Manual stimulation injection behavior.
17///
18/// - `Candidate`: inject into FCL candidates (normal dynamics path)
19/// - `ForceFire`: stage neurons to be emitted in next burst fire queue
20#[derive(Debug, Clone, Copy, PartialEq, Eq)]
21pub enum ManualStimulationMode {
22    Candidate,
23    ForceFire,
24}
25
26/// Runtime control service (transport-agnostic)
27#[async_trait]
28pub trait RuntimeService: Send + Sync {
29    /// Start the burst engine
30    ///
31    /// Begins executing neural bursts at the configured frequency.
32    ///
33    /// # Errors
34    /// * `ServiceError::InvalidState` - Already running
35    /// * `ServiceError::Backend` - Failed to start burst engine
36    ///
37    async fn start(&self) -> ServiceResult<()>;
38
39    /// Stop the burst engine
40    ///
41    /// Gracefully stops burst execution.
42    ///
43    /// # Errors
44    /// * `ServiceError::Backend` - Failed to stop burst engine
45    ///
46    async fn stop(&self) -> ServiceResult<()>;
47
48    /// Pause the burst engine
49    ///
50    /// Temporarily pauses burst execution without stopping the thread.
51    ///
52    /// # Errors
53    /// * `ServiceError::InvalidState` - Not running
54    /// * `ServiceError::Backend` - Failed to pause
55    ///
56    async fn pause(&self) -> ServiceResult<()>;
57
58    /// Resume the burst engine
59    ///
60    /// Resumes burst execution after pause.
61    ///
62    /// # Errors
63    /// * `ServiceError::InvalidState` - Not paused
64    /// * `ServiceError::Backend` - Failed to resume
65    ///
66    async fn resume(&self) -> ServiceResult<()>;
67
68    /// Execute a single burst step
69    ///
70    /// Executes one burst cycle and then pauses.
71    /// Useful for debugging and step-by-step execution.
72    ///
73    /// # Errors
74    /// * `ServiceError::InvalidState` - Already running in continuous mode
75    /// * `ServiceError::Backend` - Failed to execute step
76    ///
77    async fn step(&self) -> ServiceResult<()>;
78
79    /// Get runtime status
80    ///
81    /// Returns the current state of the burst engine.
82    ///
83    /// # Returns
84    /// * `RuntimeStatus` - Current runtime status
85    ///
86    async fn get_status(&self) -> ServiceResult<RuntimeStatus>;
87
88    /// Set burst frequency
89    ///
90    /// Changes the burst execution frequency (Hz).
91    ///
92    /// # Arguments
93    /// * `frequency_hz` - New frequency in Hz (e.g., 30.0)
94    ///
95    /// # Errors
96    /// * `ServiceError::InvalidInput` - Invalid frequency (must be > 0)
97    ///
98    async fn set_frequency(&self, frequency_hz: f64) -> ServiceResult<()>;
99
100    /// Get current burst count
101    ///
102    /// Returns the total number of bursts executed since start.
103    ///
104    /// # Returns
105    /// * `u64` - Total burst count
106    ///
107    async fn get_burst_count(&self) -> ServiceResult<u64>;
108
109    /// Reset burst count
110    ///
111    /// Resets the burst counter to zero.
112    ///
113    async fn reset_burst_count(&self) -> ServiceResult<()>;
114
115    /// Get FCL (Fire Candidate List) snapshot for monitoring
116    ///
117    /// Returns vector of (neuron_id, potential) pairs from last burst
118    ///
119    /// # Returns
120    /// * `Vec<(u64, f32)>` - Neuron IDs and their membrane potentials
121    ///
122    async fn get_fcl_snapshot(&self) -> ServiceResult<Vec<(u64, f32)>>;
123
124    /// Get Fire Candidate List snapshot with cortical area information
125    ///
126    /// Returns the last FCL snapshot with cortical_idx for each neuron.
127    /// This avoids the need to query cortical_area for each neuron separately.
128    ///
129    /// # Returns
130    /// * `Vec<(u64, u32, f32)>` - (neuron_id, cortical_idx, membrane_potential) tuples
131    ///
132    async fn get_fcl_snapshot_with_cortical_idx(&self) -> ServiceResult<Vec<(u64, u32, f32)>>;
133
134    /// Get Fire Queue sample for monitoring
135    ///
136    /// Returns neurons that actually fired in the last burst, organized by cortical area
137    ///
138    /// # Returns
139    /// * `HashMap<u32, (Vec<u32>, Vec<u32>, Vec<u32>, Vec<u32>, Vec<f32>)>` - Area data
140    ///
141    async fn get_fire_queue_sample(
142        &self,
143    ) -> ServiceResult<
144        std::collections::HashMap<u32, (Vec<u32>, Vec<u32>, Vec<u32>, Vec<u32>, Vec<f32>)>,
145    >;
146
147    /// Get Fire Ledger window configurations for all cortical areas
148    ///
149    /// # Returns
150    /// * `Vec<(u32, usize)>` - (cortical_idx, window_size) pairs
151    ///
152    async fn get_fire_ledger_configs(&self) -> ServiceResult<Vec<(u32, usize)>>;
153
154    /// Configure Fire Ledger window size for a cortical area
155    ///
156    /// # Arguments
157    /// * `cortical_idx` - Cortical area index
158    /// * `window_size` - Number of bursts to retain in history
159    ///
160    async fn configure_fire_ledger_window(
161        &self,
162        cortical_idx: u32,
163        window_size: usize,
164    ) -> ServiceResult<()>;
165
166    /// Get FCL/FQ sampler configuration
167    ///
168    /// # Returns
169    /// * `(f64, u32)` - (frequency_hz, consumer_type) where consumer: 1=viz, 2=motor, 3=both
170    ///
171    async fn get_fcl_sampler_config(&self) -> ServiceResult<(f64, u32)>;
172
173    /// Set FCL/FQ sampler configuration
174    ///
175    /// # Arguments
176    /// * `frequency` - Optional sampling frequency in Hz
177    /// * `consumer` - Optional consumer type (1=viz, 2=motor, 3=both)
178    ///
179    async fn set_fcl_sampler_config(
180        &self,
181        frequency: Option<f64>,
182        consumer: Option<u32>,
183    ) -> ServiceResult<()>;
184
185    /// Get FCL sample rate for a specific cortical area
186    ///
187    /// # Arguments
188    /// * `area_id` - Cortical area ID (cortical_idx)
189    ///
190    /// # Returns
191    /// * `f64` - Sample rate in Hz
192    ///
193    async fn get_area_fcl_sample_rate(&self, area_id: u32) -> ServiceResult<f64>;
194
195    /// Set FCL sample rate for a specific cortical area
196    ///
197    /// # Arguments
198    /// * `area_id` - Cortical area ID (cortical_idx)
199    /// * `sample_rate` - Sample rate in Hz
200    ///
201    async fn set_area_fcl_sample_rate(&self, area_id: u32, sample_rate: f64) -> ServiceResult<()>;
202
203    /// Inject sensory data by cortical area ID and coordinates
204    ///
205    /// Takes cortical ID (base64 string) and coordinates with potential values,
206    /// converts coordinates to neuron IDs, and injects them into FCL.
207    ///
208    /// # Arguments
209    /// * `cortical_id` - Base64 encoded cortical area ID
210    /// * `xyzp_data` - Vector of (x, y, z, potential) tuples
211    ///
212    /// # Returns
213    /// * Number of neurons successfully injected
214    ///
215    /// # Errors
216    /// * `ServiceError::NotFound` - Cortical area not found
217    /// * `ServiceError::InvalidInput` - Invalid cortical ID format
218    ///
219    async fn inject_sensory_by_coordinates(
220        &self,
221        cortical_id: &str,
222        xyzp_data: &[(u32, u32, u32, f32)],
223        mode: ManualStimulationMode,
224    ) -> ServiceResult<usize>;
225
226    /// Register motor subscriptions with per-agent rate limits.
227    ///
228    /// # Arguments
229    /// * `agent_id` - Unique agent identifier
230    /// * `cortical_ids` - List of cortical IDs to subscribe to
231    /// * `rate_hz` - Motor publish rate (Hz)
232    ///
233    async fn register_motor_subscriptions(
234        &self,
235        agent_id: &str,
236        cortical_ids: Vec<String>,
237        rate_hz: f64,
238    ) -> ServiceResult<()>;
239
240    /// Register visualization subscriptions with per-agent rate limits.
241    ///
242    /// # Arguments
243    /// * `agent_id` - Unique agent identifier
244    /// * `rate_hz` - Visualization publish rate (Hz)
245    ///
246    async fn register_visualization_subscriptions(
247        &self,
248        agent_id: &str,
249        rate_hz: f64,
250    ) -> ServiceResult<()>;
251
252    /// Unregister motor subscriptions for a disconnected agent.
253    ///
254    /// Called when an agent is deregistered (e.g. descriptor replacement, timeout).
255    fn unregister_motor_subscriptions(&self, agent_id: &str);
256
257    /// Unregister visualization subscriptions for a disconnected agent.
258    ///
259    /// Called when an agent is deregistered (e.g. descriptor replacement, timeout).
260    fn unregister_visualization_subscriptions(&self, agent_id: &str);
261}