1use crate::dsl::ast::*;
6use crate::error::{ReplError, Result};
7use crate::execution_monitor::{ExecutionMonitor, TraceEventType};
8use crate::runtime_bridge::RuntimeBridge;
9use crate::session::SessionSnapshot;
10use serde_json::Value as JsonValue;
11use std::collections::HashMap;
12use std::future::Future;
13use std::pin::Pin;
14use std::sync::{Arc, Mutex};
15use symbi_runtime::integrations::policy_engine::engine::PolicyDecision;
16use symbi_runtime::types::security::Capability;
17use tokio::sync::RwLock;
18use uuid::Uuid;
19
20type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
21type BuiltinFunction = fn(&[DslValue]) -> Result<DslValue>;
22type AsyncBuiltinFn =
23 Arc<dyn Fn(Vec<DslValue>) -> BoxFuture<'static, Result<DslValue>> + Send + Sync>;
24
25#[derive(Debug, Clone)]
27pub struct ExecutionContext {
28 pub variables: HashMap<String, DslValue>,
30 pub functions: HashMap<String, FunctionDefinition>,
32 pub agent_id: Option<Uuid>,
34 pub depth: usize,
36 pub max_depth: usize,
38}
39
40impl Default for ExecutionContext {
41 fn default() -> Self {
42 Self {
43 variables: HashMap::new(),
44 functions: HashMap::new(),
45 agent_id: None,
46 depth: 0,
47 max_depth: 100,
48 }
49 }
50}
51
52#[derive(Debug, Clone, PartialEq)]
54pub enum DslValue {
55 String(String),
56 Number(f64),
57 Integer(i64),
58 Boolean(bool),
59 Duration { value: u64, unit: DurationUnit },
60 Size { value: u64, unit: SizeUnit },
61 List(Vec<DslValue>),
62 Map(HashMap<String, DslValue>),
63 Null,
64 Agent(Box<AgentInstance>),
65 Function(String), Lambda(LambdaFunction), }
68
69#[derive(Debug, Clone, PartialEq)]
71pub struct LambdaFunction {
72 pub parameters: Vec<String>,
73 pub body: Expression,
74 pub captured_context: HashMap<String, DslValue>,
75}
76
77impl DslValue {
78 pub fn to_json(&self) -> JsonValue {
80 match self {
81 DslValue::String(s) => JsonValue::String(s.clone()),
82 DslValue::Number(n) => JsonValue::Number(
83 serde_json::Number::from_f64(*n).unwrap_or_else(|| serde_json::Number::from(0)),
84 ),
85 DslValue::Integer(i) => JsonValue::Number(serde_json::Number::from(*i)),
86 DslValue::Boolean(b) => JsonValue::Bool(*b),
87 DslValue::Duration { value, unit } => {
88 let unit_str = match unit {
89 DurationUnit::Milliseconds => "ms",
90 DurationUnit::Seconds => "s",
91 DurationUnit::Minutes => "m",
92 DurationUnit::Hours => "h",
93 DurationUnit::Days => "d",
94 };
95 JsonValue::String(format!("{}{}", value, unit_str))
96 }
97 DslValue::Size { value, unit } => {
98 let unit_str = match unit {
99 SizeUnit::Bytes => "B",
100 SizeUnit::KB => "KB",
101 SizeUnit::MB => "MB",
102 SizeUnit::GB => "GB",
103 SizeUnit::TB => "TB",
104 };
105 JsonValue::String(format!("{}{}", value, unit_str))
106 }
107 DslValue::List(items) => JsonValue::Array(items.iter().map(|v| v.to_json()).collect()),
108 DslValue::Map(entries) => {
109 let mut map = serde_json::Map::new();
110 for (k, v) in entries {
111 map.insert(k.clone(), v.to_json());
112 }
113 JsonValue::Object(map)
114 }
115 DslValue::Null => JsonValue::Null,
116 DslValue::Agent(agent) => JsonValue::String(format!("Agent({})", agent.id)),
117 DslValue::Function(name) => JsonValue::String(format!("Function({})", name)),
118 DslValue::Lambda(lambda) => {
119 JsonValue::String(format!("Lambda({} params)", lambda.parameters.len()))
120 }
121 }
122 }
123
124 pub fn type_name(&self) -> &'static str {
126 match self {
127 DslValue::String(_) => "string",
128 DslValue::Number(_) => "number",
129 DslValue::Integer(_) => "integer",
130 DslValue::Boolean(_) => "boolean",
131 DslValue::Duration { .. } => "duration",
132 DslValue::Size { .. } => "size",
133 DslValue::List(_) => "list",
134 DslValue::Map(_) => "map",
135 DslValue::Null => "null",
136 DslValue::Agent(_) => "agent",
137 DslValue::Function(_) => "function",
138 DslValue::Lambda(_) => "lambda",
139 }
140 }
141
142 pub fn is_truthy(&self) -> bool {
144 match self {
145 DslValue::Boolean(b) => *b,
146 DslValue::Null => false,
147 DslValue::String(s) => !s.is_empty(),
148 DslValue::Number(n) => *n != 0.0,
149 DslValue::Integer(i) => *i != 0,
150 DslValue::List(items) => !items.is_empty(),
151 DslValue::Map(entries) => !entries.is_empty(),
152 DslValue::Lambda(_) => true,
153 _ => true,
154 }
155 }
156}
157
158#[derive(Debug, Clone, PartialEq)]
160pub struct AgentInstance {
161 pub id: Uuid,
162 pub definition: AgentDefinition,
163 pub state: AgentState,
164 pub created_at: chrono::DateTime<chrono::Utc>,
165}
166
167#[derive(Debug, Clone, PartialEq)]
169pub enum AgentState {
170 Created,
171 Starting,
172 Running,
173 Paused,
174 Stopping,
175 Stopped,
176 Failed(String),
177}
178
179#[derive(Debug, Clone)]
181pub enum ExecutionResult {
182 Value(DslValue),
183 Return(DslValue),
184 Continue,
185 Break,
186 Error(String),
187}
188
189pub struct DslEvaluator {
191 runtime_bridge: Arc<RuntimeBridge>,
193 agents: Arc<RwLock<HashMap<Uuid, AgentInstance>>>,
195 global_context: Arc<Mutex<ExecutionContext>>,
197 builtins: HashMap<String, BuiltinFunction>,
199 async_builtins: HashMap<String, AsyncBuiltinFn>,
201 monitor: Arc<ExecutionMonitor>,
203}
204
205impl DslEvaluator {
206 pub fn new(runtime_bridge: Arc<RuntimeBridge>) -> Self {
208 let mut builtins: HashMap<String, BuiltinFunction> = HashMap::new();
209
210 builtins.insert("print".to_string(), builtin_print as BuiltinFunction);
212 builtins.insert("len".to_string(), builtin_len as BuiltinFunction);
213 builtins.insert("upper".to_string(), builtin_upper as BuiltinFunction);
214 builtins.insert("lower".to_string(), builtin_lower as BuiltinFunction);
215 builtins.insert("format".to_string(), builtin_format as BuiltinFunction);
216 builtins.insert(
217 "parse_json".to_string(),
218 crate::dsl::reasoning_builtins::builtin_parse_json as BuiltinFunction,
219 );
220
221 let async_builtins = Self::register_async_builtins(&runtime_bridge);
223
224 Self {
225 runtime_bridge,
226 agents: Arc::new(RwLock::new(HashMap::new())),
227 global_context: Arc::new(Mutex::new(ExecutionContext::default())),
228 builtins,
229 async_builtins,
230 monitor: Arc::new(ExecutionMonitor::new()),
231 }
232 }
233
234 fn register_async_builtins(bridge: &Arc<RuntimeBridge>) -> HashMap<String, AsyncBuiltinFn> {
236 use crate::dsl::agent_composition;
237 use crate::dsl::pattern_builtins;
238 use crate::dsl::reasoning_builtins;
239
240 let mut async_builtins: HashMap<String, AsyncBuiltinFn> = HashMap::new();
241 let ctx = bridge.reasoning_context();
242
243 {
245 let ctx = ctx.clone();
246 async_builtins.insert(
247 "reason".to_string(),
248 Arc::new(move |args| {
249 let ctx = ctx.clone();
250 Box::pin(async move { reasoning_builtins::builtin_reason(&args, &ctx).await })
251 }),
252 );
253 }
254 {
255 let ctx = ctx.clone();
256 async_builtins.insert(
257 "llm_call".to_string(),
258 Arc::new(move |args| {
259 let ctx = ctx.clone();
260 Box::pin(async move { reasoning_builtins::builtin_llm_call(&args, &ctx).await })
261 }),
262 );
263 }
264 {
265 let ctx = ctx.clone();
266 async_builtins.insert(
267 "delegate".to_string(),
268 Arc::new(move |args| {
269 let ctx = ctx.clone();
270 Box::pin(async move { reasoning_builtins::builtin_delegate(&args, &ctx).await })
271 }),
272 );
273 }
274 {
275 let ctx = ctx.clone();
276 async_builtins.insert(
277 "tool_call".to_string(),
278 Arc::new(move |args| {
279 let ctx = ctx.clone();
280 Box::pin(
281 async move { reasoning_builtins::builtin_tool_call(&args, &ctx).await },
282 )
283 }),
284 );
285 }
286
287 {
289 let ctx = ctx.clone();
290 async_builtins.insert(
291 "chain".to_string(),
292 Arc::new(move |args| {
293 let ctx = ctx.clone();
294 Box::pin(async move { pattern_builtins::builtin_chain(&args, &ctx).await })
295 }),
296 );
297 }
298 {
299 let ctx = ctx.clone();
300 async_builtins.insert(
301 "debate".to_string(),
302 Arc::new(move |args| {
303 let ctx = ctx.clone();
304 Box::pin(async move { pattern_builtins::builtin_debate(&args, &ctx).await })
305 }),
306 );
307 }
308 {
309 let ctx = ctx.clone();
310 async_builtins.insert(
311 "map_reduce".to_string(),
312 Arc::new(move |args| {
313 let ctx = ctx.clone();
314 Box::pin(async move { pattern_builtins::builtin_map_reduce(&args, &ctx).await })
315 }),
316 );
317 }
318 {
319 let ctx = ctx.clone();
320 async_builtins.insert(
321 "director".to_string(),
322 Arc::new(move |args| {
323 let ctx = ctx.clone();
324 Box::pin(async move { pattern_builtins::builtin_director(&args, &ctx).await })
325 }),
326 );
327 }
328
329 {
331 let ctx = ctx.clone();
332 async_builtins.insert(
333 "spawn_agent".to_string(),
334 Arc::new(move |args| {
335 let ctx = ctx.clone();
336 Box::pin(
337 async move { agent_composition::builtin_spawn_agent(&args, &ctx).await },
338 )
339 }),
340 );
341 }
342 {
343 let ctx = ctx.clone();
344 async_builtins.insert(
345 "ask".to_string(),
346 Arc::new(move |args| {
347 let ctx = ctx.clone();
348 Box::pin(async move { agent_composition::builtin_ask(&args, &ctx).await })
349 }),
350 );
351 }
352 {
353 let ctx = ctx.clone();
354 async_builtins.insert(
355 "send_to".to_string(),
356 Arc::new(move |args| {
357 let ctx = ctx.clone();
358 Box::pin(async move { agent_composition::builtin_send_to(&args, &ctx).await })
359 }),
360 );
361 }
362 {
363 let ctx = ctx.clone();
364 async_builtins.insert(
365 "parallel".to_string(),
366 Arc::new(move |args| {
367 let ctx = ctx.clone();
368 Box::pin(async move { agent_composition::builtin_parallel(&args, &ctx).await })
369 }),
370 );
371 }
372 {
373 let ctx = ctx.clone();
374 async_builtins.insert(
375 "race".to_string(),
376 Arc::new(move |args| {
377 let ctx = ctx.clone();
378 Box::pin(async move { agent_composition::builtin_race(&args, &ctx).await })
379 }),
380 );
381 }
382
383 async_builtins
384 }
385
386 pub fn monitor(&self) -> Arc<ExecutionMonitor> {
388 Arc::clone(&self.monitor)
389 }
390
391 pub fn builtin_names(&self) -> Vec<String> {
393 let mut names: Vec<String> = self.builtins.keys().cloned().collect();
394 names.sort();
395 names
396 }
397
398 pub fn async_builtin_names(&self) -> Vec<String> {
400 let mut names: Vec<String> = self.async_builtins.keys().cloned().collect();
401 names.sort();
402 names
403 }
404
405 pub fn user_defined_names(&self) -> Vec<String> {
407 if let Ok(guard) = self.agents.try_read() {
410 let mut names: Vec<String> =
411 guard.values().map(|a| a.definition.name.clone()).collect();
412 names.sort();
413 names
414 } else {
415 vec![]
416 }
417 }
418
419 pub async fn execute_program(&self, program: Program) -> Result<DslValue> {
421 let mut context = ExecutionContext::default();
422
423 for declaration in &program.declarations {
425 if let Declaration::Function(func) = declaration {
426 context.functions.insert(func.name.clone(), func.clone());
427 }
428 }
429
430 let mut last_value = DslValue::Null;
432 for declaration in &program.declarations {
433 match self.execute_declaration(declaration, &mut context).await? {
434 ExecutionResult::Value(value) => last_value = value,
435 ExecutionResult::Return(value) => return Ok(value),
436 ExecutionResult::Error(msg) => return Err(ReplError::Execution(msg)),
437 _ => {}
438 }
439 }
440
441 Ok(last_value)
442 }
443
444 async fn execute_declaration(
446 &self,
447 declaration: &Declaration,
448 context: &mut ExecutionContext,
449 ) -> Result<ExecutionResult> {
450 match declaration {
451 Declaration::Agent(agent_def) => self.create_agent(agent_def.clone(), context).await,
452 Declaration::Behavior(behavior_def) => {
453 let func_def = FunctionDefinition {
455 name: behavior_def.name.clone(),
456 parameters: behavior_def.input.clone().unwrap_or_default(),
457 return_type: behavior_def.output.as_ref().map(|_| Type::Any),
458 body: behavior_def.steps.clone(),
459 span: behavior_def.span.clone(),
460 };
461 context
462 .functions
463 .insert(behavior_def.name.clone(), func_def);
464 Ok(ExecutionResult::Value(DslValue::Function(
465 behavior_def.name.clone(),
466 )))
467 }
468 Declaration::Function(func_def) => {
469 context
470 .functions
471 .insert(func_def.name.clone(), func_def.clone());
472 Ok(ExecutionResult::Value(DslValue::Function(
473 func_def.name.clone(),
474 )))
475 }
476 Declaration::EventHandler(handler) => {
477 let agent_id = context.agent_id.unwrap_or_else(Uuid::new_v4);
479
480 match self
481 .runtime_bridge
482 .register_event_handler(
483 &agent_id.to_string(),
484 &handler.event_name,
485 &handler.event_name,
486 )
487 .await
488 {
489 Ok(_) => {
490 tracing::info!(
491 "Registered event handler '{}' for agent {}",
492 handler.event_name,
493 agent_id
494 );
495 Ok(ExecutionResult::Value(DslValue::Function(
496 handler.event_name.clone(),
497 )))
498 }
499 Err(e) => {
500 tracing::error!("Failed to register event handler: {}", e);
501 Err(ReplError::Runtime(format!(
502 "Failed to register event handler: {}",
503 e
504 )))
505 }
506 }
507 }
508 Declaration::Struct(struct_def) => {
509 let struct_info = format!("{}:{}", struct_def.name, struct_def.fields.len());
511 context.variables.insert(
512 format!("type_{}", struct_def.name),
513 DslValue::String(struct_info.clone()),
514 );
515
516 tracing::info!(
517 "Registered struct type '{}' with {} fields",
518 struct_def.name,
519 struct_def.fields.len()
520 );
521 Ok(ExecutionResult::Value(DslValue::String(format!(
522 "Struct({})",
523 struct_def.name
524 ))))
525 }
526 }
527 }
528
529 pub async fn create_agent(
531 &self,
532 agent_def: AgentDefinition,
533 context: &mut ExecutionContext,
534 ) -> Result<ExecutionResult> {
535 if let Some(security) = &agent_def.security {
537 for capability in &security.capabilities {
538 if !self.check_capability(capability).await? {
539 return Err(ReplError::Security(format!(
540 "Missing capability: {}",
541 capability
542 )));
543 }
544 }
545 }
546
547 let agent_id = Uuid::new_v4();
548 let agent = AgentInstance {
549 id: agent_id,
550 definition: agent_def.clone(),
551 state: AgentState::Created,
552 created_at: chrono::Utc::now(),
553 };
554
555 self.monitor
557 .log_agent_event(&agent, TraceEventType::AgentCreated);
558
559 self.agents.write().await.insert(agent_id, agent.clone());
561 context.agent_id = Some(agent_id);
562
563 tracing::info!("Agent '{}' created with ID {}", agent_def.name, agent_id);
564 Ok(ExecutionResult::Value(DslValue::Agent(Box::new(agent))))
565 }
566
567 fn execute_block<'a>(
569 &'a self,
570 block: &'a Block,
571 context: &'a mut ExecutionContext,
572 ) -> BoxFuture<'a, Result<ExecutionResult>> {
573 Box::pin(async move {
574 if context.depth >= context.max_depth {
575 return Err(ReplError::Execution(
576 "Maximum execution depth exceeded".to_string(),
577 ));
578 }
579
580 context.depth += 1;
581
582 let mut last_result = ExecutionResult::Value(DslValue::Null);
583
584 for statement in &block.statements {
585 match self.execute_statement(statement, context).await? {
586 ExecutionResult::Return(value) => {
587 context.depth -= 1;
588 return Ok(ExecutionResult::Return(value));
589 }
590 ExecutionResult::Break | ExecutionResult::Continue => {
591 context.depth -= 1;
592 return Ok(last_result);
593 }
594 ExecutionResult::Error(msg) => {
595 context.depth -= 1;
596 return Err(ReplError::Execution(msg));
597 }
598 result => last_result = result,
599 }
600 }
601
602 context.depth -= 1;
603 Ok(last_result)
604 })
605 }
606
607 async fn execute_statement(
609 &self,
610 statement: &Statement,
611 context: &mut ExecutionContext,
612 ) -> Result<ExecutionResult> {
613 match statement {
614 Statement::Let(let_stmt) => {
615 let value = self
616 .evaluate_expression_impl(&let_stmt.value, context)
617 .await?;
618 context.variables.insert(let_stmt.name.clone(), value);
619 Ok(ExecutionResult::Value(DslValue::Null))
620 }
621 Statement::If(if_stmt) => {
622 let condition = self
623 .evaluate_expression_impl(&if_stmt.condition, context)
624 .await?;
625
626 if condition.is_truthy() {
627 self.execute_block(&if_stmt.then_block, context).await
628 } else {
629 for else_if in &if_stmt.else_ifs {
631 let else_condition = self
632 .evaluate_expression_impl(&else_if.condition, context)
633 .await?;
634 if else_condition.is_truthy() {
635 return self.execute_block(&else_if.block, context).await;
636 }
637 }
638
639 if let Some(else_block) = &if_stmt.else_block {
641 self.execute_block(else_block, context).await
642 } else {
643 Ok(ExecutionResult::Value(DslValue::Null))
644 }
645 }
646 }
647 Statement::Return(ret_stmt) => {
648 let value = if let Some(expr) = &ret_stmt.value {
649 self.evaluate_expression_impl(expr, context).await?
650 } else {
651 DslValue::Null
652 };
653 Ok(ExecutionResult::Return(value))
654 }
655 Statement::Emit(emit_stmt) => {
656 let data = if let Some(expr) = &emit_stmt.data {
657 self.evaluate_expression_impl(expr, context).await?
658 } else {
659 DslValue::Null
660 };
661
662 let agent_id = context.agent_id.unwrap_or_else(Uuid::new_v4);
664
665 match self
666 .runtime_bridge
667 .emit_event(
668 &agent_id.to_string(),
669 &emit_stmt.event_name,
670 &data.to_json(),
671 )
672 .await
673 {
674 Ok(_) => {
675 tracing::info!(
676 "Successfully emitted event: {} with data: {:?}",
677 emit_stmt.event_name,
678 data
679 );
680 }
681 Err(e) => {
682 tracing::error!("Failed to emit event '{}': {}", emit_stmt.event_name, e);
683 return Err(ReplError::Runtime(format!("Failed to emit event: {}", e)));
684 }
685 }
686 Ok(ExecutionResult::Value(DslValue::Null))
687 }
688 Statement::Require(req_stmt) => {
689 match &req_stmt.requirement {
690 RequirementType::Capability(cap_name) => {
691 if !self.check_capability(cap_name).await? {
692 return Err(ReplError::Security(format!(
693 "Missing capability: {}",
694 cap_name
695 )));
696 }
697 }
698 RequirementType::Capabilities(cap_names) => {
699 for cap_name in cap_names {
700 if !self.check_capability(cap_name).await? {
701 return Err(ReplError::Security(format!(
702 "Missing capability: {}",
703 cap_name
704 )));
705 }
706 }
707 }
708 }
709 Ok(ExecutionResult::Value(DslValue::Null))
710 }
711 Statement::Expression(expr) => {
712 let value = self.evaluate_expression_impl(expr, context).await?;
713 Ok(ExecutionResult::Value(value))
714 }
715 Statement::Match(match_stmt) => {
717 let value = self
718 .evaluate_expression_impl(&match_stmt.expression, context)
719 .await?;
720
721 for arm in &match_stmt.arms {
722 if self.pattern_matches(&arm.pattern, &value) {
723 return self
724 .evaluate_expression_impl(&arm.body, context)
725 .await
726 .map(ExecutionResult::Value);
727 }
728 }
729
730 Err(ReplError::Execution(
732 "No matching pattern found".to_string(),
733 ))
734 }
735 Statement::For(for_stmt) => {
736 let iterable = self
737 .evaluate_expression_impl(&for_stmt.iterable, context)
738 .await?;
739
740 match iterable {
741 DslValue::List(items) => {
742 for item in items {
743 context.variables.insert(for_stmt.variable.clone(), item);
744 match self.execute_block(&for_stmt.body, context).await? {
745 ExecutionResult::Break => break,
746 ExecutionResult::Continue => continue,
747 ExecutionResult::Return(value) => {
748 return Ok(ExecutionResult::Return(value))
749 }
750 _ => {}
751 }
752 }
753 Ok(ExecutionResult::Value(DslValue::Null))
754 }
755 _ => Err(ReplError::Execution(
756 "For loop requires iterable value".to_string(),
757 )),
758 }
759 }
760 Statement::While(while_stmt) => {
761 loop {
762 let condition = self
763 .evaluate_expression_impl(&while_stmt.condition, context)
764 .await?;
765 if !condition.is_truthy() {
766 break;
767 }
768
769 match self.execute_block(&while_stmt.body, context).await? {
770 ExecutionResult::Break => break,
771 ExecutionResult::Continue => continue,
772 ExecutionResult::Return(value) => {
773 return Ok(ExecutionResult::Return(value))
774 }
775 _ => {}
776 }
777 }
778 Ok(ExecutionResult::Value(DslValue::Null))
779 }
780 Statement::Try(try_stmt) => {
781 match self.execute_block(&try_stmt.try_block, context).await {
783 Ok(result) => Ok(result),
784 Err(_) => {
785 self.execute_block(&try_stmt.catch_block, context).await
787 }
788 }
789 }
790 Statement::Check(check_stmt) => {
791 tracing::info!("Policy check for: {}", check_stmt.policy_name);
793 Ok(ExecutionResult::Value(DslValue::Boolean(true)))
794 }
795 }
796 }
797
798 pub async fn evaluate_expression(
800 &self,
801 expression: &Expression,
802 context: &mut ExecutionContext,
803 ) -> Result<DslValue> {
804 self.evaluate_expression_impl(expression, context).await
805 }
806
807 fn evaluate_expression_impl<'a>(
809 &'a self,
810 expression: &'a Expression,
811 context: &'a mut ExecutionContext,
812 ) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<DslValue>> + Send + 'a>> {
813 Box::pin(async move {
814 match expression {
815 Expression::Literal(literal) => self.evaluate_literal(literal),
816 Expression::Identifier(identifier) => {
817 if let Some(value) = context.variables.get(&identifier.name) {
818 Ok(value.clone())
819 } else {
820 Err(ReplError::Execution(format!(
821 "Undefined variable: {}",
822 identifier.name
823 )))
824 }
825 }
826 Expression::FieldAccess(field_access) => {
827 let object = self
828 .evaluate_expression_impl(&field_access.object, context)
829 .await?;
830 self.access_field(object, &field_access.field)
831 }
832 Expression::IndexAccess(index_access) => {
833 let object = self
834 .evaluate_expression_impl(&index_access.object, context)
835 .await?;
836 let index = self
837 .evaluate_expression_impl(&index_access.index, context)
838 .await?;
839 self.access_index(object, index)
840 }
841 Expression::FunctionCall(func_call) => {
842 self.call_function(&func_call.function, &func_call.arguments, context)
843 .await
844 }
845 Expression::MethodCall(method_call) => {
846 let object = self
847 .evaluate_expression_impl(&method_call.object, context)
848 .await?;
849 self.call_method(object, &method_call.method, &method_call.arguments, context)
850 .await
851 }
852 Expression::BinaryOp(binary_op) => {
853 let left = self
854 .evaluate_expression_impl(&binary_op.left, context)
855 .await?;
856 let right = self
857 .evaluate_expression_impl(&binary_op.right, context)
858 .await?;
859 self.evaluate_binary_op(&binary_op.operator, left, right)
860 }
861 Expression::UnaryOp(unary_op) => {
862 let operand = self
863 .evaluate_expression_impl(&unary_op.operand, context)
864 .await?;
865 self.evaluate_unary_op(&unary_op.operator, operand)
866 }
867 Expression::Assignment(assignment) => {
868 let value = self
869 .evaluate_expression_impl(&assignment.value, context)
870 .await?;
871
872 if let Expression::Identifier(identifier) = assignment.target.as_ref() {
873 context
874 .variables
875 .insert(identifier.name.clone(), value.clone());
876 Ok(value)
877 } else {
878 Err(ReplError::Execution(
879 "Invalid assignment target".to_string(),
880 ))
881 }
882 }
883 Expression::List(list_expr) => {
884 let mut items = Vec::new();
885 for element in &list_expr.elements {
886 items.push(self.evaluate_expression_impl(element, context).await?);
887 }
888 Ok(DslValue::List(items))
889 }
890 Expression::Map(map_expr) => {
891 let mut entries = HashMap::new();
892 for entry in &map_expr.entries {
893 let key = self.evaluate_expression_impl(&entry.key, context).await?;
894 let value = self.evaluate_expression_impl(&entry.value, context).await?;
895
896 if let DslValue::String(key_str) = key {
897 entries.insert(key_str, value);
898 } else {
899 return Err(ReplError::Execution(
900 "Map keys must be strings".to_string(),
901 ));
902 }
903 }
904 Ok(DslValue::Map(entries))
905 }
906 Expression::Invoke(invoke) => {
907 self.evaluate_invoke_expression(invoke, context).await
908 }
909 Expression::Lambda(lambda) => {
910 self.evaluate_lambda_expression(lambda, context).await
911 }
912 Expression::Conditional(conditional) => {
913 let condition = self
914 .evaluate_expression_impl(&conditional.condition, context)
915 .await?;
916
917 if condition.is_truthy() {
918 self.evaluate_expression_impl(&conditional.if_true, context)
919 .await
920 } else {
921 self.evaluate_expression_impl(&conditional.if_false, context)
922 .await
923 }
924 }
925 }
926 })
927 }
928
929 pub fn evaluate_literal(&self, literal: &Literal) -> Result<DslValue> {
931 match literal {
932 Literal::String(s) => Ok(DslValue::String(s.clone())),
933 Literal::Number(n) => Ok(DslValue::Number(*n)),
934 Literal::Integer(i) => Ok(DslValue::Integer(*i)),
935 Literal::Boolean(b) => Ok(DslValue::Boolean(*b)),
936 Literal::Duration(duration) => Ok(DslValue::Duration {
937 value: duration.value,
938 unit: duration.unit.clone(),
939 }),
940 Literal::Size(size) => Ok(DslValue::Size {
941 value: size.value,
942 unit: size.unit.clone(),
943 }),
944 Literal::Null => Ok(DslValue::Null),
945 }
946 }
947
948 fn access_field(&self, object: DslValue, field: &str) -> Result<DslValue> {
950 match object {
951 DslValue::Map(entries) => entries
952 .get(field)
953 .cloned()
954 .ok_or_else(|| ReplError::Execution(format!("Field '{}' not found", field))),
955 DslValue::Agent(agent) => match field {
956 "id" => Ok(DslValue::String(agent.id.to_string())),
957 "state" => Ok(DslValue::String(format!("{:?}", agent.state))),
958 "created_at" => Ok(DslValue::String(agent.created_at.to_rfc3339())),
959 _ => Err(ReplError::Execution(format!(
960 "Agent field '{}' not found",
961 field
962 ))),
963 },
964 _ => Err(ReplError::Execution(format!(
965 "Cannot access field on {}",
966 object.type_name()
967 ))),
968 }
969 }
970
971 fn access_index(&self, object: DslValue, index: DslValue) -> Result<DslValue> {
973 match (object, index) {
974 (DslValue::List(items), DslValue::Integer(i)) => {
975 let idx = if i < 0 { items.len() as i64 + i } else { i } as usize;
976
977 items
978 .get(idx)
979 .cloned()
980 .ok_or_else(|| ReplError::Execution("Index out of bounds".to_string()))
981 }
982 (DslValue::Map(entries), DslValue::String(key)) => entries
983 .get(&key)
984 .cloned()
985 .ok_or_else(|| ReplError::Execution(format!("Key '{}' not found", key))),
986 (obj, idx) => Err(ReplError::Execution(format!(
987 "Cannot index {} with {}",
988 obj.type_name(),
989 idx.type_name()
990 ))),
991 }
992 }
993
994 async fn call_function(
996 &self,
997 name: &str,
998 arguments: &[Expression],
999 context: &mut ExecutionContext,
1000 ) -> Result<DslValue> {
1001 let mut arg_values = Vec::new();
1003 for arg in arguments {
1004 arg_values.push(self.evaluate_expression_impl(arg, context).await?);
1005 }
1006
1007 if let Some(builtin) = self.builtins.get(name) {
1009 return builtin(&arg_values);
1010 }
1011
1012 if let Some(async_builtin) = self.async_builtins.get(name) {
1014 return async_builtin(arg_values).await;
1015 }
1016
1017 if let Some(func_def) = context.functions.get(name).cloned() {
1019 return self.call_user_function(func_def, arg_values, context).await;
1020 }
1021
1022 Err(ReplError::Execution(format!("Unknown function: {}", name)))
1023 }
1024
1025 async fn call_user_function(
1027 &self,
1028 func_def: FunctionDefinition,
1029 arguments: Vec<DslValue>,
1030 context: &mut ExecutionContext,
1031 ) -> Result<DslValue> {
1032 let mut new_context = context.clone();
1034 new_context.variables.clear();
1035
1036 for (i, param) in func_def.parameters.parameters.iter().enumerate() {
1038 let value = match arguments.get(i) {
1039 Some(value) => value.clone(),
1040 None => {
1041 if let Some(default_expr) = ¶m.default_value {
1042 self.evaluate_expression_impl(default_expr, &mut new_context)
1044 .await?
1045 } else {
1046 return Err(ReplError::Execution(format!(
1047 "Missing argument for parameter '{}'",
1048 param.name
1049 )));
1050 }
1051 }
1052 };
1053
1054 new_context.variables.insert(param.name.clone(), value);
1055 }
1056
1057 match self.execute_block(&func_def.body, &mut new_context).await? {
1059 ExecutionResult::Value(value) => Ok(value),
1060 ExecutionResult::Return(value) => Ok(value),
1061 _ => Ok(DslValue::Null),
1062 }
1063 }
1064
1065 async fn call_method(
1067 &self,
1068 object: DslValue,
1069 method: &str,
1070 arguments: &[Expression],
1071 context: &mut ExecutionContext,
1072 ) -> Result<DslValue> {
1073 let mut arg_values = vec![object.clone()];
1074 for arg in arguments {
1075 arg_values.push(self.evaluate_expression(arg, context).await?);
1076 }
1077
1078 match (&object, method) {
1079 (DslValue::String(_), "upper") => builtin_upper(&[object]),
1080 (DslValue::String(_), "lower") => builtin_lower(&[object]),
1081 (DslValue::List(_) | DslValue::Map(_) | DslValue::String(_), "len") => {
1082 builtin_len(&[object])
1083 }
1084 _ => Err(ReplError::Execution(format!(
1085 "Method '{}' not found on {}",
1086 method,
1087 object.type_name()
1088 ))),
1089 }
1090 }
1091
1092 fn evaluate_binary_op(
1094 &self,
1095 operator: &BinaryOperator,
1096 left: DslValue,
1097 right: DslValue,
1098 ) -> Result<DslValue> {
1099 match operator {
1100 BinaryOperator::Add => match (left, right) {
1101 (DslValue::Number(l), DslValue::Number(r)) => Ok(DslValue::Number(l + r)),
1102 (DslValue::Integer(l), DslValue::Integer(r)) => Ok(DslValue::Integer(l + r)),
1103 (DslValue::String(l), DslValue::String(r)) => Ok(DslValue::String(l + &r)),
1104 _ => Err(ReplError::Execution(
1105 "Invalid operands for addition".to_string(),
1106 )),
1107 },
1108 BinaryOperator::Subtract => match (left, right) {
1109 (DslValue::Number(l), DslValue::Number(r)) => Ok(DslValue::Number(l - r)),
1110 (DslValue::Integer(l), DslValue::Integer(r)) => Ok(DslValue::Integer(l - r)),
1111 _ => Err(ReplError::Execution(
1112 "Invalid operands for subtraction".to_string(),
1113 )),
1114 },
1115 BinaryOperator::Multiply => match (left, right) {
1116 (DslValue::Number(l), DslValue::Number(r)) => Ok(DslValue::Number(l * r)),
1117 (DslValue::Integer(l), DslValue::Integer(r)) => Ok(DslValue::Integer(l * r)),
1118 _ => Err(ReplError::Execution(
1119 "Invalid operands for multiplication".to_string(),
1120 )),
1121 },
1122 BinaryOperator::Divide => match (left, right) {
1123 (DslValue::Number(l), DslValue::Number(r)) => {
1124 if r == 0.0 {
1125 Err(ReplError::Execution("Division by zero".to_string()))
1126 } else {
1127 Ok(DslValue::Number(l / r))
1128 }
1129 }
1130 (DslValue::Integer(l), DslValue::Integer(r)) => {
1131 if r == 0 {
1132 Err(ReplError::Execution("Division by zero".to_string()))
1133 } else {
1134 Ok(DslValue::Integer(l / r))
1135 }
1136 }
1137 _ => Err(ReplError::Execution(
1138 "Invalid operands for division".to_string(),
1139 )),
1140 },
1141 BinaryOperator::Modulo => match (left, right) {
1142 (DslValue::Integer(l), DslValue::Integer(r)) => {
1143 if r == 0 {
1144 Err(ReplError::Execution("Modulo by zero".to_string()))
1145 } else {
1146 Ok(DslValue::Integer(l % r))
1147 }
1148 }
1149 _ => Err(ReplError::Execution(
1150 "Invalid operands for modulo".to_string(),
1151 )),
1152 },
1153 BinaryOperator::Equal => Ok(DslValue::Boolean(left == right)),
1154 BinaryOperator::NotEqual => Ok(DslValue::Boolean(left != right)),
1155 BinaryOperator::LessThan => match (left, right) {
1156 (DslValue::Number(l), DslValue::Number(r)) => Ok(DslValue::Boolean(l < r)),
1157 (DslValue::Integer(l), DslValue::Integer(r)) => Ok(DslValue::Boolean(l < r)),
1158 _ => Err(ReplError::Execution(
1159 "Invalid operands for comparison".to_string(),
1160 )),
1161 },
1162 BinaryOperator::LessThanOrEqual => match (left, right) {
1163 (DslValue::Number(l), DslValue::Number(r)) => Ok(DslValue::Boolean(l <= r)),
1164 (DslValue::Integer(l), DslValue::Integer(r)) => Ok(DslValue::Boolean(l <= r)),
1165 _ => Err(ReplError::Execution(
1166 "Invalid operands for comparison".to_string(),
1167 )),
1168 },
1169 BinaryOperator::GreaterThan => match (left, right) {
1170 (DslValue::Number(l), DslValue::Number(r)) => Ok(DslValue::Boolean(l > r)),
1171 (DslValue::Integer(l), DslValue::Integer(r)) => Ok(DslValue::Boolean(l > r)),
1172 _ => Err(ReplError::Execution(
1173 "Invalid operands for comparison".to_string(),
1174 )),
1175 },
1176 BinaryOperator::GreaterThanOrEqual => match (left, right) {
1177 (DslValue::Number(l), DslValue::Number(r)) => Ok(DslValue::Boolean(l >= r)),
1178 (DslValue::Integer(l), DslValue::Integer(r)) => Ok(DslValue::Boolean(l >= r)),
1179 _ => Err(ReplError::Execution(
1180 "Invalid operands for comparison".to_string(),
1181 )),
1182 },
1183 BinaryOperator::And => Ok(DslValue::Boolean(left.is_truthy() && right.is_truthy())),
1184 BinaryOperator::Or => Ok(DslValue::Boolean(left.is_truthy() || right.is_truthy())),
1185 BinaryOperator::BitwiseAnd => match (left, right) {
1187 (DslValue::Integer(l), DslValue::Integer(r)) => Ok(DslValue::Integer(l & r)),
1188 _ => Err(ReplError::Execution(
1189 "Bitwise AND requires integer operands".to_string(),
1190 )),
1191 },
1192 BinaryOperator::BitwiseOr => match (left, right) {
1193 (DslValue::Integer(l), DslValue::Integer(r)) => Ok(DslValue::Integer(l | r)),
1194 _ => Err(ReplError::Execution(
1195 "Bitwise OR requires integer operands".to_string(),
1196 )),
1197 },
1198 BinaryOperator::BitwiseXor => match (left, right) {
1199 (DslValue::Integer(l), DslValue::Integer(r)) => Ok(DslValue::Integer(l ^ r)),
1200 _ => Err(ReplError::Execution(
1201 "Bitwise XOR requires integer operands".to_string(),
1202 )),
1203 },
1204 BinaryOperator::LeftShift => match (left, right) {
1205 (DslValue::Integer(l), DslValue::Integer(r)) => {
1206 if !(0..=63).contains(&r) {
1207 Err(ReplError::Execution("Invalid shift amount".to_string()))
1208 } else {
1209 Ok(DslValue::Integer(l << r))
1210 }
1211 }
1212 _ => Err(ReplError::Execution(
1213 "Left shift requires integer operands".to_string(),
1214 )),
1215 },
1216 BinaryOperator::RightShift => match (left, right) {
1217 (DslValue::Integer(l), DslValue::Integer(r)) => {
1218 if !(0..=63).contains(&r) {
1219 Err(ReplError::Execution("Invalid shift amount".to_string()))
1220 } else {
1221 Ok(DslValue::Integer(l >> r))
1222 }
1223 }
1224 _ => Err(ReplError::Execution(
1225 "Right shift requires integer operands".to_string(),
1226 )),
1227 },
1228 }
1229 }
1230
1231 fn evaluate_unary_op(&self, operator: &UnaryOperator, operand: DslValue) -> Result<DslValue> {
1233 match operator {
1234 UnaryOperator::Not => Ok(DslValue::Boolean(!operand.is_truthy())),
1235 UnaryOperator::Negate => match operand {
1236 DslValue::Number(n) => Ok(DslValue::Number(-n)),
1237 DslValue::Integer(i) => Ok(DslValue::Integer(-i)),
1238 _ => Err(ReplError::Execution(
1239 "Invalid operand for negation".to_string(),
1240 )),
1241 },
1242 UnaryOperator::BitwiseNot => match operand {
1243 DslValue::Integer(i) => Ok(DslValue::Integer(!i)),
1244 _ => Err(ReplError::Execution(
1245 "Bitwise NOT requires integer operand".to_string(),
1246 )),
1247 },
1248 }
1249 }
1250
1251 async fn check_capability(&self, capability_name: &str) -> Result<bool> {
1253 let capability = match capability_name {
1254 "filesystem" => Capability::FileRead("/".to_string()), "network" => Capability::NetworkRequest("*".to_string()), "execute" => Capability::Execute("*".to_string()), "data" => Capability::DataRead("*".to_string()), _ => return Ok(false),
1259 };
1260
1261 let agent_id = "default";
1263 match self
1264 .runtime_bridge
1265 .check_capability(agent_id, &capability)
1266 .await
1267 {
1268 Ok(PolicyDecision::Allow) => Ok(true),
1269 Ok(PolicyDecision::Deny) => Ok(false),
1270 Err(e) => Err(ReplError::Runtime(format!(
1271 "Capability check failed: {}",
1272 e
1273 ))),
1274 }
1275 }
1276
1277 pub async fn get_agent(&self, agent_id: Uuid) -> Option<AgentInstance> {
1279 self.agents.read().await.get(&agent_id).cloned()
1280 }
1281
1282 pub async fn list_agents(&self) -> Vec<AgentInstance> {
1284 self.agents.read().await.values().cloned().collect()
1285 }
1286
1287 pub async fn start_agent(&self, agent_id: Uuid) -> Result<()> {
1289 let mut agents = self.agents.write().await;
1290 if let Some(agent) = agents.get_mut(&agent_id) {
1291 agent.state = AgentState::Starting;
1292
1293 self.monitor
1295 .log_agent_event(agent, TraceEventType::AgentStarted);
1296
1297 match self.runtime_bridge.initialize().await {
1299 Ok(_) => {
1300 agent.state = AgentState::Running;
1301 tracing::info!("Agent {} started and integrated with runtime", agent_id);
1302 Ok(())
1303 }
1304 Err(e) => {
1305 agent.state = AgentState::Failed(format!("Runtime integration failed: {}", e));
1306 tracing::error!("Failed to start agent {}: {}", agent_id, e);
1307 Err(ReplError::Runtime(format!("Failed to start agent: {}", e)))
1308 }
1309 }
1310 } else {
1311 Err(ReplError::Execution(format!(
1312 "Agent {} not found",
1313 agent_id
1314 )))
1315 }
1316 }
1317
1318 pub async fn stop_agent(&self, agent_id: Uuid) -> Result<()> {
1320 let mut agents = self.agents.write().await;
1321 if let Some(agent) = agents.get_mut(&agent_id) {
1322 agent.state = AgentState::Stopping;
1323 self.monitor
1325 .log_agent_event(agent, TraceEventType::AgentStopped);
1326
1327 agent.state = AgentState::Stopped;
1331 tracing::info!("Agent {} stopped", agent_id);
1332 Ok(())
1333 } else {
1334 Err(ReplError::Execution(format!(
1335 "Agent {} not found",
1336 agent_id
1337 )))
1338 }
1339 }
1340
1341 pub async fn pause_agent(&self, agent_id: Uuid) -> Result<()> {
1343 let mut agents = self.agents.write().await;
1344 if let Some(agent) = agents.get_mut(&agent_id) {
1345 match agent.state {
1346 AgentState::Running => {
1347 agent.state = AgentState::Paused;
1348 self.monitor
1349 .log_agent_event(agent, TraceEventType::AgentPaused);
1350 tracing::info!("Agent {} paused", agent_id);
1351 Ok(())
1352 }
1353 _ => Err(ReplError::Execution(format!(
1354 "Agent {} is not running",
1355 agent_id
1356 ))),
1357 }
1358 } else {
1359 Err(ReplError::Execution(format!(
1360 "Agent {} not found",
1361 agent_id
1362 )))
1363 }
1364 }
1365
1366 pub async fn resume_agent(&self, agent_id: Uuid) -> Result<()> {
1368 let mut agents = self.agents.write().await;
1369 if let Some(agent) = agents.get_mut(&agent_id) {
1370 match agent.state {
1371 AgentState::Paused => {
1372 agent.state = AgentState::Running;
1373 self.monitor
1374 .log_agent_event(agent, TraceEventType::AgentResumed);
1375 tracing::info!("Agent {} resumed", agent_id);
1376 Ok(())
1377 }
1378 _ => Err(ReplError::Execution(format!(
1379 "Agent {} is not paused",
1380 agent_id
1381 ))),
1382 }
1383 } else {
1384 Err(ReplError::Execution(format!(
1385 "Agent {} not found",
1386 agent_id
1387 )))
1388 }
1389 }
1390
1391 pub async fn destroy_agent(&self, agent_id: Uuid) -> Result<()> {
1393 let mut agents = self.agents.write().await;
1394 if let Some(agent) = agents.remove(&agent_id) {
1395 self.monitor
1396 .log_agent_event(&agent, TraceEventType::AgentDestroyed);
1397 tracing::info!("Agent {} destroyed", agent_id);
1398 Ok(())
1399 } else {
1400 Err(ReplError::Execution(format!(
1401 "Agent {} not found",
1402 agent_id
1403 )))
1404 }
1405 }
1406
1407 pub async fn execute_agent_behavior(
1409 &self,
1410 agent_id: Uuid,
1411 behavior_name: &str,
1412 args: &str,
1413 ) -> Result<DslValue> {
1414 let agent = {
1416 let agents = self.agents.read().await;
1417 agents
1418 .get(&agent_id)
1419 .cloned()
1420 .ok_or_else(|| ReplError::Execution(format!("Agent {} not found", agent_id)))?
1421 };
1422
1423 match agent.state {
1425 AgentState::Running => {}
1426 AgentState::Created => {
1427 return Err(ReplError::Execution(format!(
1428 "Agent {} is not started",
1429 agent_id
1430 )));
1431 }
1432 AgentState::Paused => {
1433 return Err(ReplError::Execution(format!(
1434 "Agent {} is paused",
1435 agent_id
1436 )));
1437 }
1438 AgentState::Stopped => {
1439 return Err(ReplError::Execution(format!(
1440 "Agent {} is stopped",
1441 agent_id
1442 )));
1443 }
1444 AgentState::Failed(ref reason) => {
1445 return Err(ReplError::Execution(format!(
1446 "Agent {} failed: {}",
1447 agent_id, reason
1448 )));
1449 }
1450 _ => {
1451 return Err(ReplError::Execution(format!(
1452 "Agent {} is not ready for execution",
1453 agent_id
1454 )));
1455 }
1456 }
1457
1458 let behavior = {
1460 let context_guard = self.global_context.lock().unwrap();
1461 let behavior = context_guard.functions.get(behavior_name).ok_or_else(|| {
1462 ReplError::Execution(format!("Behavior '{}' not found", behavior_name))
1463 })?;
1464 behavior.clone()
1465 };
1466
1467 let mut context = ExecutionContext {
1469 agent_id: Some(agent_id),
1470 ..ExecutionContext::default()
1471 };
1472
1473 if !args.is_empty() {
1475 context
1477 .variables
1478 .insert("args".to_string(), DslValue::String(args.to_string()));
1479 }
1480
1481 self.execute_function_with_policies(&behavior, &mut context)
1483 .await
1484 }
1485
1486 async fn execute_function_with_policies(
1488 &self,
1489 function: &FunctionDefinition,
1490 context: &mut ExecutionContext,
1491 ) -> Result<DslValue> {
1492 let execution_id = self
1494 .monitor
1495 .start_execution(context.agent_id, Some(function.name.clone()));
1496
1497 tracing::info!(
1499 "Executing function '{}' for agent {:?}",
1500 function.name,
1501 context.agent_id
1502 );
1503
1504 let result = match self.execute_block(&function.body, context).await? {
1506 ExecutionResult::Value(value) => Ok(value),
1507 ExecutionResult::Return(value) => Ok(value),
1508 ExecutionResult::Error(msg) => Err(ReplError::Execution(msg)),
1509 _ => Ok(DslValue::Null),
1510 };
1511
1512 match &result {
1514 Ok(value) => {
1515 self.monitor.end_execution(execution_id, Ok(value.clone()));
1516 }
1517 Err(error) => {
1518 let error_msg = format!("{}", error);
1519 self.monitor
1520 .end_execution(execution_id, Err(ReplError::Execution(error_msg)));
1521 }
1522 }
1523
1524 result
1525 }
1526
1527 pub async fn debug_agent(&self, agent_id: Uuid) -> Result<String> {
1529 let agents = self.agents.read().await;
1530 if let Some(agent) = agents.get(&agent_id) {
1531 let mut debug_info = String::new();
1532 debug_info.push_str("Agent Debug Information:\n");
1533 debug_info.push_str(&format!(" ID: {}\n", agent.id));
1534 debug_info.push_str(&format!(" Name: {}\n", agent.definition.name));
1535
1536 if let Some(version) = &agent.definition.metadata.version {
1537 debug_info.push_str(&format!(" Version: {}\n", version));
1538 }
1539
1540 debug_info.push_str(&format!(" State: {:?}\n", agent.state));
1541 debug_info.push_str(&format!(
1542 " Created: {}\n",
1543 agent.created_at.format("%Y-%m-%d %H:%M:%S UTC")
1544 ));
1545
1546 if let Some(description) = &agent.definition.metadata.description {
1547 debug_info.push_str(&format!(" Description: {}\n", description));
1548 }
1549
1550 if let Some(author) = &agent.definition.metadata.author {
1551 debug_info.push_str(&format!(" Author: {}\n", author));
1552 }
1553
1554 let context_guard = self.global_context.lock().unwrap();
1556 let function_count = context_guard.functions.len();
1557 drop(context_guard);
1558
1559 debug_info.push_str(&format!(
1560 " Available Functions/Behaviors: {}\n",
1561 function_count
1562 ));
1563
1564 if let Some(security) = &agent.definition.security {
1565 debug_info.push_str(&format!(
1566 " Required Capabilities: {}\n",
1567 security.capabilities.len()
1568 ));
1569 for cap in &security.capabilities {
1570 debug_info.push_str(&format!(" - {}\n", cap));
1571 }
1572 }
1573
1574 if let Some(resources) = &agent.definition.resources {
1575 debug_info.push_str(" Resource Configuration:\n");
1576 if let Some(memory) = &resources.memory {
1577 debug_info
1578 .push_str(&format!(" Memory: {}{:?}\n", memory.value, memory.unit));
1579 }
1580 if let Some(cpu) = &resources.cpu {
1581 debug_info.push_str(&format!(" CPU: {}{:?}\n", cpu.value, cpu.unit));
1582 }
1583 if let Some(network) = resources.network {
1584 debug_info.push_str(&format!(" Network: {}\n", network));
1585 }
1586 if let Some(storage) = &resources.storage {
1587 debug_info.push_str(&format!(
1588 " Storage: {}{:?}\n",
1589 storage.value, storage.unit
1590 ));
1591 }
1592 }
1593
1594 Ok(debug_info)
1595 } else {
1596 Err(ReplError::Execution(format!(
1597 "Agent {} not found",
1598 agent_id
1599 )))
1600 }
1601 }
1602
1603 pub async fn create_snapshot(&self) -> SessionSnapshot {
1605 let agents = self.agents.read().await.clone();
1606 let context = self.global_context.lock().unwrap().clone();
1607
1608 SessionSnapshot {
1609 id: Uuid::new_v4(),
1610 timestamp: chrono::Utc::now(),
1611 data: serde_json::json!({
1612 "agents": agents.iter().map(|(id, agent)| {
1613 (id.to_string(), serde_json::json!({
1614 "id": agent.id,
1615 "definition": agent.definition.name,
1616 "state": format!("{:?}", agent.state),
1617 "created_at": agent.created_at
1618 }))
1619 }).collect::<serde_json::Map<_, _>>(),
1620 "context": {
1621 "variables": context.variables.iter().map(|(k, v)| {
1622 (k.clone(), v.to_json())
1623 }).collect::<serde_json::Map<_, _>>(),
1624 "functions": context.functions.keys().collect::<Vec<_>>()
1625 }
1626 }),
1627 }
1628 }
1629
1630 pub async fn restore_snapshot(&self, snapshot: &SessionSnapshot) -> Result<()> {
1632 self.agents.write().await.clear();
1634 self.global_context.lock().unwrap().variables.clear();
1635 self.global_context.lock().unwrap().functions.clear();
1636
1637 if let Some(snapshot_data) = snapshot.data.as_object() {
1639 if let Some(agents_data) = snapshot_data.get("agents").and_then(|v| v.as_object()) {
1641 for (agent_id_str, agent_data) in agents_data {
1642 if let Ok(agent_id) = uuid::Uuid::parse_str(agent_id_str) {
1643 if let Some(_agent_obj) = agent_data.as_object() {
1644 tracing::info!("Restored agent {} from snapshot", agent_id);
1647 }
1648 }
1649 }
1650 }
1651
1652 if let Some(context_data) = snapshot_data.get("context").and_then(|v| v.as_object()) {
1654 if let Some(variables) = context_data.get("variables").and_then(|v| v.as_object()) {
1655 let mut context_guard = self.global_context.lock().unwrap();
1656 for (var_name, var_value) in variables {
1657 let dsl_value = Self::json_to_dsl_value(var_value);
1659 context_guard.variables.insert(var_name.clone(), dsl_value);
1660 }
1661 }
1662
1663 if let Some(functions) = context_data.get("functions").and_then(|v| v.as_array()) {
1666 tracing::info!(
1667 "Restored {} function definitions from snapshot",
1668 functions.len()
1669 );
1670 }
1671 }
1672 }
1673
1674 tracing::info!(
1675 "Successfully restored evaluator state from snapshot {}",
1676 snapshot.id
1677 );
1678 Ok(())
1679 }
1680
1681 fn json_to_dsl_value(json_value: &JsonValue) -> DslValue {
1683 match json_value {
1684 JsonValue::String(s) => DslValue::String(s.clone()),
1685 JsonValue::Number(n) => {
1686 if let Some(i) = n.as_i64() {
1687 DslValue::Integer(i)
1688 } else {
1689 DslValue::Number(n.as_f64().unwrap_or(0.0))
1690 }
1691 }
1692 JsonValue::Bool(b) => DslValue::Boolean(*b),
1693 JsonValue::Array(arr) => {
1694 let items = arr.iter().map(Self::json_to_dsl_value).collect();
1695 DslValue::List(items)
1696 }
1697 JsonValue::Object(obj) => {
1698 let mut entries = HashMap::new();
1699 for (k, v) in obj {
1700 entries.insert(k.clone(), Self::json_to_dsl_value(v));
1701 }
1702 DslValue::Map(entries)
1703 }
1704 JsonValue::Null => DslValue::Null,
1705 }
1706 }
1707
1708 async fn evaluate_invoke_expression(
1710 &self,
1711 invoke: &InvokeExpression,
1712 context: &mut ExecutionContext,
1713 ) -> Result<DslValue> {
1714 let behavior_name = &invoke.behavior;
1715
1716 let behavior_def = {
1718 let context_guard = self.global_context.lock().unwrap();
1719 context_guard
1720 .functions
1721 .get(behavior_name)
1722 .cloned()
1723 .ok_or_else(|| {
1724 ReplError::Execution(format!("Behavior '{}' not found", behavior_name))
1725 })?
1726 };
1727
1728 let mut arg_values = Vec::new();
1730 for param in &behavior_def.parameters.parameters {
1731 if let Some(arg_expr) = invoke.arguments.get(¶m.name) {
1732 arg_values.push(self.evaluate_expression_impl(arg_expr, context).await?);
1733 } else if let Some(default_expr) = ¶m.default_value {
1734 arg_values.push(self.evaluate_expression_impl(default_expr, context).await?);
1735 } else {
1736 return Err(ReplError::Execution(format!(
1737 "Missing argument for parameter '{}'",
1738 param.name
1739 )));
1740 }
1741 }
1742
1743 self.call_user_function(behavior_def, arg_values, context)
1745 .await
1746 }
1747
1748 async fn evaluate_lambda_expression(
1750 &self,
1751 lambda: &LambdaExpression,
1752 context: &mut ExecutionContext,
1753 ) -> Result<DslValue> {
1754 let captured_context = context.variables.clone();
1756
1757 let lambda_func = LambdaFunction {
1758 parameters: lambda.parameters.clone(),
1759 body: *lambda.body.clone(),
1760 captured_context,
1761 };
1762
1763 Ok(DslValue::Lambda(lambda_func))
1764 }
1765
1766 async fn _call_lambda(
1768 &self,
1769 lambda: &LambdaFunction,
1770 arguments: Vec<DslValue>,
1771 context: &mut ExecutionContext,
1772 ) -> Result<DslValue> {
1773 let mut new_context = context.clone();
1775 new_context.variables = lambda.captured_context.clone();
1776
1777 if arguments.len() != lambda.parameters.len() {
1779 return Err(ReplError::Execution(format!(
1780 "Lambda expects {} arguments, got {}",
1781 lambda.parameters.len(),
1782 arguments.len()
1783 )));
1784 }
1785
1786 for (param_name, arg_value) in lambda.parameters.iter().zip(arguments.iter()) {
1787 new_context
1788 .variables
1789 .insert(param_name.clone(), arg_value.clone());
1790 }
1791
1792 self.evaluate_expression_impl(&lambda.body, &mut new_context)
1794 .await
1795 }
1796
1797 fn pattern_matches(&self, pattern: &Pattern, value: &DslValue) -> bool {
1799 match pattern {
1800 Pattern::Literal(literal) => {
1801 if let Ok(literal_value) = self.evaluate_literal(literal) {
1802 &literal_value == value
1803 } else {
1804 false
1805 }
1806 }
1807 Pattern::Wildcard => true,
1808 Pattern::Identifier(_) => true, }
1810 }
1811}
1812
1813pub fn builtin_print(args: &[DslValue]) -> Result<DslValue> {
1815 let output = args
1816 .iter()
1817 .map(|v| match v {
1818 DslValue::String(s) => s.clone(),
1819 other => format!("{:?}", other),
1820 })
1821 .collect::<Vec<_>>()
1822 .join(" ");
1823
1824 println!("{}", output);
1825 Ok(DslValue::Null)
1826}
1827
1828pub fn builtin_len(args: &[DslValue]) -> Result<DslValue> {
1829 if args.len() != 1 {
1830 return Err(ReplError::Execution(
1831 "len() takes exactly one argument".to_string(),
1832 ));
1833 }
1834
1835 let len = match &args[0] {
1836 DslValue::String(s) => s.len() as i64,
1837 DslValue::List(items) => items.len() as i64,
1838 DslValue::Map(entries) => entries.len() as i64,
1839 _ => {
1840 return Err(ReplError::Execution(
1841 "len() requires string, list, or map".to_string(),
1842 ))
1843 }
1844 };
1845
1846 Ok(DslValue::Integer(len))
1847}
1848
1849pub fn builtin_upper(args: &[DslValue]) -> Result<DslValue> {
1850 if args.len() != 1 {
1851 return Err(ReplError::Execution(
1852 "upper() takes exactly one argument".to_string(),
1853 ));
1854 }
1855
1856 match &args[0] {
1857 DslValue::String(s) => Ok(DslValue::String(s.to_uppercase())),
1858 _ => Err(ReplError::Execution(
1859 "upper() requires string argument".to_string(),
1860 )),
1861 }
1862}
1863
1864pub fn builtin_lower(args: &[DslValue]) -> Result<DslValue> {
1865 if args.len() != 1 {
1866 return Err(ReplError::Execution(
1867 "lower() takes exactly one argument".to_string(),
1868 ));
1869 }
1870
1871 match &args[0] {
1872 DslValue::String(s) => Ok(DslValue::String(s.to_lowercase())),
1873 _ => Err(ReplError::Execution(
1874 "lower() requires string argument".to_string(),
1875 )),
1876 }
1877}
1878
1879pub fn builtin_format(args: &[DslValue]) -> Result<DslValue> {
1880 if args.is_empty() {
1881 return Err(ReplError::Execution(
1882 "format() requires at least one argument".to_string(),
1883 ));
1884 }
1885
1886 let format_str = match &args[0] {
1887 DslValue::String(s) => s,
1888 _ => {
1889 return Err(ReplError::Execution(
1890 "format() first argument must be string".to_string(),
1891 ))
1892 }
1893 };
1894
1895 let mut result = format_str.clone();
1897 for arg in &args[1..] {
1898 let placeholder = "{}";
1899 if let Some(pos) = result.find(placeholder) {
1900 let replacement = match arg {
1901 DslValue::String(s) => s.clone(),
1902 DslValue::Number(n) => n.to_string(),
1903 DslValue::Integer(i) => i.to_string(),
1904 DslValue::Boolean(b) => b.to_string(),
1905 other => format!("{:?}", other),
1906 };
1907 result.replace_range(pos..pos + placeholder.len(), &replacement);
1908 }
1909 }
1910
1911 Ok(DslValue::String(result))
1912}
1913
1914#[cfg(test)]
1915mod tests {
1916 use super::*;
1917 use crate::dsl::{lexer::Lexer, parser::Parser};
1918
1919 async fn create_test_evaluator() -> DslEvaluator {
1920 let runtime_bridge = Arc::new(RuntimeBridge::new_permissive_for_dev());
1921 DslEvaluator::new(runtime_bridge)
1922 }
1923
1924 async fn evaluate_source(source: &str) -> Result<DslValue> {
1925 let mut lexer = Lexer::new(source);
1926 let tokens = lexer.tokenize()?;
1927 let mut parser = Parser::new(tokens);
1928 let program = parser.parse()?;
1929
1930 let evaluator = create_test_evaluator().await;
1931 evaluator.execute_program(program).await
1932 }
1933
1934 #[tokio::test]
1935 async fn test_basic_arithmetic() {
1936 let result = evaluate_source(
1937 r#"
1938 function test() {
1939 return 2 + 3 * 4
1940 }
1941 "#,
1942 )
1943 .await
1944 .unwrap();
1945 assert_eq!(result, DslValue::Function("test".to_string()));
1946 }
1947
1948 #[tokio::test]
1949 async fn test_variable_assignment() {
1950 let result = evaluate_source(
1951 r#"
1952 function test() {
1953 let x = 42
1954 return x
1955 }
1956 "#,
1957 )
1958 .await
1959 .unwrap();
1960 assert_eq!(result, DslValue::Function("test".to_string()));
1961 }
1962
1963 #[tokio::test]
1964 async fn test_function_call() {
1965 let result = evaluate_source(
1966 r#"
1967 function add(a: number, b: number) -> number {
1968 return a + b
1969 }
1970 "#,
1971 )
1972 .await
1973 .unwrap();
1974 assert_eq!(result, DslValue::Function("add".to_string()));
1975 }
1976
1977 #[tokio::test]
1978 async fn test_builtin_functions() {
1979 let result = builtin_len(&[DslValue::String("hello".to_string())]);
1981 assert!(result.is_ok());
1982 assert_eq!(result.unwrap(), DslValue::Integer(5));
1983
1984 let result = builtin_upper(&[DslValue::String("hello".to_string())]);
1985 assert!(result.is_ok());
1986 assert_eq!(result.unwrap(), DslValue::String("HELLO".to_string()));
1987 }
1988}