1use crate::memory::SymbolicContext;
4use anyhow::Result;
5use std::collections::HashMap;
6
7pub struct OperatorMetadata {
9 pub name: String,
10 pub description: String,
11 pub category: String,
12}
13
14pub struct UncertaintyModel {
16 pub entropy: f64,
17 pub source: String,
18}
19
20pub trait SomaOperator {
22 fn execute(&self, inputs: &SymbolicContext) -> Result<SymbolicContext>;
24 fn metadata(&self) -> OperatorMetadata;
26 fn cognitive_cost(&self) -> f64;
28 fn uncertainty_propagation(&self) -> UncertaintyModel;
30}
31
32pub struct ComposeOperator;
34
35impl SomaOperator for ComposeOperator {
36 fn execute(&self, inputs: &SymbolicContext) -> Result<SymbolicContext> {
37 let a = inputs.resolve_or_default("a", "");
38 let b = inputs.resolve_or_default("b", "");
39 let mut ctx = SymbolicContext::new();
40 ctx.set("c", &format!("{}{}", a, b));
41 Ok(ctx)
42 }
43
44 fn metadata(&self) -> OperatorMetadata {
45 OperatorMetadata {
46 name: "compose".to_string(),
47 description: "Concatenates two symbolic inputs".to_string(),
48 category: "string".to_string(),
49 }
50 }
51
52 fn cognitive_cost(&self) -> f64 {
53 1.0
54 }
55
56 fn uncertainty_propagation(&self) -> UncertaintyModel {
57 UncertaintyModel {
58 entropy: 0.01,
59 source: "string_merge".to_string(),
60 }
61 }
62}
63
64pub struct AddOperator;
66
67impl SomaOperator for AddOperator {
68 fn execute(&self, inputs: &SymbolicContext) -> Result<SymbolicContext> {
69 let x = inputs
70 .resolve_or_default("x", "0")
71 .parse::<f64>()
72 .unwrap_or(0.0);
73 let y = inputs
74 .resolve_or_default("y", "0")
75 .parse::<f64>()
76 .unwrap_or(0.0);
77 let mut ctx = SymbolicContext::new();
78 ctx.set("sum", &format!("{}", x + y));
79 Ok(ctx)
80 }
81 fn metadata(&self) -> OperatorMetadata {
82 OperatorMetadata {
83 name: "add".to_string(),
84 description: "Adds two numbers (x, y) from the context and stores 'sum'.".to_string(),
85 category: "math".to_string(),
86 }
87 }
88 fn cognitive_cost(&self) -> f64 {
89 0.4
90 }
91 fn uncertainty_propagation(&self) -> UncertaintyModel {
92 UncertaintyModel {
93 entropy: 0.001,
94 source: "numeric_addition".to_string(),
95 }
96 }
97}
98
99pub struct IfThenOperator;
101
102impl SomaOperator for IfThenOperator {
103 fn execute(&self, inputs: &SymbolicContext) -> Result<SymbolicContext> {
104 let cond = inputs.resolve_or_default("condition", "false");
105 let then_val = inputs.resolve_or_default("then", "");
106 let else_val = inputs.resolve_or_default("else", "");
107 let mut ctx = SymbolicContext::new();
108 let result = match cond.as_str() {
109 "true" | "1" => then_val,
110 _ => else_val,
111 };
112 ctx.set("result", &result);
113 Ok(ctx)
114 }
115 fn metadata(&self) -> OperatorMetadata {
116 OperatorMetadata {
117 name: "if_then".to_string(),
118 description: "Checks 'condition' and sets 'result' to 'then' or 'else'.".to_string(),
119 category: "logic".to_string(),
120 }
121 }
122 fn cognitive_cost(&self) -> f64 {
123 0.6
124 }
125 fn uncertainty_propagation(&self) -> UncertaintyModel {
126 UncertaintyModel {
127 entropy: 0.02,
128 source: "conditional_branch".to_string(),
129 }
130 }
131}
132
133pub struct ReflectOperator;
135
136impl SomaOperator for ReflectOperator {
137 fn execute(&self, inputs: &SymbolicContext) -> Result<SymbolicContext> {
138 let keys: Vec<_> = inputs.flatten().keys().cloned().collect();
139 let mut ctx = SymbolicContext::new();
140 ctx.set("summary", &format!("Keys: [{}]", keys.join(", ")));
141 Ok(ctx)
142 }
143 fn metadata(&self) -> OperatorMetadata {
144 OperatorMetadata {
145 name: "reflect".to_string(),
146 description: "Summarizes input context keys into 'summary'.".to_string(),
147 category: "meta".to_string(),
148 }
149 }
150 fn cognitive_cost(&self) -> f64 {
151 0.8
152 }
153 fn uncertainty_propagation(&self) -> UncertaintyModel {
154 UncertaintyModel {
155 entropy: 0.05,
156 source: "symbolic_reflection".to_string(),
157 }
158 }
159}
160
161pub struct DelayOperator;
163
164impl SomaOperator for DelayOperator {
165 fn execute(&self, inputs: &SymbolicContext) -> Result<SymbolicContext> {
166 use std::{thread, time::Duration};
167 let ms = inputs
168 .resolve_or_default("delay_ms", "100")
169 .parse::<u64>()
170 .unwrap_or(100);
171 thread::sleep(Duration::from_millis(ms));
172 let mut ctx = SymbolicContext::new();
173 ctx.set("delayed", &format!("{}ms", ms));
174 Ok(ctx)
175 }
176 fn metadata(&self) -> OperatorMetadata {
177 OperatorMetadata {
178 name: "delay".to_string(),
179 description: "Sleeps for N milliseconds (from 'delay_ms').".to_string(),
180 category: "utility".to_string(),
181 }
182 }
183 fn cognitive_cost(&self) -> f64 {
184 0.2
185 }
186 fn uncertainty_propagation(&self) -> UncertaintyModel {
187 UncertaintyModel {
188 entropy: 0.0,
189 source: "simulated_delay".to_string(),
190 }
191 }
192}
193
194pub struct UncertaintyPropagateOperator;
198
199impl SomaOperator for UncertaintyPropagateOperator {
200 fn execute(&self, inputs: &SymbolicContext) -> Result<SymbolicContext> {
201 let entropy = inputs
202 .resolve_or_default("entropy", "0.1")
203 .parse::<f64>()
204 .unwrap_or(0.1);
205 let confidence = inputs
206 .resolve_or_default("confidence", "0.9")
207 .parse::<f64>()
208 .unwrap_or(0.9);
209
210 let propagated_entropy = entropy * 1.05; let propagated_confidence = confidence * 0.98; let mut ctx = SymbolicContext::new();
215 ctx.set("propagated_entropy", &format!("{:.3}", propagated_entropy));
216 ctx.set(
217 "propagated_confidence",
218 &format!("{:.3}", propagated_confidence),
219 );
220 ctx.set("uncertainty_source", "propagated");
221
222 for (key, value) in inputs.flatten() {
224 if !key.starts_with("entropy") && !key.starts_with("confidence") {
225 ctx.set(&format!("{}_uncertain", key), &value);
226 }
227 }
228
229 Ok(ctx)
230 }
231
232 fn metadata(&self) -> OperatorMetadata {
233 OperatorMetadata {
234 name: "uncertainty_propagate".to_string(),
235 description: "Propagates entropy/confidence metadata across symbolic DAG paths"
236 .to_string(),
237 category: "uncertainty".to_string(),
238 }
239 }
240
241 fn cognitive_cost(&self) -> f64 {
242 0.7
243 }
244
245 fn uncertainty_propagation(&self) -> UncertaintyModel {
246 UncertaintyModel {
247 entropy: 0.15,
248 source: "uncertainty_propagation".to_string(),
249 }
250 }
251}
252
253pub struct DoubtOperator;
255
256impl SomaOperator for DoubtOperator {
257 fn execute(&self, inputs: &SymbolicContext) -> Result<SymbolicContext> {
258 let confidence = inputs
259 .resolve_or_default("confidence", "1.0")
260 .parse::<f64>()
261 .unwrap_or(1.0);
262 let threshold = inputs
263 .resolve_or_default("doubt_threshold", "0.5")
264 .parse::<f64>()
265 .unwrap_or(0.5);
266
267 let mut ctx = SymbolicContext::new();
268 let flagged = confidence < threshold;
269
270 ctx.set("confidence", &confidence.to_string());
271 ctx.set("flagged", &flagged.to_string());
272 ctx.set(
273 "doubt_reason",
274 if flagged {
275 "confidence_below_threshold"
276 } else {
277 "confidence_acceptable"
278 },
279 );
280
281 if flagged {
282 ctx.set("verification_required", "true");
283 ctx.set("doubt_level", &format!("{:.3}", threshold - confidence));
284 }
285
286 Ok(ctx)
287 }
288
289 fn metadata(&self) -> OperatorMetadata {
290 OperatorMetadata {
291 name: "doubt".to_string(),
292 description: "Flags nodes for verification if confidence < threshold".to_string(),
293 category: "uncertainty".to_string(),
294 }
295 }
296
297 fn cognitive_cost(&self) -> f64 {
298 0.3
299 }
300
301 fn uncertainty_propagation(&self) -> UncertaintyModel {
302 UncertaintyModel {
303 entropy: 0.08,
304 source: "doubt_analysis".to_string(),
305 }
306 }
307}
308
309pub struct IntrospectOperator;
313
314impl SomaOperator for IntrospectOperator {
315 fn execute(&self, inputs: &SymbolicContext) -> Result<SymbolicContext> {
316 let context_map = inputs.flatten();
317 let key_count = context_map.len();
318 let total_size: usize = context_map.values().map(|v| v.len()).sum();
319
320 let depth_estimate = (key_count as f64).log2().ceil() as i32;
322 let branching_factor = if key_count > 0 {
323 total_size / key_count
324 } else {
325 0
326 };
327 let complexity_score = key_count as f64 * 0.1 + branching_factor as f64 * 0.05;
328
329 let mut ctx = SymbolicContext::new();
330 ctx.set("reasoning_depth", &depth_estimate.to_string());
331 ctx.set("branching_factor", &branching_factor.to_string());
332 ctx.set("complexity_score", &format!("{:.3}", complexity_score));
333 ctx.set("context_size", &key_count.to_string());
334
335 let bottleneck = if complexity_score > 5.0 {
337 "high_complexity"
338 } else if branching_factor > 50 {
339 "high_branching"
340 } else if key_count > 20 {
341 "context_overflow"
342 } else {
343 "none"
344 };
345
346 ctx.set("bottleneck_detected", bottleneck);
347 let timestamp = std::time::SystemTime::now()
348 .duration_since(std::time::UNIX_EPOCH)
349 .unwrap()
350 .as_secs();
351 ctx.set("introspection_timestamp", ×tamp.to_string());
352
353 Ok(ctx)
354 }
355
356 fn metadata(&self) -> OperatorMetadata {
357 OperatorMetadata {
358 name: "introspect".to_string(),
359 description: "Analyzes reasoning paths and detects cognitive bottlenecks".to_string(),
360 category: "meta".to_string(),
361 }
362 }
363
364 fn cognitive_cost(&self) -> f64 {
365 1.2
366 }
367
368 fn uncertainty_propagation(&self) -> UncertaintyModel {
369 UncertaintyModel {
370 entropy: 0.03,
371 source: "introspective_analysis".to_string(),
372 }
373 }
374}
375
376pub struct CognitiveLoadOperator;
378
379impl SomaOperator for CognitiveLoadOperator {
380 fn execute(&self, inputs: &SymbolicContext) -> Result<SymbolicContext> {
381 let context_map = inputs.flatten();
382
383 let memory_keys = context_map.len();
385 let total_content_size: usize = context_map.values().map(|v| v.len()).sum();
386 let nested_keys = context_map.keys().filter(|k| k.contains('.')).count();
387
388 let base_load = memory_keys as f64 * 0.2;
390 let content_load = (total_content_size as f64 / 100.0).sqrt();
391 let nesting_load = nested_keys as f64 * 0.5;
392 let load_score = base_load + content_load + nesting_load;
393
394 let mut ctx = SymbolicContext::new();
395 ctx.set("memory_keys", &memory_keys.to_string());
396 ctx.set("content_size", &total_content_size.to_string());
397 ctx.set("nested_keys", &nested_keys.to_string());
398 ctx.set("load_score", &format!("{:.3}", load_score));
399
400 let load_level = if load_score > 10.0 {
402 "critical"
403 } else if load_score > 5.0 {
404 "high"
405 } else if load_score > 2.0 {
406 "moderate"
407 } else {
408 "low"
409 };
410
411 ctx.set("load_level", load_level);
412 ctx.set("optimization_needed", &(load_score > 5.0).to_string());
413
414 Ok(ctx)
415 }
416
417 fn metadata(&self) -> OperatorMetadata {
418 OperatorMetadata {
419 name: "cognitive_load".to_string(),
420 description: "Estimates symbolic complexity of current reasoning state".to_string(),
421 category: "meta".to_string(),
422 }
423 }
424
425 fn cognitive_cost(&self) -> f64 {
426 0.6
427 }
428
429 fn uncertainty_propagation(&self) -> UncertaintyModel {
430 UncertaintyModel {
431 entropy: 0.02,
432 source: "cognitive_load_estimation".to_string(),
433 }
434 }
435}
436
437pub struct AttentionFocusOperator;
439
440impl SomaOperator for AttentionFocusOperator {
441 fn execute(&self, inputs: &SymbolicContext) -> Result<SymbolicContext> {
442 let context_map = inputs.flatten();
443 let current_timestamp = std::time::SystemTime::now()
444 .duration_since(std::time::UNIX_EPOCH)
445 .unwrap()
446 .as_secs() as i64;
447
448 let mut focus_weights: Vec<(String, f64)> = Vec::new();
449
450 for (key, value) in &context_map {
451 let recency_weight = if key.contains("timestamp") {
453 let timestamp = value.parse::<i64>().unwrap_or(0);
454 let age_seconds = current_timestamp - timestamp;
455 (1.0 / (1.0 + age_seconds as f64 / 3600.0)).max(0.1) } else {
457 0.5 };
459
460 let semantic_weight = match key.as_str() {
461 k if k.contains("goal") || k.contains("target") => 1.0,
462 k if k.contains("error") || k.contains("problem") => 0.9,
463 k if k.contains("result") || k.contains("output") => 0.8,
464 k if k.contains("input") || k.contains("param") => 0.7,
465 _ => 0.6,
466 };
467
468 let content_weight = (value.len() as f64 / 100.0).clamp(0.1, 1.0);
469
470 let combined_weight = (recency_weight + semantic_weight + content_weight) / 3.0;
471 focus_weights.push((key.clone(), combined_weight));
472 }
473
474 focus_weights.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap());
476
477 let mut ctx = SymbolicContext::new();
478
479 for (i, (key, weight)) in focus_weights.iter().take(5).enumerate() {
481 ctx.set(&format!("focus_target_{}", i), key);
482 ctx.set(&format!("focus_weight_{}", i), &format!("{:.3}", weight));
483 }
484
485 let total_elements = focus_weights.len();
487 let avg_weight: f64 =
488 focus_weights.iter().map(|(_, w)| w).sum::<f64>() / total_elements as f64;
489
490 ctx.set("attention_targets", &total_elements.to_string());
491 ctx.set("avg_attention_weight", &format!("{:.3}", avg_weight));
492 ctx.set("attention_analysis_time", ¤t_timestamp.to_string());
493
494 Ok(ctx)
495 }
496
497 fn metadata(&self) -> OperatorMetadata {
498 OperatorMetadata {
499 name: "attention_focus".to_string(),
500 description: "Weights context elements by symbolic or temporal relevance".to_string(),
501 category: "meta".to_string(),
502 }
503 }
504
505 fn cognitive_cost(&self) -> f64 {
506 0.9
507 }
508
509 fn uncertainty_propagation(&self) -> UncertaintyModel {
510 UncertaintyModel {
511 entropy: 0.05,
512 source: "attention_weighting".to_string(),
513 }
514 }
515}
516
517pub struct MetaReflectiveOperator;
520
521impl SomaOperator for MetaReflectiveOperator {
522 fn execute(&self, inputs: &SymbolicContext) -> Result<SymbolicContext> {
523 let context_map = inputs.flatten();
524
525 let _total_operators = inputs
527 .resolve_or_default("operator_count", "12")
528 .parse::<usize>()
529 .unwrap_or(12);
530 let _system_uptime = inputs
531 .resolve_or_default("system_uptime", "3600")
532 .parse::<u64>()
533 .unwrap_or(3600);
534 let errors_count = inputs
535 .resolve_or_default("errors_count", "0")
536 .parse::<usize>()
537 .unwrap_or(0);
538
539 let reasoning_patterns = context_map
541 .keys()
542 .filter(|k| k.contains("reasoning") || k.contains("pattern") || k.contains("strategy"))
543 .count();
544
545 let symbolic_depth = context_map
546 .keys()
547 .map(|k| k.split('.').count())
548 .max()
549 .unwrap_or(1);
550
551 let performance_score = if errors_count == 0 && reasoning_patterns > 3 {
553 0.95
554 } else if errors_count < 3 && reasoning_patterns > 1 {
555 0.80
556 } else {
557 0.60
558 };
559
560 let optimization_suggestions = if performance_score < 0.7 {
561 vec![
562 "Φ_increase_reasoning_depth",
563 "Θ_optimize_symbolic_paths",
564 "Δ_reduce_cognitive_overhead",
565 ]
566 } else if performance_score < 0.9 {
567 vec![
568 "Θ_enhance_pattern_recognition",
569 "Φ_expand_context_awareness",
570 ]
571 } else {
572 vec!["Ω_maintain_current_excellence"]
573 };
574
575 let mut ctx = SymbolicContext::new();
576 ctx.set(
577 "meta_analysis_timestamp",
578 &std::time::SystemTime::now()
579 .duration_since(std::time::UNIX_EPOCH)
580 .unwrap()
581 .as_secs()
582 .to_string(),
583 );
584 ctx.set(
585 "system_performance_score",
586 &format!("{:.3}", performance_score),
587 );
588 ctx.set(
589 "reasoning_patterns_detected",
590 &reasoning_patterns.to_string(),
591 );
592 ctx.set("symbolic_depth", &symbolic_depth.to_string());
593 ctx.set(
594 "cognitive_efficiency",
595 &format!("{:.2}", 1.0 / (errors_count + 1) as f64),
596 );
597
598 ctx.set(
600 "emergence_level",
601 if symbolic_depth > 3 {
602 "high"
603 } else {
604 "moderate"
605 },
606 );
607 ctx.set(
608 "emergent_capabilities",
609 &format!("{}", reasoning_patterns * symbolic_depth),
610 );
611
612 for (i, suggestion) in optimization_suggestions.iter().enumerate() {
614 ctx.set(&format!("optimization_Θ_{}", i), suggestion);
615 }
616
617 let introspection_score = (performance_score + (reasoning_patterns as f64 / 10.0)) / 2.0;
619 ctx.set(
620 "introspection_score",
621 &format!("{:.3}", introspection_score),
622 );
623 ctx.set(
624 "meta_cognitive_state",
625 if introspection_score > 0.8 {
626 "optimal"
627 } else {
628 "improving"
629 },
630 );
631
632 Ok(ctx)
633 }
634
635 fn metadata(&self) -> OperatorMetadata {
636 OperatorMetadata {
637 name: "meta_reflective".to_string(),
638 description: "Claude's signature operator for recursive system introspection and self-improvement".to_string(),
639 category: "meta".to_string(),
640 }
641 }
642
643 fn cognitive_cost(&self) -> f64 {
644 1.8
645 }
646
647 fn uncertainty_propagation(&self) -> UncertaintyModel {
648 UncertaintyModel {
649 entropy: 0.04,
650 source: "meta_introspection".to_string(),
651 }
652 }
653}
654
655pub struct VisualReasoningOperator;
658
659impl SomaOperator for VisualReasoningOperator {
660 fn execute(&self, inputs: &SymbolicContext) -> Result<SymbolicContext> {
661 let visual_input_type = inputs.resolve_or_default("visual_type", "unknown");
662 let _visual_content = inputs.resolve_or_default("visual_content", "");
663 let analysis_mode = inputs.resolve_or_default("analysis_mode", "diagram");
664
665 let mut ctx = SymbolicContext::new();
666
667 let (symbolic_elements, relationships, complexity) = match visual_input_type.as_str() {
669 "diagram" | "flowchart" => {
670 let elements = ["node", "edge", "decision", "process", "data"];
671 let relations = ["connects_to", "precedes", "branches_to"];
672 (elements.len(), relations.len(), 0.7)
673 }
674 "screenshot" | "ui" => {
675 let elements = ["button", "text", "input", "menu", "window"];
676 let relations = ["contains", "adjacent_to", "overlaps"];
677 (elements.len(), relations.len(), 0.5)
678 }
679 "code_diagram" | "architecture" => {
680 let elements = ["class", "function", "module", "interface", "dependency"];
681 let relations = ["inherits", "implements", "uses", "calls"];
682 (elements.len(), relations.len(), 0.9)
683 }
684 _ => {
685 let elements = ["visual_element", "spatial_relation"];
686 let relations = ["spatial_connection"];
687 (elements.len(), relations.len(), 0.3)
688 }
689 };
690
691 ctx.set("visual_type", &visual_input_type);
693 ctx.set("symbolic_elements_count", &symbolic_elements.to_string());
694 ctx.set("relationship_types", &relationships.to_string());
695 ctx.set("visual_complexity", &format!("{:.2}", complexity));
696
697 ctx.set(
699 "symbolic_graph_nodes",
700 "visual_element_0,visual_element_1,visual_element_2",
701 );
702 ctx.set("symbolic_graph_edges", "edge_0,edge_1");
703 ctx.set(
704 "visual_semantic_tags",
705 &format!("{}_{}_semantic", visual_input_type, analysis_mode),
706 );
707
708 let conversion_confidence = match complexity {
710 c if c > 0.8 => 0.9,
711 c if c > 0.5 => 0.75,
712 _ => 0.6,
713 };
714
715 ctx.set(
716 "conversion_confidence",
717 &format!("{:.3}", conversion_confidence),
718 );
719 ctx.set(
720 "visual_reasoning_timestamp",
721 &std::time::SystemTime::now()
722 .duration_since(std::time::UNIX_EPOCH)
723 .unwrap()
724 .as_secs()
725 .to_string(),
726 );
727
728 ctx.set(
730 "memory_integration_path",
731 &format!("visual.{}.symbolic", visual_input_type),
732 );
733 ctx.set("dag_integration_points", &symbolic_elements.to_string());
734 ctx.set("visual_context_preserved", "true");
735
736 Ok(ctx)
737 }
738
739 fn metadata(&self) -> OperatorMetadata {
740 OperatorMetadata {
741 name: "visual_reasoning".to_string(),
742 description:
743 "Transforms visual input into symbolic memory for code understanding and analysis"
744 .to_string(),
745 category: "visual".to_string(),
746 }
747 }
748
749 fn cognitive_cost(&self) -> f64 {
750 2.5
751 }
752
753 fn uncertainty_propagation(&self) -> UncertaintyModel {
754 UncertaintyModel {
755 entropy: 0.25,
756 source: "visual_to_symbolic_conversion".to_string(),
757 }
758 }
759}
760
761pub struct EmpathyOperator;
765
766impl SomaOperator for EmpathyOperator {
767 fn execute(&self, inputs: &SymbolicContext) -> Result<SymbolicContext> {
768 let target_agent = inputs.resolve_or_default("target_agent", "agent_unknown");
769 let context_map = inputs.flatten();
770
771 let agent_keys: Vec<_> = context_map
773 .keys()
774 .filter(|k| k.starts_with(&format!("{}.", target_agent)))
775 .collect();
776
777 let mut empathy_model: HashMap<String, String> = HashMap::new();
778 let mut priority_sum = 0.0;
779 let mut priority_count = 0;
780
781 for key in &agent_keys {
782 let value = context_map.get(*key).unwrap();
783 let local_key = key
784 .strip_prefix(&format!("{}.", target_agent))
785 .unwrap_or(key);
786 empathy_model.insert(local_key.to_string(), value.clone());
787
788 let priority = match local_key {
790 k if k.contains("goal") => 3.0,
791 k if k.contains("priority") => value.parse::<f64>().unwrap_or(1.0),
792 k if k.contains("urgent") => 2.5,
793 k if k.contains("task") => 2.0,
794 _ => 1.0,
795 };
796 priority_sum += priority;
797 priority_count += 1;
798 }
799
800 let avg_priority = if priority_count > 0 {
801 priority_sum / priority_count as f64
802 } else {
803 1.0
804 };
805
806 let context_similarity = (agent_keys.len() as f64 / context_map.len() as f64).min(1.0);
808 let cognitive_alignment = (avg_priority / 3.0).min(1.0);
809 let empathy_score = (context_similarity + cognitive_alignment) / 2.0;
810
811 let mut ctx = SymbolicContext::new();
812 ctx.set("target_agent", &target_agent);
813 ctx.set("agent_context_keys", &agent_keys.len().to_string());
814 ctx.set("avg_priority", &format!("{:.3}", avg_priority));
815 ctx.set("context_similarity", &format!("{:.3}", context_similarity));
816 ctx.set("empathy_score", &format!("{:.3}", empathy_score));
817
818 for (key, value) in empathy_model {
820 ctx.set(&format!("empathy_model.{}", key), &value);
821 }
822
823 Ok(ctx)
824 }
825
826 fn metadata(&self) -> OperatorMetadata {
827 OperatorMetadata {
828 name: "empathy".to_string(),
829 description: "Models the symbolic reasoning state of another agent".to_string(),
830 category: "multi-agent".to_string(),
831 }
832 }
833
834 fn cognitive_cost(&self) -> f64 {
835 1.5
836 }
837
838 fn uncertainty_propagation(&self) -> UncertaintyModel {
839 UncertaintyModel {
840 entropy: 0.12,
841 source: "empathy_modeling".to_string(),
842 }
843 }
844}
845
846pub struct NegotiateOperator;
848
849impl SomaOperator for NegotiateOperator {
850 fn execute(&self, inputs: &SymbolicContext) -> Result<SymbolicContext> {
851 let context_map = inputs.flatten();
852 let conflict_key = inputs.resolve_or_default("conflict_key", "goal");
853
854 let mut agent_values: HashMap<String, String> = HashMap::new();
856
857 for (key, value) in &context_map {
858 if key.contains(&conflict_key) && key.contains("agent_") {
859 let agent_id = key.split('.').next().unwrap_or("unknown");
860 agent_values.insert(agent_id.to_string(), value.clone());
861 }
862 }
863
864 let mut ctx = SymbolicContext::new();
865
866 if agent_values.is_empty() {
867 ctx.set("negotiation_result", "no_conflicts_found");
868 ctx.set("resolution_strategy", "none");
869 return Ok(ctx);
870 }
871
872 let strategy = inputs.resolve_or_default("strategy", "consensus");
874 let resolved_value = match strategy.as_str() {
875 "majority" => {
876 let mut value_counts: HashMap<String, usize> = HashMap::new();
878 for value in agent_values.values() {
879 *value_counts.entry(value.clone()).or_insert(0) += 1;
880 }
881 value_counts
882 .into_iter()
883 .max_by_key(|(_, count)| *count)
884 .map(|(value, _)| value)
885 .unwrap_or_else(|| "unresolved".to_string())
886 }
887 "priority" => {
888 let priority_agent = inputs.resolve_or_default("priority_agent", "agent_1");
890 agent_values
891 .get(&priority_agent)
892 .cloned()
893 .unwrap_or_else(|| {
894 agent_values
895 .values()
896 .next()
897 .cloned()
898 .unwrap_or_else(|| "unresolved".to_string())
899 })
900 }
901 "average" => {
902 let numeric_values: Vec<f64> = agent_values
904 .values()
905 .filter_map(|v| v.parse::<f64>().ok())
906 .collect();
907 if !numeric_values.is_empty() {
908 let avg = numeric_values.iter().sum::<f64>() / numeric_values.len() as f64;
909 format!("{:.3}", avg)
910 } else {
911 "non_numeric_conflict".to_string()
912 }
913 }
914 _ => {
915 let unique_values: std::collections::HashSet<_> = agent_values.values().collect();
917 if unique_values.len() == 1 {
918 unique_values.into_iter().next().unwrap().clone()
919 } else {
920 "consensus_failed".to_string()
921 }
922 }
923 };
924
925 ctx.set("conflict_key", &conflict_key);
926 ctx.set("agent_count", &agent_values.len().to_string());
927 ctx.set("resolution_strategy", &strategy);
928 ctx.set("resolved_value", &resolved_value);
929 ctx.set(
930 "negotiation_result",
931 if resolved_value == "unresolved" || resolved_value == "consensus_failed" {
932 "failed"
933 } else {
934 "success"
935 },
936 );
937
938 for (agent, value) in agent_values {
940 ctx.set(&format!("position.{}", agent), &value);
941 }
942
943 Ok(ctx)
944 }
945
946 fn metadata(&self) -> OperatorMetadata {
947 OperatorMetadata {
948 name: "negotiate".to_string(),
949 description: "Resolves symbolic value conflicts across multiple agents".to_string(),
950 category: "multi-agent".to_string(),
951 }
952 }
953
954 fn cognitive_cost(&self) -> f64 {
955 1.8
956 }
957
958 fn uncertainty_propagation(&self) -> UncertaintyModel {
959 UncertaintyModel {
960 entropy: 0.20,
961 source: "negotiation_process".to_string(),
962 }
963 }
964}
965
966pub struct ConsensusOperator;
968
969impl SomaOperator for ConsensusOperator {
970 fn execute(&self, inputs: &SymbolicContext) -> Result<SymbolicContext> {
971 let context_map = inputs.flatten();
972 let min_agreement = inputs
973 .resolve_or_default("min_agreement", "0.6")
974 .parse::<f64>()
975 .unwrap_or(0.6);
976
977 let mut agent_contexts: HashMap<String, HashMap<String, String>> = HashMap::new();
979
980 for (key, value) in &context_map {
981 if key.contains("agent_") {
982 let parts: Vec<&str> = key.split('.').collect();
983 if parts.len() >= 2 {
984 let agent_id = parts[0];
985 let context_key = parts[1..].join(".");
986 agent_contexts
987 .entry(agent_id.to_string())
988 .or_insert_with(HashMap::new)
989 .insert(context_key, value.clone());
990 }
991 }
992 }
993
994 let mut consensus_result: HashMap<String, String> = HashMap::new();
995 let mut agreement_scores: HashMap<String, f64> = HashMap::new();
996
997 let mut all_keys: std::collections::HashSet<String> = std::collections::HashSet::new();
999 for agent_context in agent_contexts.values() {
1000 all_keys.extend(agent_context.keys().cloned());
1001 }
1002
1003 for context_key in all_keys {
1004 let mut values: Vec<String> = Vec::new();
1005 for agent_context in agent_contexts.values() {
1006 if let Some(value) = agent_context.get(&context_key) {
1007 values.push(value.clone());
1008 }
1009 }
1010
1011 if values.is_empty() {
1012 continue;
1013 }
1014
1015 let unique_values: std::collections::HashSet<_> = values.iter().collect();
1017 let agreement_ratio = if unique_values.len() == 1 {
1018 1.0
1019 } else {
1020 let mut value_counts: HashMap<String, usize> = HashMap::new();
1022 for value in &values {
1023 *value_counts.entry(value.clone()).or_insert(0) += 1;
1024 }
1025 let max_count = value_counts.values().max().unwrap_or(&0);
1026 *max_count as f64 / values.len() as f64
1027 };
1028
1029 agreement_scores.insert(context_key.clone(), agreement_ratio);
1030
1031 if agreement_ratio >= min_agreement {
1032 let mut value_counts: HashMap<String, usize> = HashMap::new();
1034 for value in &values {
1035 *value_counts.entry(value.clone()).or_insert(0) += 1;
1036 }
1037 let consensus_value = value_counts
1038 .into_iter()
1039 .max_by_key(|(_, count)| *count)
1040 .map(|(value, _)| value)
1041 .unwrap_or_else(|| "no_consensus".to_string());
1042
1043 consensus_result.insert(context_key, consensus_value);
1044 }
1045 }
1046
1047 let total_keys = agreement_scores.len();
1049 let consensus_keys = consensus_result.len();
1050 let avg_agreement: f64 = if total_keys > 0 {
1051 agreement_scores.values().sum::<f64>() / total_keys as f64
1052 } else {
1053 0.0
1054 };
1055
1056 let mut ctx = SymbolicContext::new();
1057 ctx.set("agent_count", &agent_contexts.len().to_string());
1058 ctx.set("total_keys", &total_keys.to_string());
1059 ctx.set("consensus_keys", &consensus_keys.to_string());
1060 ctx.set(
1061 "consensus_ratio",
1062 &format!("{:.3}", consensus_keys as f64 / total_keys.max(1) as f64),
1063 );
1064 ctx.set("avg_agreement", &format!("{:.3}", avg_agreement));
1065 ctx.set("min_agreement_threshold", &min_agreement.to_string());
1066
1067 for (key, value) in consensus_result {
1069 ctx.set(&format!("consensus.{}", key), &value);
1070 }
1071
1072 for (key, score) in agreement_scores {
1074 ctx.set(&format!("agreement.{}", key), &format!("{:.3}", score));
1075 }
1076
1077 Ok(ctx)
1078 }
1079
1080 fn metadata(&self) -> OperatorMetadata {
1081 OperatorMetadata {
1082 name: "consensus".to_string(),
1083 description: "Finds symbolic agreement across diverse agent proposals".to_string(),
1084 category: "multi-agent".to_string(),
1085 }
1086 }
1087
1088 fn cognitive_cost(&self) -> f64 {
1089 2.0
1090 }
1091
1092 fn uncertainty_propagation(&self) -> UncertaintyModel {
1093 UncertaintyModel {
1094 entropy: 0.25,
1095 source: "consensus_building".to_string(),
1096 }
1097 }
1098}
1099
1100pub fn default_operator_registry() -> HashMap<String, Box<dyn SomaOperator>> {
1101 let mut reg: HashMap<String, Box<dyn SomaOperator>> = HashMap::new();
1102
1103 reg.insert("add".to_string(), Box::new(AddOperator));
1105 reg.insert("compose".to_string(), Box::new(ComposeOperator));
1106 reg.insert("if_then".to_string(), Box::new(IfThenOperator));
1107 reg.insert("reflect".to_string(), Box::new(ReflectOperator));
1108 reg.insert("delay".to_string(), Box::new(DelayOperator));
1109
1110 reg.insert(
1112 "uncertainty_propagate".to_string(),
1113 Box::new(UncertaintyPropagateOperator),
1114 );
1115 reg.insert("doubt".to_string(), Box::new(DoubtOperator));
1116
1117 reg.insert("introspect".to_string(), Box::new(IntrospectOperator));
1119 reg.insert(
1120 "cognitive_load".to_string(),
1121 Box::new(CognitiveLoadOperator),
1122 );
1123 reg.insert(
1124 "attention_focus".to_string(),
1125 Box::new(AttentionFocusOperator),
1126 );
1127 reg.insert(
1128 "meta_reflective".to_string(),
1129 Box::new(MetaReflectiveOperator),
1130 );
1131 reg.insert(
1132 "visual_reasoning".to_string(),
1133 Box::new(VisualReasoningOperator),
1134 );
1135
1136 reg.insert("empathy".to_string(), Box::new(EmpathyOperator));
1138 reg.insert("negotiate".to_string(), Box::new(NegotiateOperator));
1139 reg.insert("consensus".to_string(), Box::new(ConsensusOperator));
1140
1141 reg
1142}
1143
1144pub use crate::llm_operator::{llm_registry, LLMOperator};
1146
1147#[cfg(test)]
1148mod tests {
1149 use super::*;
1150 use crate::memory::SymbolicContext;
1151
1152 #[test]
1153 fn test_add_operator() {
1154 let registry = default_operator_registry();
1155 let mut ctx = SymbolicContext::new();
1156 ctx.set("x", "3");
1157 ctx.set("y", "7");
1158 let add = registry.get("add").unwrap();
1159 let result_ctx = add.execute(&ctx).unwrap();
1160 assert_eq!(result_ctx.get("sum").unwrap(), "10");
1161 }
1162
1163 #[test]
1164 fn test_if_then_operator() {
1165 let registry = default_operator_registry();
1166 let mut ctx = SymbolicContext::new();
1167 ctx.set("condition", "true");
1168 ctx.set("then", "yes");
1169 ctx.set("else", "no");
1170 let if_then = registry.get("if_then").unwrap();
1171 let result_ctx = if_then.execute(&ctx).unwrap();
1172 assert_eq!(result_ctx.get("result").unwrap(), "yes");
1173 }
1174
1175 #[test]
1176 fn test_reflect_operator() {
1177 let registry = default_operator_registry();
1178 let mut ctx = SymbolicContext::new();
1179 ctx.set("key1", "value1");
1180 ctx.set("key2", "value2");
1181 let reflect = registry.get("reflect").unwrap();
1182 let result_ctx = reflect.execute(&ctx).unwrap();
1183 let summary = result_ctx.get("summary").unwrap();
1184 assert!(summary.contains("key1"));
1185 assert!(summary.contains("key2"));
1186 }
1187
1188 #[test]
1189 fn test_delay_operator() {
1190 let registry = default_operator_registry();
1191 let mut ctx = SymbolicContext::new();
1192 ctx.set("delay_ms", "50");
1193 let delay = registry.get("delay").unwrap();
1194 let result_ctx = delay.execute(&ctx).unwrap();
1195 assert_eq!(result_ctx.get("delayed").unwrap(), "50ms");
1196 }
1197
1198 #[test]
1201 fn test_uncertainty_propagate_operator() {
1202 let registry = default_operator_registry();
1203 let mut ctx = SymbolicContext::new();
1204 ctx.set("entropy", "0.2");
1205 ctx.set("confidence", "0.8");
1206 ctx.set("data", "test_value");
1207
1208 let op = registry.get("uncertainty_propagate").unwrap();
1209 let result_ctx = op.execute(&ctx).unwrap();
1210
1211 assert_eq!(result_ctx.get("uncertainty_source").unwrap(), "propagated");
1212 assert_eq!(result_ctx.get("data_uncertain").unwrap(), "test_value");
1213
1214 let propagated_entropy = result_ctx
1215 .get("propagated_entropy")
1216 .unwrap()
1217 .parse::<f64>()
1218 .unwrap();
1219 assert!(propagated_entropy > 0.2); let propagated_confidence = result_ctx
1222 .get("propagated_confidence")
1223 .unwrap()
1224 .parse::<f64>()
1225 .unwrap();
1226 assert!(propagated_confidence < 0.8); }
1228
1229 #[test]
1230 fn test_doubt_operator() {
1231 let registry = default_operator_registry();
1232
1233 let mut ctx_low = SymbolicContext::new();
1235 ctx_low.set("confidence", "0.3");
1236 ctx_low.set("doubt_threshold", "0.5");
1237
1238 let doubt = registry.get("doubt").unwrap();
1239 let result_low = doubt.execute(&ctx_low).unwrap();
1240
1241 assert_eq!(result_low.get("flagged").unwrap(), "true");
1242 assert_eq!(result_low.get("verification_required").unwrap(), "true");
1243 assert_eq!(
1244 result_low.get("doubt_reason").unwrap(),
1245 "confidence_below_threshold"
1246 );
1247
1248 let mut ctx_high = SymbolicContext::new();
1250 ctx_high.set("confidence", "0.9");
1251 ctx_high.set("doubt_threshold", "0.5");
1252
1253 let result_high = doubt.execute(&ctx_high).unwrap();
1254 assert_eq!(result_high.get("flagged").unwrap(), "false");
1255 assert_eq!(
1256 result_high.get("doubt_reason").unwrap(),
1257 "confidence_acceptable"
1258 );
1259 }
1260
1261 #[test]
1264 fn test_introspect_operator() {
1265 let registry = default_operator_registry();
1266 let mut ctx = SymbolicContext::new();
1267
1268 for i in 0..15 {
1270 ctx.set(&format!("key_{}", i), &format!("value_{}", i));
1271 }
1272
1273 let introspect = registry.get("introspect").unwrap();
1274 let result_ctx = introspect.execute(&ctx).unwrap();
1275
1276 assert_eq!(result_ctx.get("context_size").unwrap(), "15");
1277 assert!(result_ctx.get("reasoning_depth").is_some());
1278 assert!(result_ctx.get("complexity_score").is_some());
1279 assert!(result_ctx.get("bottleneck_detected").is_some());
1280 assert!(result_ctx.get("introspection_timestamp").is_some());
1281 }
1282
1283 #[test]
1284 fn test_cognitive_load_operator() {
1285 let registry = default_operator_registry();
1286 let mut ctx = SymbolicContext::new();
1287
1288 ctx.set("simple", "value");
1290 ctx.set("nested.key", "nested_value");
1291 ctx.set("nested.deep.key", "deep_value");
1292 ctx.set("long_content", &"a".repeat(200)); let cognitive_load = registry.get("cognitive_load").unwrap();
1295 let result_ctx = cognitive_load.execute(&ctx).unwrap();
1296
1297 assert_eq!(result_ctx.get("memory_keys").unwrap(), "4");
1298 assert_eq!(result_ctx.get("nested_keys").unwrap(), "2");
1299 assert!(result_ctx.get("load_score").is_some());
1300 assert!(result_ctx.get("load_level").is_some());
1301 assert!(result_ctx.get("optimization_needed").is_some());
1302
1303 let load_score = result_ctx
1304 .get("load_score")
1305 .unwrap()
1306 .parse::<f64>()
1307 .unwrap();
1308 assert!(load_score > 0.0);
1309 }
1310
1311 #[test]
1312 fn test_attention_focus_operator() {
1313 let registry = default_operator_registry();
1314 let mut ctx = SymbolicContext::new();
1315
1316 ctx.set("goal_primary", "main_objective");
1318 ctx.set("error_critical", "system_failure");
1319 ctx.set("result_output", "final_result");
1320 ctx.set("input_param", "user_input");
1321 ctx.set("misc_data", "other_info");
1322
1323 let attention = registry.get("attention_focus").unwrap();
1324 let result_ctx = attention.execute(&ctx).unwrap();
1325
1326 assert!(result_ctx.get("attention_targets").is_some());
1327 assert!(result_ctx.get("avg_attention_weight").is_some());
1328 assert!(result_ctx.get("focus_target_0").is_some()); assert!(result_ctx.get("focus_weight_0").is_some());
1330 assert!(result_ctx.get("attention_analysis_time").is_some());
1331 }
1332
1333 #[test]
1334 fn test_meta_reflective_operator() {
1335 let registry = default_operator_registry();
1336 let mut ctx = SymbolicContext::new();
1337
1338 ctx.set("operator_count", "15");
1340 ctx.set("system_uptime", "7200");
1341 ctx.set("errors_count", "1");
1342 ctx.set("reasoning_pattern_1", "deep_analysis");
1343 ctx.set("strategy_optimization", "active");
1344 ctx.set("nested.reasoning.path", "complex");
1345
1346 let meta_op = registry.get("meta_reflective").unwrap();
1347 let result_ctx = meta_op.execute(&ctx).unwrap();
1348
1349 assert!(result_ctx.get("system_performance_score").is_some());
1351 assert!(result_ctx.get("reasoning_patterns_detected").is_some());
1352 assert!(result_ctx.get("symbolic_depth").is_some());
1353 assert!(result_ctx.get("cognitive_efficiency").is_some());
1354 assert!(result_ctx.get("emergence_level").is_some());
1355 assert!(result_ctx.get("introspection_score").is_some());
1356 assert!(result_ctx.get("meta_cognitive_state").is_some());
1357
1358 assert!(result_ctx.get("optimization_Θ_0").is_some());
1360
1361 let performance = result_ctx
1363 .get("system_performance_score")
1364 .unwrap()
1365 .parse::<f64>()
1366 .unwrap();
1367 assert!(performance > 0.0 && performance <= 1.0);
1368
1369 let emergence_level = result_ctx.get("emergence_level").unwrap();
1371 assert!(emergence_level == "high" || emergence_level == "moderate");
1372 }
1373
1374 #[test]
1375 fn test_visual_reasoning_operator() {
1376 let registry = default_operator_registry();
1377 let mut ctx = SymbolicContext::new();
1378
1379 ctx.set("visual_type", "code_diagram");
1381 ctx.set("analysis_mode", "architecture");
1382 ctx.set("visual_content", "class_diagram_with_multiple_classes");
1383
1384 let visual_reasoning = registry.get("visual_reasoning").unwrap();
1385 let result_ctx = visual_reasoning.execute(&ctx).unwrap();
1386
1387 assert_eq!(result_ctx.get("visual_type").unwrap(), "code_diagram");
1389 assert!(result_ctx.get("symbolic_elements_count").is_some());
1390 assert!(result_ctx.get("visual_complexity").is_some());
1391 assert!(result_ctx.get("conversion_confidence").is_some());
1392 assert!(result_ctx.get("visual_reasoning_timestamp").is_some());
1393
1394 assert!(result_ctx.get("symbolic_graph_nodes").is_some());
1396 assert!(result_ctx.get("symbolic_graph_edges").is_some());
1397 assert!(result_ctx.get("visual_semantic_tags").is_some());
1398 assert!(result_ctx.get("memory_integration_path").is_some());
1399
1400 let complexity = result_ctx
1402 .get("visual_complexity")
1403 .unwrap()
1404 .parse::<f64>()
1405 .unwrap();
1406 assert!(complexity >= 0.0 && complexity <= 1.0);
1407
1408 let confidence = result_ctx
1409 .get("conversion_confidence")
1410 .unwrap()
1411 .parse::<f64>()
1412 .unwrap();
1413 assert!(confidence >= 0.6); let mut ctx_screenshot = SymbolicContext::new();
1417 ctx_screenshot.set("visual_type", "screenshot");
1418 ctx_screenshot.set("analysis_mode", "ui_analysis");
1419
1420 let result_screenshot = visual_reasoning.execute(&ctx_screenshot).unwrap();
1421 assert_eq!(result_screenshot.get("visual_type").unwrap(), "screenshot");
1422
1423 let screenshot_confidence = result_screenshot
1425 .get("conversion_confidence")
1426 .unwrap()
1427 .parse::<f64>()
1428 .unwrap();
1429 assert!(screenshot_confidence < confidence); let mut ctx_unknown = SymbolicContext::new();
1433 ctx_unknown.set("visual_type", "unknown_format");
1434
1435 let result_unknown = visual_reasoning.execute(&ctx_unknown).unwrap();
1436 let unknown_confidence = result_unknown
1437 .get("conversion_confidence")
1438 .unwrap()
1439 .parse::<f64>()
1440 .unwrap();
1441 assert!(unknown_confidence <= 0.6); }
1443
1444 #[test]
1445 fn test_visual_reasoning_memory_integration() {
1446 let registry = default_operator_registry();
1447 let mut ctx = SymbolicContext::new();
1448
1449 ctx.set("visual_type", "architecture");
1450 ctx.set("analysis_mode", "system_design");
1451 ctx.set("visual_content", "microservices_architecture_diagram");
1452
1453 let visual_reasoning = registry.get("visual_reasoning").unwrap();
1454 let result_ctx = visual_reasoning.execute(&ctx).unwrap();
1455
1456 let integration_path = result_ctx.get("memory_integration_path").unwrap();
1458 assert!(integration_path.contains("visual.architecture.symbolic"));
1459
1460 assert!(result_ctx.get("dag_integration_points").is_some());
1462 assert_eq!(result_ctx.get("visual_context_preserved").unwrap(), "true");
1463
1464 let semantic_tags = result_ctx.get("visual_semantic_tags").unwrap();
1466 assert!(semantic_tags.contains("architecture"));
1467 assert!(semantic_tags.contains("system_design"));
1468 }
1469
1470 #[test]
1471 fn test_visual_reasoning_cognitive_cost() {
1472 let registry = default_operator_registry();
1473 let visual_reasoning = registry.get("visual_reasoning").unwrap();
1474
1475 let cost = visual_reasoning.cognitive_cost();
1477 assert_eq!(cost, 2.5);
1478
1479 let add_op = registry.get("add").unwrap();
1481 assert!(cost > add_op.cognitive_cost());
1482
1483 let introspect_op = registry.get("introspect").unwrap();
1484 assert!(cost > introspect_op.cognitive_cost());
1485 }
1486
1487 #[test]
1488 fn test_visual_reasoning_uncertainty_model() {
1489 let registry = default_operator_registry();
1490 let visual_reasoning = registry.get("visual_reasoning").unwrap();
1491
1492 let uncertainty = visual_reasoning.uncertainty_propagation();
1493 assert_eq!(uncertainty.entropy, 0.25);
1494 assert_eq!(uncertainty.source, "visual_to_symbolic_conversion");
1495
1496 let add_op = registry.get("add").unwrap();
1498 let add_uncertainty = add_op.uncertainty_propagation();
1499 assert!(uncertainty.entropy > add_uncertainty.entropy);
1500 }
1501
1502 #[test]
1503 fn test_visual_reasoning_multiple_analysis_modes() {
1504 let registry = default_operator_registry();
1505 let visual_reasoning = registry.get("visual_reasoning").unwrap();
1506
1507 let mut ctx_diagram = SymbolicContext::new();
1509 ctx_diagram.set("visual_type", "flowchart");
1510 ctx_diagram.set("analysis_mode", "diagram");
1511 let result_diagram = visual_reasoning.execute(&ctx_diagram).unwrap();
1512
1513 let mut ctx_ui = SymbolicContext::new();
1515 ctx_ui.set("visual_type", "ui");
1516 ctx_ui.set("analysis_mode", "interface_analysis");
1517 let result_ui = visual_reasoning.execute(&ctx_ui).unwrap();
1518
1519 let diagram_complexity = result_diagram
1521 .get("visual_complexity")
1522 .unwrap()
1523 .parse::<f64>()
1524 .unwrap();
1525 let ui_complexity = result_ui
1526 .get("visual_complexity")
1527 .unwrap()
1528 .parse::<f64>()
1529 .unwrap();
1530
1531 assert!(diagram_complexity != ui_complexity);
1533 assert!(diagram_complexity >= 0.0 && diagram_complexity <= 1.0);
1534 assert!(ui_complexity >= 0.0 && ui_complexity <= 1.0);
1535 }
1536
1537 #[test]
1540 fn test_empathy_operator() {
1541 let registry = default_operator_registry();
1542 let mut ctx = SymbolicContext::new();
1543
1544 ctx.set("target_agent", "agent_1");
1546 ctx.set("agent_1.goal", "complete_task");
1547 ctx.set("agent_1.priority", "2.5");
1548 ctx.set("agent_1.task", "data_processing");
1549 ctx.set("agent_2.goal", "monitor_system"); let empathy = registry.get("empathy").unwrap();
1552 let result_ctx = empathy.execute(&ctx).unwrap();
1553
1554 assert_eq!(result_ctx.get("target_agent").unwrap(), "agent_1");
1555 assert_eq!(result_ctx.get("agent_context_keys").unwrap(), "3");
1556 assert!(result_ctx.get("empathy_score").is_some());
1557 assert!(result_ctx.get("context_similarity").is_some());
1558 assert_eq!(
1559 result_ctx.get("empathy_model.goal").unwrap(),
1560 "complete_task"
1561 );
1562 assert_eq!(result_ctx.get("empathy_model.priority").unwrap(), "2.5");
1563 }
1564
1565 #[test]
1566 fn test_negotiate_operator() {
1567 let registry = default_operator_registry();
1568
1569 let mut ctx_majority = SymbolicContext::new();
1571 ctx_majority.set("conflict_key", "goal");
1572 ctx_majority.set("strategy", "majority");
1573 ctx_majority.set("agent_1.goal", "option_a");
1574 ctx_majority.set("agent_2.goal", "option_a");
1575 ctx_majority.set("agent_3.goal", "option_b");
1576
1577 let negotiate = registry.get("negotiate").unwrap();
1578 let result_majority = negotiate.execute(&ctx_majority).unwrap();
1579
1580 assert_eq!(result_majority.get("resolved_value").unwrap(), "option_a");
1581 assert_eq!(
1582 result_majority.get("negotiation_result").unwrap(),
1583 "success"
1584 );
1585 assert_eq!(result_majority.get("agent_count").unwrap(), "3");
1586
1587 let mut ctx_empty = SymbolicContext::new();
1589 ctx_empty.set("conflict_key", "nonexistent");
1590
1591 let result_empty = negotiate.execute(&ctx_empty).unwrap();
1592 assert_eq!(
1593 result_empty.get("negotiation_result").unwrap(),
1594 "no_conflicts_found"
1595 );
1596
1597 let mut ctx_numeric = SymbolicContext::new();
1599 ctx_numeric.set("conflict_key", "score");
1600 ctx_numeric.set("strategy", "average");
1601 ctx_numeric.set("agent_1.score", "8.5");
1602 ctx_numeric.set("agent_2.score", "7.0");
1603 ctx_numeric.set("agent_3.score", "9.5");
1604
1605 let result_numeric = negotiate.execute(&ctx_numeric).unwrap();
1606 let avg_value = result_numeric
1607 .get("resolved_value")
1608 .unwrap()
1609 .parse::<f64>()
1610 .unwrap();
1611 assert!((avg_value - 8.333).abs() < 0.01); }
1613
1614 #[test]
1615 fn test_consensus_operator() {
1616 let registry = default_operator_registry();
1617 let mut ctx = SymbolicContext::new();
1618
1619 ctx.set("min_agreement", "0.6");
1621 ctx.set("agent_1.priority", "high");
1622 ctx.set("agent_2.priority", "high");
1623 ctx.set("agent_3.priority", "medium"); ctx.set("agent_1.status", "ready");
1625 ctx.set("agent_2.status", "ready");
1626 ctx.set("agent_3.status", "ready"); let consensus = registry.get("consensus").unwrap();
1629 let result_ctx = consensus.execute(&ctx).unwrap();
1630
1631 assert_eq!(result_ctx.get("agent_count").unwrap(), "3");
1632 assert_eq!(result_ctx.get("total_keys").unwrap(), "2");
1633
1634 assert_eq!(result_ctx.get("consensus.status").unwrap(), "ready");
1636 assert_eq!(result_ctx.get("consensus.priority").unwrap(), "high"); let consensus_ratio = result_ctx
1639 .get("consensus_ratio")
1640 .unwrap()
1641 .parse::<f64>()
1642 .unwrap();
1643 assert!(consensus_ratio > 0.0);
1644
1645 assert!(result_ctx.get("avg_agreement").is_some());
1646 assert_eq!(result_ctx.get("agreement.status").unwrap(), "1.000"); }
1648
1649 #[test]
1650 fn test_new_operators_in_registry() {
1651 let registry = default_operator_registry();
1652
1653 let expected_operators = vec![
1655 "add",
1656 "compose",
1657 "if_then",
1658 "reflect",
1659 "delay", "uncertainty_propagate",
1661 "doubt", "introspect",
1663 "cognitive_load",
1664 "attention_focus", "meta_reflective",
1666 "visual_reasoning", "empathy",
1668 "negotiate",
1669 "consensus", ];
1671
1672 for operator_name in expected_operators {
1673 assert!(
1674 registry.contains_key(operator_name),
1675 "Missing operator: {}",
1676 operator_name
1677 );
1678 }
1679
1680 assert_eq!(registry.len(), 15); let introspect = registry.get("introspect").unwrap();
1685 let metadata = introspect.metadata();
1686 assert_eq!(metadata.category, "meta");
1687 assert_eq!(metadata.name, "introspect");
1688
1689 let empathy = registry.get("empathy").unwrap();
1690 let empathy_metadata = empathy.metadata();
1691 assert_eq!(empathy_metadata.category, "multi-agent");
1692
1693 let uncertainty = registry.get("uncertainty_propagate").unwrap();
1694 let uncertainty_metadata = uncertainty.metadata();
1695 assert_eq!(uncertainty_metadata.category, "uncertainty");
1696
1697 let meta_reflective = registry.get("meta_reflective").unwrap();
1699 let meta_metadata = meta_reflective.metadata();
1700 assert_eq!(meta_metadata.category, "meta");
1701 assert_eq!(meta_metadata.name, "meta_reflective");
1702 assert!(meta_reflective.cognitive_cost() > 1.0);
1703
1704 let visual_reasoning = registry.get("visual_reasoning").unwrap();
1705 let visual_metadata = visual_reasoning.metadata();
1706 assert_eq!(visual_metadata.category, "visual");
1707 assert_eq!(visual_metadata.name, "visual_reasoning");
1708 assert!(visual_reasoning.cognitive_cost() > 2.0);
1709 }
1710}