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 async fn execute_program(&self, program: Program) -> Result<DslValue> {
393 let mut context = ExecutionContext::default();
394
395 for declaration in &program.declarations {
397 if let Declaration::Function(func) = declaration {
398 context.functions.insert(func.name.clone(), func.clone());
399 }
400 }
401
402 let mut last_value = DslValue::Null;
404 for declaration in &program.declarations {
405 match self.execute_declaration(declaration, &mut context).await? {
406 ExecutionResult::Value(value) => last_value = value,
407 ExecutionResult::Return(value) => return Ok(value),
408 ExecutionResult::Error(msg) => return Err(ReplError::Execution(msg)),
409 _ => {}
410 }
411 }
412
413 Ok(last_value)
414 }
415
416 async fn execute_declaration(
418 &self,
419 declaration: &Declaration,
420 context: &mut ExecutionContext,
421 ) -> Result<ExecutionResult> {
422 match declaration {
423 Declaration::Agent(agent_def) => self.create_agent(agent_def.clone(), context).await,
424 Declaration::Behavior(behavior_def) => {
425 let func_def = FunctionDefinition {
427 name: behavior_def.name.clone(),
428 parameters: behavior_def.input.clone().unwrap_or_default(),
429 return_type: behavior_def.output.as_ref().map(|_| Type::Any),
430 body: behavior_def.steps.clone(),
431 span: behavior_def.span.clone(),
432 };
433 context
434 .functions
435 .insert(behavior_def.name.clone(), func_def);
436 Ok(ExecutionResult::Value(DslValue::Function(
437 behavior_def.name.clone(),
438 )))
439 }
440 Declaration::Function(func_def) => {
441 context
442 .functions
443 .insert(func_def.name.clone(), func_def.clone());
444 Ok(ExecutionResult::Value(DslValue::Function(
445 func_def.name.clone(),
446 )))
447 }
448 Declaration::EventHandler(handler) => {
449 let agent_id = context.agent_id.unwrap_or_else(Uuid::new_v4);
451
452 match self
453 .runtime_bridge
454 .register_event_handler(
455 &agent_id.to_string(),
456 &handler.event_name,
457 &handler.event_name,
458 )
459 .await
460 {
461 Ok(_) => {
462 tracing::info!(
463 "Registered event handler '{}' for agent {}",
464 handler.event_name,
465 agent_id
466 );
467 Ok(ExecutionResult::Value(DslValue::Function(
468 handler.event_name.clone(),
469 )))
470 }
471 Err(e) => {
472 tracing::error!("Failed to register event handler: {}", e);
473 Err(ReplError::Runtime(format!(
474 "Failed to register event handler: {}",
475 e
476 )))
477 }
478 }
479 }
480 Declaration::Struct(struct_def) => {
481 let struct_info = format!("{}:{}", struct_def.name, struct_def.fields.len());
483 context.variables.insert(
484 format!("type_{}", struct_def.name),
485 DslValue::String(struct_info.clone()),
486 );
487
488 tracing::info!(
489 "Registered struct type '{}' with {} fields",
490 struct_def.name,
491 struct_def.fields.len()
492 );
493 Ok(ExecutionResult::Value(DslValue::String(format!(
494 "Struct({})",
495 struct_def.name
496 ))))
497 }
498 }
499 }
500
501 pub async fn create_agent(
503 &self,
504 agent_def: AgentDefinition,
505 context: &mut ExecutionContext,
506 ) -> Result<ExecutionResult> {
507 if let Some(security) = &agent_def.security {
509 for capability in &security.capabilities {
510 if !self.check_capability(capability).await? {
511 return Err(ReplError::Security(format!(
512 "Missing capability: {}",
513 capability
514 )));
515 }
516 }
517 }
518
519 let agent_id = Uuid::new_v4();
520 let agent = AgentInstance {
521 id: agent_id,
522 definition: agent_def.clone(),
523 state: AgentState::Created,
524 created_at: chrono::Utc::now(),
525 };
526
527 self.monitor
529 .log_agent_event(&agent, TraceEventType::AgentCreated);
530
531 self.agents.write().await.insert(agent_id, agent.clone());
533 context.agent_id = Some(agent_id);
534
535 tracing::info!("Agent '{}' created with ID {}", agent_def.name, agent_id);
536 Ok(ExecutionResult::Value(DslValue::Agent(Box::new(agent))))
537 }
538
539 fn execute_block<'a>(
541 &'a self,
542 block: &'a Block,
543 context: &'a mut ExecutionContext,
544 ) -> BoxFuture<'a, Result<ExecutionResult>> {
545 Box::pin(async move {
546 if context.depth >= context.max_depth {
547 return Err(ReplError::Execution(
548 "Maximum execution depth exceeded".to_string(),
549 ));
550 }
551
552 context.depth += 1;
553
554 let mut last_result = ExecutionResult::Value(DslValue::Null);
555
556 for statement in &block.statements {
557 match self.execute_statement(statement, context).await? {
558 ExecutionResult::Return(value) => {
559 context.depth -= 1;
560 return Ok(ExecutionResult::Return(value));
561 }
562 ExecutionResult::Break | ExecutionResult::Continue => {
563 context.depth -= 1;
564 return Ok(last_result);
565 }
566 ExecutionResult::Error(msg) => {
567 context.depth -= 1;
568 return Err(ReplError::Execution(msg));
569 }
570 result => last_result = result,
571 }
572 }
573
574 context.depth -= 1;
575 Ok(last_result)
576 })
577 }
578
579 async fn execute_statement(
581 &self,
582 statement: &Statement,
583 context: &mut ExecutionContext,
584 ) -> Result<ExecutionResult> {
585 match statement {
586 Statement::Let(let_stmt) => {
587 let value = self
588 .evaluate_expression_impl(&let_stmt.value, context)
589 .await?;
590 context.variables.insert(let_stmt.name.clone(), value);
591 Ok(ExecutionResult::Value(DslValue::Null))
592 }
593 Statement::If(if_stmt) => {
594 let condition = self
595 .evaluate_expression_impl(&if_stmt.condition, context)
596 .await?;
597
598 if condition.is_truthy() {
599 self.execute_block(&if_stmt.then_block, context).await
600 } else {
601 for else_if in &if_stmt.else_ifs {
603 let else_condition = self
604 .evaluate_expression_impl(&else_if.condition, context)
605 .await?;
606 if else_condition.is_truthy() {
607 return self.execute_block(&else_if.block, context).await;
608 }
609 }
610
611 if let Some(else_block) = &if_stmt.else_block {
613 self.execute_block(else_block, context).await
614 } else {
615 Ok(ExecutionResult::Value(DslValue::Null))
616 }
617 }
618 }
619 Statement::Return(ret_stmt) => {
620 let value = if let Some(expr) = &ret_stmt.value {
621 self.evaluate_expression_impl(expr, context).await?
622 } else {
623 DslValue::Null
624 };
625 Ok(ExecutionResult::Return(value))
626 }
627 Statement::Emit(emit_stmt) => {
628 let data = if let Some(expr) = &emit_stmt.data {
629 self.evaluate_expression_impl(expr, context).await?
630 } else {
631 DslValue::Null
632 };
633
634 let agent_id = context.agent_id.unwrap_or_else(Uuid::new_v4);
636
637 match self
638 .runtime_bridge
639 .emit_event(
640 &agent_id.to_string(),
641 &emit_stmt.event_name,
642 &data.to_json(),
643 )
644 .await
645 {
646 Ok(_) => {
647 tracing::info!(
648 "Successfully emitted event: {} with data: {:?}",
649 emit_stmt.event_name,
650 data
651 );
652 }
653 Err(e) => {
654 tracing::error!("Failed to emit event '{}': {}", emit_stmt.event_name, e);
655 return Err(ReplError::Runtime(format!("Failed to emit event: {}", e)));
656 }
657 }
658 Ok(ExecutionResult::Value(DslValue::Null))
659 }
660 Statement::Require(req_stmt) => {
661 match &req_stmt.requirement {
662 RequirementType::Capability(cap_name) => {
663 if !self.check_capability(cap_name).await? {
664 return Err(ReplError::Security(format!(
665 "Missing capability: {}",
666 cap_name
667 )));
668 }
669 }
670 RequirementType::Capabilities(cap_names) => {
671 for cap_name in cap_names {
672 if !self.check_capability(cap_name).await? {
673 return Err(ReplError::Security(format!(
674 "Missing capability: {}",
675 cap_name
676 )));
677 }
678 }
679 }
680 }
681 Ok(ExecutionResult::Value(DslValue::Null))
682 }
683 Statement::Expression(expr) => {
684 let value = self.evaluate_expression_impl(expr, context).await?;
685 Ok(ExecutionResult::Value(value))
686 }
687 Statement::Match(match_stmt) => {
689 let value = self
690 .evaluate_expression_impl(&match_stmt.expression, context)
691 .await?;
692
693 for arm in &match_stmt.arms {
694 if self.pattern_matches(&arm.pattern, &value) {
695 return self
696 .evaluate_expression_impl(&arm.body, context)
697 .await
698 .map(ExecutionResult::Value);
699 }
700 }
701
702 Err(ReplError::Execution(
704 "No matching pattern found".to_string(),
705 ))
706 }
707 Statement::For(for_stmt) => {
708 let iterable = self
709 .evaluate_expression_impl(&for_stmt.iterable, context)
710 .await?;
711
712 match iterable {
713 DslValue::List(items) => {
714 for item in items {
715 context.variables.insert(for_stmt.variable.clone(), item);
716 match self.execute_block(&for_stmt.body, context).await? {
717 ExecutionResult::Break => break,
718 ExecutionResult::Continue => continue,
719 ExecutionResult::Return(value) => {
720 return Ok(ExecutionResult::Return(value))
721 }
722 _ => {}
723 }
724 }
725 Ok(ExecutionResult::Value(DslValue::Null))
726 }
727 _ => Err(ReplError::Execution(
728 "For loop requires iterable value".to_string(),
729 )),
730 }
731 }
732 Statement::While(while_stmt) => {
733 loop {
734 let condition = self
735 .evaluate_expression_impl(&while_stmt.condition, context)
736 .await?;
737 if !condition.is_truthy() {
738 break;
739 }
740
741 match self.execute_block(&while_stmt.body, context).await? {
742 ExecutionResult::Break => break,
743 ExecutionResult::Continue => continue,
744 ExecutionResult::Return(value) => {
745 return Ok(ExecutionResult::Return(value))
746 }
747 _ => {}
748 }
749 }
750 Ok(ExecutionResult::Value(DslValue::Null))
751 }
752 Statement::Try(try_stmt) => {
753 match self.execute_block(&try_stmt.try_block, context).await {
755 Ok(result) => Ok(result),
756 Err(_) => {
757 self.execute_block(&try_stmt.catch_block, context).await
759 }
760 }
761 }
762 Statement::Check(check_stmt) => {
763 tracing::info!("Policy check for: {}", check_stmt.policy_name);
765 Ok(ExecutionResult::Value(DslValue::Boolean(true)))
766 }
767 }
768 }
769
770 pub async fn evaluate_expression(
772 &self,
773 expression: &Expression,
774 context: &mut ExecutionContext,
775 ) -> Result<DslValue> {
776 self.evaluate_expression_impl(expression, context).await
777 }
778
779 fn evaluate_expression_impl<'a>(
781 &'a self,
782 expression: &'a Expression,
783 context: &'a mut ExecutionContext,
784 ) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<DslValue>> + Send + 'a>> {
785 Box::pin(async move {
786 match expression {
787 Expression::Literal(literal) => self.evaluate_literal(literal),
788 Expression::Identifier(identifier) => {
789 if let Some(value) = context.variables.get(&identifier.name) {
790 Ok(value.clone())
791 } else {
792 Err(ReplError::Execution(format!(
793 "Undefined variable: {}",
794 identifier.name
795 )))
796 }
797 }
798 Expression::FieldAccess(field_access) => {
799 let object = self
800 .evaluate_expression_impl(&field_access.object, context)
801 .await?;
802 self.access_field(object, &field_access.field)
803 }
804 Expression::IndexAccess(index_access) => {
805 let object = self
806 .evaluate_expression_impl(&index_access.object, context)
807 .await?;
808 let index = self
809 .evaluate_expression_impl(&index_access.index, context)
810 .await?;
811 self.access_index(object, index)
812 }
813 Expression::FunctionCall(func_call) => {
814 self.call_function(&func_call.function, &func_call.arguments, context)
815 .await
816 }
817 Expression::MethodCall(method_call) => {
818 let object = self
819 .evaluate_expression_impl(&method_call.object, context)
820 .await?;
821 self.call_method(object, &method_call.method, &method_call.arguments, context)
822 .await
823 }
824 Expression::BinaryOp(binary_op) => {
825 let left = self
826 .evaluate_expression_impl(&binary_op.left, context)
827 .await?;
828 let right = self
829 .evaluate_expression_impl(&binary_op.right, context)
830 .await?;
831 self.evaluate_binary_op(&binary_op.operator, left, right)
832 }
833 Expression::UnaryOp(unary_op) => {
834 let operand = self
835 .evaluate_expression_impl(&unary_op.operand, context)
836 .await?;
837 self.evaluate_unary_op(&unary_op.operator, operand)
838 }
839 Expression::Assignment(assignment) => {
840 let value = self
841 .evaluate_expression_impl(&assignment.value, context)
842 .await?;
843
844 if let Expression::Identifier(identifier) = assignment.target.as_ref() {
845 context
846 .variables
847 .insert(identifier.name.clone(), value.clone());
848 Ok(value)
849 } else {
850 Err(ReplError::Execution(
851 "Invalid assignment target".to_string(),
852 ))
853 }
854 }
855 Expression::List(list_expr) => {
856 let mut items = Vec::new();
857 for element in &list_expr.elements {
858 items.push(self.evaluate_expression_impl(element, context).await?);
859 }
860 Ok(DslValue::List(items))
861 }
862 Expression::Map(map_expr) => {
863 let mut entries = HashMap::new();
864 for entry in &map_expr.entries {
865 let key = self.evaluate_expression_impl(&entry.key, context).await?;
866 let value = self.evaluate_expression_impl(&entry.value, context).await?;
867
868 if let DslValue::String(key_str) = key {
869 entries.insert(key_str, value);
870 } else {
871 return Err(ReplError::Execution(
872 "Map keys must be strings".to_string(),
873 ));
874 }
875 }
876 Ok(DslValue::Map(entries))
877 }
878 Expression::Invoke(invoke) => {
879 self.evaluate_invoke_expression(invoke, context).await
880 }
881 Expression::Lambda(lambda) => {
882 self.evaluate_lambda_expression(lambda, context).await
883 }
884 Expression::Conditional(conditional) => {
885 let condition = self
886 .evaluate_expression_impl(&conditional.condition, context)
887 .await?;
888
889 if condition.is_truthy() {
890 self.evaluate_expression_impl(&conditional.if_true, context)
891 .await
892 } else {
893 self.evaluate_expression_impl(&conditional.if_false, context)
894 .await
895 }
896 }
897 }
898 })
899 }
900
901 pub fn evaluate_literal(&self, literal: &Literal) -> Result<DslValue> {
903 match literal {
904 Literal::String(s) => Ok(DslValue::String(s.clone())),
905 Literal::Number(n) => Ok(DslValue::Number(*n)),
906 Literal::Integer(i) => Ok(DslValue::Integer(*i)),
907 Literal::Boolean(b) => Ok(DslValue::Boolean(*b)),
908 Literal::Duration(duration) => Ok(DslValue::Duration {
909 value: duration.value,
910 unit: duration.unit.clone(),
911 }),
912 Literal::Size(size) => Ok(DslValue::Size {
913 value: size.value,
914 unit: size.unit.clone(),
915 }),
916 Literal::Null => Ok(DslValue::Null),
917 }
918 }
919
920 fn access_field(&self, object: DslValue, field: &str) -> Result<DslValue> {
922 match object {
923 DslValue::Map(entries) => entries
924 .get(field)
925 .cloned()
926 .ok_or_else(|| ReplError::Execution(format!("Field '{}' not found", field))),
927 DslValue::Agent(agent) => match field {
928 "id" => Ok(DslValue::String(agent.id.to_string())),
929 "state" => Ok(DslValue::String(format!("{:?}", agent.state))),
930 "created_at" => Ok(DslValue::String(agent.created_at.to_rfc3339())),
931 _ => Err(ReplError::Execution(format!(
932 "Agent field '{}' not found",
933 field
934 ))),
935 },
936 _ => Err(ReplError::Execution(format!(
937 "Cannot access field on {}",
938 object.type_name()
939 ))),
940 }
941 }
942
943 fn access_index(&self, object: DslValue, index: DslValue) -> Result<DslValue> {
945 match (object, index) {
946 (DslValue::List(items), DslValue::Integer(i)) => {
947 let idx = if i < 0 { items.len() as i64 + i } else { i } as usize;
948
949 items
950 .get(idx)
951 .cloned()
952 .ok_or_else(|| ReplError::Execution("Index out of bounds".to_string()))
953 }
954 (DslValue::Map(entries), DslValue::String(key)) => entries
955 .get(&key)
956 .cloned()
957 .ok_or_else(|| ReplError::Execution(format!("Key '{}' not found", key))),
958 (obj, idx) => Err(ReplError::Execution(format!(
959 "Cannot index {} with {}",
960 obj.type_name(),
961 idx.type_name()
962 ))),
963 }
964 }
965
966 async fn call_function(
968 &self,
969 name: &str,
970 arguments: &[Expression],
971 context: &mut ExecutionContext,
972 ) -> Result<DslValue> {
973 let mut arg_values = Vec::new();
975 for arg in arguments {
976 arg_values.push(self.evaluate_expression_impl(arg, context).await?);
977 }
978
979 if let Some(builtin) = self.builtins.get(name) {
981 return builtin(&arg_values);
982 }
983
984 if let Some(async_builtin) = self.async_builtins.get(name) {
986 return async_builtin(arg_values).await;
987 }
988
989 if let Some(func_def) = context.functions.get(name).cloned() {
991 return self.call_user_function(func_def, arg_values, context).await;
992 }
993
994 Err(ReplError::Execution(format!("Unknown function: {}", name)))
995 }
996
997 async fn call_user_function(
999 &self,
1000 func_def: FunctionDefinition,
1001 arguments: Vec<DslValue>,
1002 context: &mut ExecutionContext,
1003 ) -> Result<DslValue> {
1004 let mut new_context = context.clone();
1006 new_context.variables.clear();
1007
1008 for (i, param) in func_def.parameters.parameters.iter().enumerate() {
1010 let value = match arguments.get(i) {
1011 Some(value) => value.clone(),
1012 None => {
1013 if let Some(default_expr) = ¶m.default_value {
1014 self.evaluate_expression_impl(default_expr, &mut new_context)
1016 .await?
1017 } else {
1018 return Err(ReplError::Execution(format!(
1019 "Missing argument for parameter '{}'",
1020 param.name
1021 )));
1022 }
1023 }
1024 };
1025
1026 new_context.variables.insert(param.name.clone(), value);
1027 }
1028
1029 match self.execute_block(&func_def.body, &mut new_context).await? {
1031 ExecutionResult::Value(value) => Ok(value),
1032 ExecutionResult::Return(value) => Ok(value),
1033 _ => Ok(DslValue::Null),
1034 }
1035 }
1036
1037 async fn call_method(
1039 &self,
1040 object: DslValue,
1041 method: &str,
1042 arguments: &[Expression],
1043 context: &mut ExecutionContext,
1044 ) -> Result<DslValue> {
1045 let mut arg_values = vec![object.clone()];
1046 for arg in arguments {
1047 arg_values.push(self.evaluate_expression(arg, context).await?);
1048 }
1049
1050 match (&object, method) {
1051 (DslValue::String(_), "upper") => builtin_upper(&[object]),
1052 (DslValue::String(_), "lower") => builtin_lower(&[object]),
1053 (DslValue::List(_) | DslValue::Map(_) | DslValue::String(_), "len") => {
1054 builtin_len(&[object])
1055 }
1056 _ => Err(ReplError::Execution(format!(
1057 "Method '{}' not found on {}",
1058 method,
1059 object.type_name()
1060 ))),
1061 }
1062 }
1063
1064 fn evaluate_binary_op(
1066 &self,
1067 operator: &BinaryOperator,
1068 left: DslValue,
1069 right: DslValue,
1070 ) -> Result<DslValue> {
1071 match operator {
1072 BinaryOperator::Add => match (left, right) {
1073 (DslValue::Number(l), DslValue::Number(r)) => Ok(DslValue::Number(l + r)),
1074 (DslValue::Integer(l), DslValue::Integer(r)) => Ok(DslValue::Integer(l + r)),
1075 (DslValue::String(l), DslValue::String(r)) => Ok(DslValue::String(l + &r)),
1076 _ => Err(ReplError::Execution(
1077 "Invalid operands for addition".to_string(),
1078 )),
1079 },
1080 BinaryOperator::Subtract => match (left, right) {
1081 (DslValue::Number(l), DslValue::Number(r)) => Ok(DslValue::Number(l - r)),
1082 (DslValue::Integer(l), DslValue::Integer(r)) => Ok(DslValue::Integer(l - r)),
1083 _ => Err(ReplError::Execution(
1084 "Invalid operands for subtraction".to_string(),
1085 )),
1086 },
1087 BinaryOperator::Multiply => match (left, right) {
1088 (DslValue::Number(l), DslValue::Number(r)) => Ok(DslValue::Number(l * r)),
1089 (DslValue::Integer(l), DslValue::Integer(r)) => Ok(DslValue::Integer(l * r)),
1090 _ => Err(ReplError::Execution(
1091 "Invalid operands for multiplication".to_string(),
1092 )),
1093 },
1094 BinaryOperator::Divide => match (left, right) {
1095 (DslValue::Number(l), DslValue::Number(r)) => {
1096 if r == 0.0 {
1097 Err(ReplError::Execution("Division by zero".to_string()))
1098 } else {
1099 Ok(DslValue::Number(l / r))
1100 }
1101 }
1102 (DslValue::Integer(l), DslValue::Integer(r)) => {
1103 if r == 0 {
1104 Err(ReplError::Execution("Division by zero".to_string()))
1105 } else {
1106 Ok(DslValue::Integer(l / r))
1107 }
1108 }
1109 _ => Err(ReplError::Execution(
1110 "Invalid operands for division".to_string(),
1111 )),
1112 },
1113 BinaryOperator::Modulo => match (left, right) {
1114 (DslValue::Integer(l), DslValue::Integer(r)) => {
1115 if r == 0 {
1116 Err(ReplError::Execution("Modulo by zero".to_string()))
1117 } else {
1118 Ok(DslValue::Integer(l % r))
1119 }
1120 }
1121 _ => Err(ReplError::Execution(
1122 "Invalid operands for modulo".to_string(),
1123 )),
1124 },
1125 BinaryOperator::Equal => Ok(DslValue::Boolean(left == right)),
1126 BinaryOperator::NotEqual => Ok(DslValue::Boolean(left != right)),
1127 BinaryOperator::LessThan => match (left, right) {
1128 (DslValue::Number(l), DslValue::Number(r)) => Ok(DslValue::Boolean(l < r)),
1129 (DslValue::Integer(l), DslValue::Integer(r)) => Ok(DslValue::Boolean(l < r)),
1130 _ => Err(ReplError::Execution(
1131 "Invalid operands for comparison".to_string(),
1132 )),
1133 },
1134 BinaryOperator::LessThanOrEqual => match (left, right) {
1135 (DslValue::Number(l), DslValue::Number(r)) => Ok(DslValue::Boolean(l <= r)),
1136 (DslValue::Integer(l), DslValue::Integer(r)) => Ok(DslValue::Boolean(l <= r)),
1137 _ => Err(ReplError::Execution(
1138 "Invalid operands for comparison".to_string(),
1139 )),
1140 },
1141 BinaryOperator::GreaterThan => match (left, right) {
1142 (DslValue::Number(l), DslValue::Number(r)) => Ok(DslValue::Boolean(l > r)),
1143 (DslValue::Integer(l), DslValue::Integer(r)) => Ok(DslValue::Boolean(l > r)),
1144 _ => Err(ReplError::Execution(
1145 "Invalid operands for comparison".to_string(),
1146 )),
1147 },
1148 BinaryOperator::GreaterThanOrEqual => match (left, right) {
1149 (DslValue::Number(l), DslValue::Number(r)) => Ok(DslValue::Boolean(l >= r)),
1150 (DslValue::Integer(l), DslValue::Integer(r)) => Ok(DslValue::Boolean(l >= r)),
1151 _ => Err(ReplError::Execution(
1152 "Invalid operands for comparison".to_string(),
1153 )),
1154 },
1155 BinaryOperator::And => Ok(DslValue::Boolean(left.is_truthy() && right.is_truthy())),
1156 BinaryOperator::Or => Ok(DslValue::Boolean(left.is_truthy() || right.is_truthy())),
1157 BinaryOperator::BitwiseAnd => match (left, right) {
1159 (DslValue::Integer(l), DslValue::Integer(r)) => Ok(DslValue::Integer(l & r)),
1160 _ => Err(ReplError::Execution(
1161 "Bitwise AND requires integer operands".to_string(),
1162 )),
1163 },
1164 BinaryOperator::BitwiseOr => match (left, right) {
1165 (DslValue::Integer(l), DslValue::Integer(r)) => Ok(DslValue::Integer(l | r)),
1166 _ => Err(ReplError::Execution(
1167 "Bitwise OR requires integer operands".to_string(),
1168 )),
1169 },
1170 BinaryOperator::BitwiseXor => match (left, right) {
1171 (DslValue::Integer(l), DslValue::Integer(r)) => Ok(DslValue::Integer(l ^ r)),
1172 _ => Err(ReplError::Execution(
1173 "Bitwise XOR requires integer operands".to_string(),
1174 )),
1175 },
1176 BinaryOperator::LeftShift => match (left, right) {
1177 (DslValue::Integer(l), DslValue::Integer(r)) => {
1178 if !(0..=63).contains(&r) {
1179 Err(ReplError::Execution("Invalid shift amount".to_string()))
1180 } else {
1181 Ok(DslValue::Integer(l << r))
1182 }
1183 }
1184 _ => Err(ReplError::Execution(
1185 "Left shift requires integer operands".to_string(),
1186 )),
1187 },
1188 BinaryOperator::RightShift => match (left, right) {
1189 (DslValue::Integer(l), DslValue::Integer(r)) => {
1190 if !(0..=63).contains(&r) {
1191 Err(ReplError::Execution("Invalid shift amount".to_string()))
1192 } else {
1193 Ok(DslValue::Integer(l >> r))
1194 }
1195 }
1196 _ => Err(ReplError::Execution(
1197 "Right shift requires integer operands".to_string(),
1198 )),
1199 },
1200 }
1201 }
1202
1203 fn evaluate_unary_op(&self, operator: &UnaryOperator, operand: DslValue) -> Result<DslValue> {
1205 match operator {
1206 UnaryOperator::Not => Ok(DslValue::Boolean(!operand.is_truthy())),
1207 UnaryOperator::Negate => match operand {
1208 DslValue::Number(n) => Ok(DslValue::Number(-n)),
1209 DslValue::Integer(i) => Ok(DslValue::Integer(-i)),
1210 _ => Err(ReplError::Execution(
1211 "Invalid operand for negation".to_string(),
1212 )),
1213 },
1214 UnaryOperator::BitwiseNot => match operand {
1215 DslValue::Integer(i) => Ok(DslValue::Integer(!i)),
1216 _ => Err(ReplError::Execution(
1217 "Bitwise NOT requires integer operand".to_string(),
1218 )),
1219 },
1220 }
1221 }
1222
1223 async fn check_capability(&self, capability_name: &str) -> Result<bool> {
1225 let capability = match capability_name {
1226 "filesystem" => Capability::FileRead("/".to_string()), "network" => Capability::NetworkRequest("*".to_string()), "execute" => Capability::Execute("*".to_string()), "data" => Capability::DataRead("*".to_string()), _ => return Ok(false),
1231 };
1232
1233 let agent_id = "default";
1235 match self
1236 .runtime_bridge
1237 .check_capability(agent_id, &capability)
1238 .await
1239 {
1240 Ok(PolicyDecision::Allow) => Ok(true),
1241 Ok(PolicyDecision::Deny) => Ok(false),
1242 Err(e) => Err(ReplError::Runtime(format!(
1243 "Capability check failed: {}",
1244 e
1245 ))),
1246 }
1247 }
1248
1249 pub async fn get_agent(&self, agent_id: Uuid) -> Option<AgentInstance> {
1251 self.agents.read().await.get(&agent_id).cloned()
1252 }
1253
1254 pub async fn list_agents(&self) -> Vec<AgentInstance> {
1256 self.agents.read().await.values().cloned().collect()
1257 }
1258
1259 pub async fn start_agent(&self, agent_id: Uuid) -> Result<()> {
1261 let mut agents = self.agents.write().await;
1262 if let Some(agent) = agents.get_mut(&agent_id) {
1263 agent.state = AgentState::Starting;
1264
1265 self.monitor
1267 .log_agent_event(agent, TraceEventType::AgentStarted);
1268
1269 match self.runtime_bridge.initialize().await {
1271 Ok(_) => {
1272 agent.state = AgentState::Running;
1273 tracing::info!("Agent {} started and integrated with runtime", agent_id);
1274 Ok(())
1275 }
1276 Err(e) => {
1277 agent.state = AgentState::Failed(format!("Runtime integration failed: {}", e));
1278 tracing::error!("Failed to start agent {}: {}", agent_id, e);
1279 Err(ReplError::Runtime(format!("Failed to start agent: {}", e)))
1280 }
1281 }
1282 } else {
1283 Err(ReplError::Execution(format!(
1284 "Agent {} not found",
1285 agent_id
1286 )))
1287 }
1288 }
1289
1290 pub async fn stop_agent(&self, agent_id: Uuid) -> Result<()> {
1292 let mut agents = self.agents.write().await;
1293 if let Some(agent) = agents.get_mut(&agent_id) {
1294 agent.state = AgentState::Stopping;
1295 self.monitor
1297 .log_agent_event(agent, TraceEventType::AgentStopped);
1298
1299 agent.state = AgentState::Stopped;
1303 tracing::info!("Agent {} stopped", agent_id);
1304 Ok(())
1305 } else {
1306 Err(ReplError::Execution(format!(
1307 "Agent {} not found",
1308 agent_id
1309 )))
1310 }
1311 }
1312
1313 pub async fn pause_agent(&self, agent_id: Uuid) -> Result<()> {
1315 let mut agents = self.agents.write().await;
1316 if let Some(agent) = agents.get_mut(&agent_id) {
1317 match agent.state {
1318 AgentState::Running => {
1319 agent.state = AgentState::Paused;
1320 self.monitor
1321 .log_agent_event(agent, TraceEventType::AgentPaused);
1322 tracing::info!("Agent {} paused", agent_id);
1323 Ok(())
1324 }
1325 _ => Err(ReplError::Execution(format!(
1326 "Agent {} is not running",
1327 agent_id
1328 ))),
1329 }
1330 } else {
1331 Err(ReplError::Execution(format!(
1332 "Agent {} not found",
1333 agent_id
1334 )))
1335 }
1336 }
1337
1338 pub async fn resume_agent(&self, agent_id: Uuid) -> Result<()> {
1340 let mut agents = self.agents.write().await;
1341 if let Some(agent) = agents.get_mut(&agent_id) {
1342 match agent.state {
1343 AgentState::Paused => {
1344 agent.state = AgentState::Running;
1345 self.monitor
1346 .log_agent_event(agent, TraceEventType::AgentResumed);
1347 tracing::info!("Agent {} resumed", agent_id);
1348 Ok(())
1349 }
1350 _ => Err(ReplError::Execution(format!(
1351 "Agent {} is not paused",
1352 agent_id
1353 ))),
1354 }
1355 } else {
1356 Err(ReplError::Execution(format!(
1357 "Agent {} not found",
1358 agent_id
1359 )))
1360 }
1361 }
1362
1363 pub async fn destroy_agent(&self, agent_id: Uuid) -> Result<()> {
1365 let mut agents = self.agents.write().await;
1366 if let Some(agent) = agents.remove(&agent_id) {
1367 self.monitor
1368 .log_agent_event(&agent, TraceEventType::AgentDestroyed);
1369 tracing::info!("Agent {} destroyed", agent_id);
1370 Ok(())
1371 } else {
1372 Err(ReplError::Execution(format!(
1373 "Agent {} not found",
1374 agent_id
1375 )))
1376 }
1377 }
1378
1379 pub async fn execute_agent_behavior(
1381 &self,
1382 agent_id: Uuid,
1383 behavior_name: &str,
1384 args: &str,
1385 ) -> Result<DslValue> {
1386 let agent = {
1388 let agents = self.agents.read().await;
1389 agents
1390 .get(&agent_id)
1391 .cloned()
1392 .ok_or_else(|| ReplError::Execution(format!("Agent {} not found", agent_id)))?
1393 };
1394
1395 match agent.state {
1397 AgentState::Running => {}
1398 AgentState::Created => {
1399 return Err(ReplError::Execution(format!(
1400 "Agent {} is not started",
1401 agent_id
1402 )));
1403 }
1404 AgentState::Paused => {
1405 return Err(ReplError::Execution(format!(
1406 "Agent {} is paused",
1407 agent_id
1408 )));
1409 }
1410 AgentState::Stopped => {
1411 return Err(ReplError::Execution(format!(
1412 "Agent {} is stopped",
1413 agent_id
1414 )));
1415 }
1416 AgentState::Failed(ref reason) => {
1417 return Err(ReplError::Execution(format!(
1418 "Agent {} failed: {}",
1419 agent_id, reason
1420 )));
1421 }
1422 _ => {
1423 return Err(ReplError::Execution(format!(
1424 "Agent {} is not ready for execution",
1425 agent_id
1426 )));
1427 }
1428 }
1429
1430 let behavior = {
1432 let context_guard = self.global_context.lock().unwrap();
1433 let behavior = context_guard.functions.get(behavior_name).ok_or_else(|| {
1434 ReplError::Execution(format!("Behavior '{}' not found", behavior_name))
1435 })?;
1436 behavior.clone()
1437 };
1438
1439 let mut context = ExecutionContext {
1441 agent_id: Some(agent_id),
1442 ..ExecutionContext::default()
1443 };
1444
1445 if !args.is_empty() {
1447 context
1449 .variables
1450 .insert("args".to_string(), DslValue::String(args.to_string()));
1451 }
1452
1453 self.execute_function_with_policies(&behavior, &mut context)
1455 .await
1456 }
1457
1458 async fn execute_function_with_policies(
1460 &self,
1461 function: &FunctionDefinition,
1462 context: &mut ExecutionContext,
1463 ) -> Result<DslValue> {
1464 let execution_id = self
1466 .monitor
1467 .start_execution(context.agent_id, Some(function.name.clone()));
1468
1469 tracing::info!(
1471 "Executing function '{}' for agent {:?}",
1472 function.name,
1473 context.agent_id
1474 );
1475
1476 let result = match self.execute_block(&function.body, context).await? {
1478 ExecutionResult::Value(value) => Ok(value),
1479 ExecutionResult::Return(value) => Ok(value),
1480 ExecutionResult::Error(msg) => Err(ReplError::Execution(msg)),
1481 _ => Ok(DslValue::Null),
1482 };
1483
1484 match &result {
1486 Ok(value) => {
1487 self.monitor.end_execution(execution_id, Ok(value.clone()));
1488 }
1489 Err(error) => {
1490 let error_msg = format!("{}", error);
1491 self.monitor
1492 .end_execution(execution_id, Err(ReplError::Execution(error_msg)));
1493 }
1494 }
1495
1496 result
1497 }
1498
1499 pub async fn debug_agent(&self, agent_id: Uuid) -> Result<String> {
1501 let agents = self.agents.read().await;
1502 if let Some(agent) = agents.get(&agent_id) {
1503 let mut debug_info = String::new();
1504 debug_info.push_str("Agent Debug Information:\n");
1505 debug_info.push_str(&format!(" ID: {}\n", agent.id));
1506 debug_info.push_str(&format!(" Name: {}\n", agent.definition.name));
1507
1508 if let Some(version) = &agent.definition.metadata.version {
1509 debug_info.push_str(&format!(" Version: {}\n", version));
1510 }
1511
1512 debug_info.push_str(&format!(" State: {:?}\n", agent.state));
1513 debug_info.push_str(&format!(
1514 " Created: {}\n",
1515 agent.created_at.format("%Y-%m-%d %H:%M:%S UTC")
1516 ));
1517
1518 if let Some(description) = &agent.definition.metadata.description {
1519 debug_info.push_str(&format!(" Description: {}\n", description));
1520 }
1521
1522 if let Some(author) = &agent.definition.metadata.author {
1523 debug_info.push_str(&format!(" Author: {}\n", author));
1524 }
1525
1526 let context_guard = self.global_context.lock().unwrap();
1528 let function_count = context_guard.functions.len();
1529 drop(context_guard);
1530
1531 debug_info.push_str(&format!(
1532 " Available Functions/Behaviors: {}\n",
1533 function_count
1534 ));
1535
1536 if let Some(security) = &agent.definition.security {
1537 debug_info.push_str(&format!(
1538 " Required Capabilities: {}\n",
1539 security.capabilities.len()
1540 ));
1541 for cap in &security.capabilities {
1542 debug_info.push_str(&format!(" - {}\n", cap));
1543 }
1544 }
1545
1546 if let Some(resources) = &agent.definition.resources {
1547 debug_info.push_str(" Resource Configuration:\n");
1548 if let Some(memory) = &resources.memory {
1549 debug_info
1550 .push_str(&format!(" Memory: {}{:?}\n", memory.value, memory.unit));
1551 }
1552 if let Some(cpu) = &resources.cpu {
1553 debug_info.push_str(&format!(" CPU: {}{:?}\n", cpu.value, cpu.unit));
1554 }
1555 if let Some(network) = resources.network {
1556 debug_info.push_str(&format!(" Network: {}\n", network));
1557 }
1558 if let Some(storage) = &resources.storage {
1559 debug_info.push_str(&format!(
1560 " Storage: {}{:?}\n",
1561 storage.value, storage.unit
1562 ));
1563 }
1564 }
1565
1566 Ok(debug_info)
1567 } else {
1568 Err(ReplError::Execution(format!(
1569 "Agent {} not found",
1570 agent_id
1571 )))
1572 }
1573 }
1574
1575 pub async fn create_snapshot(&self) -> SessionSnapshot {
1577 let agents = self.agents.read().await.clone();
1578 let context = self.global_context.lock().unwrap().clone();
1579
1580 SessionSnapshot {
1581 id: Uuid::new_v4(),
1582 timestamp: chrono::Utc::now(),
1583 data: serde_json::json!({
1584 "agents": agents.iter().map(|(id, agent)| {
1585 (id.to_string(), serde_json::json!({
1586 "id": agent.id,
1587 "definition": agent.definition.name,
1588 "state": format!("{:?}", agent.state),
1589 "created_at": agent.created_at
1590 }))
1591 }).collect::<serde_json::Map<_, _>>(),
1592 "context": {
1593 "variables": context.variables.iter().map(|(k, v)| {
1594 (k.clone(), v.to_json())
1595 }).collect::<serde_json::Map<_, _>>(),
1596 "functions": context.functions.keys().collect::<Vec<_>>()
1597 }
1598 }),
1599 }
1600 }
1601
1602 pub async fn restore_snapshot(&self, snapshot: &SessionSnapshot) -> Result<()> {
1604 self.agents.write().await.clear();
1606 self.global_context.lock().unwrap().variables.clear();
1607 self.global_context.lock().unwrap().functions.clear();
1608
1609 if let Some(snapshot_data) = snapshot.data.as_object() {
1611 if let Some(agents_data) = snapshot_data.get("agents").and_then(|v| v.as_object()) {
1613 for (agent_id_str, agent_data) in agents_data {
1614 if let Ok(agent_id) = uuid::Uuid::parse_str(agent_id_str) {
1615 if let Some(_agent_obj) = agent_data.as_object() {
1616 tracing::info!("Restored agent {} from snapshot", agent_id);
1619 }
1620 }
1621 }
1622 }
1623
1624 if let Some(context_data) = snapshot_data.get("context").and_then(|v| v.as_object()) {
1626 if let Some(variables) = context_data.get("variables").and_then(|v| v.as_object()) {
1627 let mut context_guard = self.global_context.lock().unwrap();
1628 for (var_name, var_value) in variables {
1629 let dsl_value = Self::json_to_dsl_value(var_value);
1631 context_guard.variables.insert(var_name.clone(), dsl_value);
1632 }
1633 }
1634
1635 if let Some(functions) = context_data.get("functions").and_then(|v| v.as_array()) {
1638 tracing::info!(
1639 "Restored {} function definitions from snapshot",
1640 functions.len()
1641 );
1642 }
1643 }
1644 }
1645
1646 tracing::info!(
1647 "Successfully restored evaluator state from snapshot {}",
1648 snapshot.id
1649 );
1650 Ok(())
1651 }
1652
1653 fn json_to_dsl_value(json_value: &JsonValue) -> DslValue {
1655 match json_value {
1656 JsonValue::String(s) => DslValue::String(s.clone()),
1657 JsonValue::Number(n) => {
1658 if let Some(i) = n.as_i64() {
1659 DslValue::Integer(i)
1660 } else {
1661 DslValue::Number(n.as_f64().unwrap_or(0.0))
1662 }
1663 }
1664 JsonValue::Bool(b) => DslValue::Boolean(*b),
1665 JsonValue::Array(arr) => {
1666 let items = arr.iter().map(Self::json_to_dsl_value).collect();
1667 DslValue::List(items)
1668 }
1669 JsonValue::Object(obj) => {
1670 let mut entries = HashMap::new();
1671 for (k, v) in obj {
1672 entries.insert(k.clone(), Self::json_to_dsl_value(v));
1673 }
1674 DslValue::Map(entries)
1675 }
1676 JsonValue::Null => DslValue::Null,
1677 }
1678 }
1679
1680 async fn evaluate_invoke_expression(
1682 &self,
1683 invoke: &InvokeExpression,
1684 context: &mut ExecutionContext,
1685 ) -> Result<DslValue> {
1686 let behavior_name = &invoke.behavior;
1687
1688 let behavior_def = {
1690 let context_guard = self.global_context.lock().unwrap();
1691 context_guard
1692 .functions
1693 .get(behavior_name)
1694 .cloned()
1695 .ok_or_else(|| {
1696 ReplError::Execution(format!("Behavior '{}' not found", behavior_name))
1697 })?
1698 };
1699
1700 let mut arg_values = Vec::new();
1702 for param in &behavior_def.parameters.parameters {
1703 if let Some(arg_expr) = invoke.arguments.get(¶m.name) {
1704 arg_values.push(self.evaluate_expression_impl(arg_expr, context).await?);
1705 } else if let Some(default_expr) = ¶m.default_value {
1706 arg_values.push(self.evaluate_expression_impl(default_expr, context).await?);
1707 } else {
1708 return Err(ReplError::Execution(format!(
1709 "Missing argument for parameter '{}'",
1710 param.name
1711 )));
1712 }
1713 }
1714
1715 self.call_user_function(behavior_def, arg_values, context)
1717 .await
1718 }
1719
1720 async fn evaluate_lambda_expression(
1722 &self,
1723 lambda: &LambdaExpression,
1724 context: &mut ExecutionContext,
1725 ) -> Result<DslValue> {
1726 let captured_context = context.variables.clone();
1728
1729 let lambda_func = LambdaFunction {
1730 parameters: lambda.parameters.clone(),
1731 body: *lambda.body.clone(),
1732 captured_context,
1733 };
1734
1735 Ok(DslValue::Lambda(lambda_func))
1736 }
1737
1738 async fn _call_lambda(
1740 &self,
1741 lambda: &LambdaFunction,
1742 arguments: Vec<DslValue>,
1743 context: &mut ExecutionContext,
1744 ) -> Result<DslValue> {
1745 let mut new_context = context.clone();
1747 new_context.variables = lambda.captured_context.clone();
1748
1749 if arguments.len() != lambda.parameters.len() {
1751 return Err(ReplError::Execution(format!(
1752 "Lambda expects {} arguments, got {}",
1753 lambda.parameters.len(),
1754 arguments.len()
1755 )));
1756 }
1757
1758 for (param_name, arg_value) in lambda.parameters.iter().zip(arguments.iter()) {
1759 new_context
1760 .variables
1761 .insert(param_name.clone(), arg_value.clone());
1762 }
1763
1764 self.evaluate_expression_impl(&lambda.body, &mut new_context)
1766 .await
1767 }
1768
1769 fn pattern_matches(&self, pattern: &Pattern, value: &DslValue) -> bool {
1771 match pattern {
1772 Pattern::Literal(literal) => {
1773 if let Ok(literal_value) = self.evaluate_literal(literal) {
1774 &literal_value == value
1775 } else {
1776 false
1777 }
1778 }
1779 Pattern::Wildcard => true,
1780 Pattern::Identifier(_) => true, }
1782 }
1783}
1784
1785pub fn builtin_print(args: &[DslValue]) -> Result<DslValue> {
1787 let output = args
1788 .iter()
1789 .map(|v| match v {
1790 DslValue::String(s) => s.clone(),
1791 other => format!("{:?}", other),
1792 })
1793 .collect::<Vec<_>>()
1794 .join(" ");
1795
1796 println!("{}", output);
1797 Ok(DslValue::Null)
1798}
1799
1800pub fn builtin_len(args: &[DslValue]) -> Result<DslValue> {
1801 if args.len() != 1 {
1802 return Err(ReplError::Execution(
1803 "len() takes exactly one argument".to_string(),
1804 ));
1805 }
1806
1807 let len = match &args[0] {
1808 DslValue::String(s) => s.len() as i64,
1809 DslValue::List(items) => items.len() as i64,
1810 DslValue::Map(entries) => entries.len() as i64,
1811 _ => {
1812 return Err(ReplError::Execution(
1813 "len() requires string, list, or map".to_string(),
1814 ))
1815 }
1816 };
1817
1818 Ok(DslValue::Integer(len))
1819}
1820
1821pub fn builtin_upper(args: &[DslValue]) -> Result<DslValue> {
1822 if args.len() != 1 {
1823 return Err(ReplError::Execution(
1824 "upper() takes exactly one argument".to_string(),
1825 ));
1826 }
1827
1828 match &args[0] {
1829 DslValue::String(s) => Ok(DslValue::String(s.to_uppercase())),
1830 _ => Err(ReplError::Execution(
1831 "upper() requires string argument".to_string(),
1832 )),
1833 }
1834}
1835
1836pub fn builtin_lower(args: &[DslValue]) -> Result<DslValue> {
1837 if args.len() != 1 {
1838 return Err(ReplError::Execution(
1839 "lower() takes exactly one argument".to_string(),
1840 ));
1841 }
1842
1843 match &args[0] {
1844 DslValue::String(s) => Ok(DslValue::String(s.to_lowercase())),
1845 _ => Err(ReplError::Execution(
1846 "lower() requires string argument".to_string(),
1847 )),
1848 }
1849}
1850
1851pub fn builtin_format(args: &[DslValue]) -> Result<DslValue> {
1852 if args.is_empty() {
1853 return Err(ReplError::Execution(
1854 "format() requires at least one argument".to_string(),
1855 ));
1856 }
1857
1858 let format_str = match &args[0] {
1859 DslValue::String(s) => s,
1860 _ => {
1861 return Err(ReplError::Execution(
1862 "format() first argument must be string".to_string(),
1863 ))
1864 }
1865 };
1866
1867 let mut result = format_str.clone();
1869 for arg in &args[1..] {
1870 let placeholder = "{}";
1871 if let Some(pos) = result.find(placeholder) {
1872 let replacement = match arg {
1873 DslValue::String(s) => s.clone(),
1874 DslValue::Number(n) => n.to_string(),
1875 DslValue::Integer(i) => i.to_string(),
1876 DslValue::Boolean(b) => b.to_string(),
1877 other => format!("{:?}", other),
1878 };
1879 result.replace_range(pos..pos + placeholder.len(), &replacement);
1880 }
1881 }
1882
1883 Ok(DslValue::String(result))
1884}
1885
1886#[cfg(test)]
1887mod tests {
1888 use super::*;
1889 use crate::dsl::{lexer::Lexer, parser::Parser};
1890
1891 async fn create_test_evaluator() -> DslEvaluator {
1892 let runtime_bridge = Arc::new(RuntimeBridge::new());
1893 DslEvaluator::new(runtime_bridge)
1894 }
1895
1896 async fn evaluate_source(source: &str) -> Result<DslValue> {
1897 let mut lexer = Lexer::new(source);
1898 let tokens = lexer.tokenize()?;
1899 let mut parser = Parser::new(tokens);
1900 let program = parser.parse()?;
1901
1902 let evaluator = create_test_evaluator().await;
1903 evaluator.execute_program(program).await
1904 }
1905
1906 #[tokio::test]
1907 async fn test_basic_arithmetic() {
1908 let result = evaluate_source(
1909 r#"
1910 function test() {
1911 return 2 + 3 * 4
1912 }
1913 "#,
1914 )
1915 .await
1916 .unwrap();
1917 assert_eq!(result, DslValue::Function("test".to_string()));
1918 }
1919
1920 #[tokio::test]
1921 async fn test_variable_assignment() {
1922 let result = evaluate_source(
1923 r#"
1924 function test() {
1925 let x = 42
1926 return x
1927 }
1928 "#,
1929 )
1930 .await
1931 .unwrap();
1932 assert_eq!(result, DslValue::Function("test".to_string()));
1933 }
1934
1935 #[tokio::test]
1936 async fn test_function_call() {
1937 let result = evaluate_source(
1938 r#"
1939 function add(a: number, b: number) -> number {
1940 return a + b
1941 }
1942 "#,
1943 )
1944 .await
1945 .unwrap();
1946 assert_eq!(result, DslValue::Function("add".to_string()));
1947 }
1948
1949 #[tokio::test]
1950 async fn test_builtin_functions() {
1951 let result = builtin_len(&[DslValue::String("hello".to_string())]);
1953 assert!(result.is_ok());
1954 assert_eq!(result.unwrap(), DslValue::Integer(5));
1955
1956 let result = builtin_upper(&[DslValue::String("hello".to_string())]);
1957 assert!(result.is_ok());
1958 assert_eq!(result.unwrap(), DslValue::String("HELLO".to_string()));
1959 }
1960}