phago_core/agent.rs
1//! Agent — the fundamental computational cell.
2//!
3//! Every agent in Phago is a cell: an isolated unit that senses its
4//! environment, processes inputs, and acts on the substrate. The base
5//! Agent trait requires the three most fundamental biological capabilities:
6//! - DIGEST: the ability to consume and process input
7//! - APOPTOSE: the ability to self-assess and gracefully die
8//! - SENSE: the ability to detect environmental signals
9
10use crate::primitives::{Apoptose, Digest, Sense};
11use crate::primitives::symbiose::AgentProfile;
12use crate::substrate::Substrate;
13use crate::types::*;
14
15/// The fundamental unit of computation in Phago — a biological cell.
16///
17/// Every agent must be able to:
18/// - **Digest** input (consume, break down, present fragments)
19/// - **Apoptose** (self-assess health, gracefully die when compromised)
20/// - **Sense** the substrate (detect signals, follow gradients)
21///
22/// Additional biological capabilities (Wire, Transfer, Emerge, etc.)
23/// are opt-in through additional trait implementations.
24pub trait Agent: Digest + Apoptose + Sense {
25 /// The agent's unique identity.
26 fn id(&self) -> AgentId;
27
28 /// The agent's current position in the substrate.
29 fn position(&self) -> Position;
30
31 /// Set the agent's position.
32 fn set_position(&mut self, position: Position);
33
34 /// The agent's type name (for display and logging).
35 fn agent_type(&self) -> &str;
36
37 /// Execute one tick of the agent's lifecycle.
38 ///
39 /// This is the main loop body. Each tick, the agent:
40 /// 1. Senses the environment
41 /// 2. Decides what to do
42 /// 3. Returns an action for the runtime to execute
43 ///
44 /// The runtime calls this once per simulation tick.
45 fn tick(&mut self, substrate: &dyn Substrate) -> AgentAction;
46
47 /// How many ticks this agent has been alive.
48 fn age(&self) -> Tick;
49
50 // --- Transfer (Horizontal Gene Transfer) default methods ---
51
52 /// Export this agent's vocabulary as serialized bytes.
53 /// Returns None if the agent has no vocabulary to export.
54 fn export_vocabulary(&self) -> Option<Vec<u8>> {
55 None
56 }
57
58 /// Integrate foreign vocabulary from serialized bytes.
59 /// Returns true if integration succeeded.
60 fn integrate_vocabulary(&mut self, _data: &[u8]) -> bool {
61 false
62 }
63
64 // --- Symbiose (Endosymbiosis) default methods ---
65
66 /// Build a profile describing this agent's capabilities.
67 fn profile(&self) -> AgentProfile {
68 AgentProfile {
69 id: self.id(),
70 agent_type: self.agent_type().to_string(),
71 capabilities: Vec::new(),
72 health: CellHealth::Healthy,
73 }
74 }
75
76 /// Evaluate whether to absorb another agent as a symbiont.
77 fn evaluate_symbiosis(&self, _other: &AgentProfile) -> Option<SymbiosisEval> {
78 None
79 }
80
81 /// Absorb another agent's profile and vocabulary data as a symbiont.
82 /// Returns true if absorption succeeded.
83 fn absorb_symbiont(&mut self, _profile: AgentProfile, _data: Vec<u8>) -> bool {
84 false
85 }
86
87 // --- Dissolve (Holobiont) default methods ---
88
89 /// Current boundary permeability (0.0 = rigid, 1.0 = fully dissolved).
90 fn permeability(&self) -> f64 {
91 0.0
92 }
93
94 /// Adjust boundary permeability based on environmental context.
95 fn modulate_boundary(&mut self, _context: &BoundaryContext) {}
96
97 /// Return vocabulary terms to externalize (reinforce in the substrate).
98 fn externalize_vocabulary(&self) -> Vec<String> {
99 Vec::new()
100 }
101
102 /// Absorb nearby concept terms from the substrate.
103 fn internalize_vocabulary(&mut self, _terms: &[String]) {}
104
105 /// Return the size of this agent's vocabulary (for metrics).
106 fn vocabulary_size(&self) -> usize {
107 0
108 }
109}