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        }
65    }
66
67    /// Initialize the runtime bridge components asynchronously
68    pub async fn initialize(&self) -> Result<(), String> {
69        // Initialize lifecycle controller
70        let lifecycle_config = LifecycleConfig::default();
71        let lifecycle_controller = Arc::new(
72            DefaultLifecycleController::new(lifecycle_config)
73                .await
74                .map_err(|e| format!("Failed to create lifecycle controller: {}", e))?,
75        );
76
77        // Initialize context manager
78        let context_config = ContextManagerConfig::default();
79        let context_manager = Arc::new(
80            StandardContextManager::new(context_config, "runtime_bridge")
81                .await
82                .map_err(|e| format!("Failed to create context manager: {}", e))?,
83        );
84
85        // Initialize the context manager
86        context_manager
87            .initialize()
88            .await
89            .map_err(|e| format!("Failed to initialize context manager: {}", e))?;
90
91        // Store the initialized components
92        *self.lifecycle_controller.lock().unwrap() = Some(lifecycle_controller);
93        *self.context_manager.lock().unwrap() = Some(context_manager);
94
95        Ok(())
96    }
97
98    pub async fn initialize_agent(&self, config: AgentConfig) -> Result<AgentId, String> {
99        let controller = {
100            let controller_guard = self.lifecycle_controller.lock().unwrap();
101            controller_guard.clone()
102        };
103
104        if let Some(controller) = controller {
105            controller
106                .initialize_agent(config)
107                .await
108                .map_err(|e| e.to_string())
109        } else {
110            Err("Lifecycle controller not initialized".to_string())
111        }
112    }
113
114    /// Checks if a given capability is allowed for an agent.
115    pub async fn check_capability(
116        &self,
117        agent_id: &str,
118        capability: &Capability,
119    ) -> Result<PolicyDecision, String> {
120        // Clone the engine to avoid holding the lock across the await
121        let engine = {
122            let engine_guard = self.policy_engine.lock().unwrap();
123            engine_guard.clone()
124        };
125        engine
126            .check_capability(agent_id, capability)
127            .await
128            .map_err(|e| e.to_string())
129    }
130
131    /// Register an event handler for an agent (stub implementation)
132    pub async fn register_event_handler(
133        &self,
134        agent_id: &str,
135        event_name: &str,
136        _event_type: &str,
137    ) -> Result<(), String> {
138        tracing::info!(
139            "Registered event handler '{}' for agent {}",
140            event_name,
141            agent_id
142        );
143        Ok(())
144    }
145
146    /// Emit an event from an agent (stub implementation)
147    pub async fn emit_event(
148        &self,
149        agent_id: &str,
150        event_name: &str,
151        _data: &serde_json::Value,
152    ) -> Result<(), String> {
153        tracing::info!("Agent {} emitted event: {}", agent_id, event_name);
154        Ok(())
155    }
156}