Skip to main content

repl_core/
runtime_bridge.rs

1use std::sync::{Arc, Mutex};
2use symbi_runtime::context::manager::{ContextManagerConfig, StandardContextManager};
3use symbi_runtime::integrations::policy_engine::engine::{
4    OpaPolicyEngine, PolicyDecision, PolicyEngine,
5};
6use symbi_runtime::lifecycle::{DefaultLifecycleController, LifecycleConfig, LifecycleController};
7use symbi_runtime::reasoning::agent_registry::AgentRegistry;
8use symbi_runtime::reasoning::inference::InferenceProvider;
9use symbi_runtime::types::agent::AgentConfig;
10use symbi_runtime::types::security::Capability;
11use symbi_runtime::types::AgentId;
12
13/// The RuntimeBridge manages a simulated, in-process Symbiont runtime environment.
14pub struct RuntimeBridge {
15    lifecycle_controller: Arc<Mutex<Option<Arc<DefaultLifecycleController>>>>,
16    context_manager: Arc<Mutex<Option<Arc<StandardContextManager>>>>,
17    policy_engine: Arc<Mutex<OpaPolicyEngine>>,
18    /// Inference provider for reasoning builtins.
19    inference_provider: Arc<Mutex<Option<Arc<dyn InferenceProvider>>>>,
20    /// Agent registry for multi-agent composition.
21    agent_registry: Arc<AgentRegistry>,
22}
23
24impl Default for RuntimeBridge {
25    fn default() -> Self {
26        Self::new()
27    }
28}
29
30impl RuntimeBridge {
31    pub fn new() -> Self {
32        // Initialize with None - will be set up asynchronously
33        let lifecycle_controller = Arc::new(Mutex::new(None));
34        let context_manager = Arc::new(Mutex::new(None));
35        let policy_engine = Arc::new(Mutex::new(OpaPolicyEngine::new()));
36        let inference_provider = Arc::new(Mutex::new(None));
37        let agent_registry = Arc::new(AgentRegistry::new());
38
39        Self {
40            lifecycle_controller,
41            context_manager,
42            policy_engine,
43            inference_provider,
44            agent_registry,
45        }
46    }
47
48    /// Set the inference provider for reasoning builtins.
49    pub fn set_inference_provider(&self, provider: Arc<dyn InferenceProvider>) {
50        *self.inference_provider.lock().unwrap() = Some(provider);
51    }
52
53    /// Get the agent registry.
54    pub fn agent_registry(&self) -> Arc<AgentRegistry> {
55        Arc::clone(&self.agent_registry)
56    }
57
58    /// Get the reasoning context for async builtins.
59    pub fn reasoning_context(&self) -> crate::dsl::reasoning_builtins::ReasoningBuiltinContext {
60        let provider = self.inference_provider.lock().unwrap().clone();
61        crate::dsl::reasoning_builtins::ReasoningBuiltinContext {
62            provider,
63            agent_registry: Some(Arc::clone(&self.agent_registry)),
64            sender_agent_id: None,
65            comm_bus: None,
66            comm_policy: None,
67        }
68    }
69
70    /// Initialize the runtime bridge components asynchronously
71    pub async fn initialize(&self) -> Result<(), String> {
72        // Initialize lifecycle controller
73        let lifecycle_config = LifecycleConfig::default();
74        let lifecycle_controller = Arc::new(
75            DefaultLifecycleController::new(lifecycle_config)
76                .await
77                .map_err(|e| format!("Failed to create lifecycle controller: {}", e))?,
78        );
79
80        // Initialize context manager
81        let context_config = ContextManagerConfig::default();
82        let context_manager = Arc::new(
83            StandardContextManager::new(context_config, "runtime_bridge")
84                .await
85                .map_err(|e| format!("Failed to create context manager: {}", e))?,
86        );
87
88        // Initialize the context manager
89        context_manager
90            .initialize()
91            .await
92            .map_err(|e| format!("Failed to initialize context manager: {}", e))?;
93
94        // Store the initialized components
95        *self.lifecycle_controller.lock().unwrap() = Some(lifecycle_controller);
96        *self.context_manager.lock().unwrap() = Some(context_manager);
97
98        Ok(())
99    }
100
101    pub async fn initialize_agent(&self, config: AgentConfig) -> Result<AgentId, String> {
102        let controller = {
103            let controller_guard = self.lifecycle_controller.lock().unwrap();
104            controller_guard.clone()
105        };
106
107        if let Some(controller) = controller {
108            controller
109                .initialize_agent(config)
110                .await
111                .map_err(|e| e.to_string())
112        } else {
113            Err("Lifecycle controller not initialized".to_string())
114        }
115    }
116
117    /// Checks if a given capability is allowed for an agent.
118    pub async fn check_capability(
119        &self,
120        agent_id: &str,
121        capability: &Capability,
122    ) -> Result<PolicyDecision, String> {
123        // Clone the engine to avoid holding the lock across the await
124        let engine = {
125            let engine_guard = self.policy_engine.lock().unwrap();
126            engine_guard.clone()
127        };
128        engine
129            .check_capability(agent_id, capability)
130            .await
131            .map_err(|e| e.to_string())
132    }
133
134    /// Register an event handler for an agent (stub implementation)
135    pub async fn register_event_handler(
136        &self,
137        agent_id: &str,
138        event_name: &str,
139        _event_type: &str,
140    ) -> Result<(), String> {
141        tracing::info!(
142            "Registered event handler '{}' for agent {}",
143            event_name,
144            agent_id
145        );
146        Ok(())
147    }
148
149    /// Emit an event from an agent (stub implementation)
150    pub async fn emit_event(
151        &self,
152        agent_id: &str,
153        event_name: &str,
154        _data: &serde_json::Value,
155    ) -> Result<(), String> {
156        tracing::info!("Agent {} emitted event: {}", agent_id, event_name);
157        Ok(())
158    }
159}