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