Skip to main content

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}