strange_loop/nano_agent/
agents.rs1use super::{NanoAgent, NanoBus, Message, TickResult, spin};
4use super::bus::MessageData;
5use crate::quantum_container::QuantumContainer;
7use crate::self_modifying::SelfModifyingLoop;
8
9pub struct SensorAgent {
13 counter: u64,
14 period_ticks: u32,
15 current_tick: u32,
16}
17
18impl SensorAgent {
19 pub fn new(period_ticks: u32) -> Self {
20 Self {
21 counter: 0,
22 period_ticks,
23 current_tick: 0,
24 }
25 }
26}
27
28impl NanoAgent for SensorAgent {
29 fn name(&self) -> &'static str { "sensor" }
30
31 #[inline(always)]
32 fn tick(&mut self, now_ns: u128, bus: &NanoBus) -> TickResult {
33 self.current_tick = self.current_tick.wrapping_add(1);
34
35 let mut messages_sent = 0;
36
37 if self.current_tick % self.period_ticks == 0 {
38 self.counter = self.counter.wrapping_add(1);
39 bus.publish(Message {
40 topic: "sensor:data",
41 data: MessageData::U64(self.counter),
42 timestamp_ns: now_ns,
43 });
44 messages_sent = 1;
45 }
46
47 TickResult {
48 cycles: 100, messages_sent,
50 messages_recv: 0,
51 budget_used_ns: 50,
52 }
53 }
54
55 fn budget_ns(&self) -> u128 { 1000 } }
57
58pub struct DebounceAgent {
60 last_value: u64,
61 stable_count: u32,
62 stability_threshold: u32,
63 spin_cycles: u32,
64}
65
66impl DebounceAgent {
67 pub fn new(stability_threshold: u32) -> Self {
68 Self {
69 last_value: 0,
70 stable_count: 0,
71 stability_threshold,
72 spin_cycles: 16,
73 }
74 }
75}
76
77impl NanoAgent for DebounceAgent {
78 fn name(&self) -> &'static str { "debouncer" }
79
80 #[inline(always)]
81 fn tick(&mut self, now_ns: u128, bus: &NanoBus) -> TickResult {
82 let mut messages_recv = 0;
83 let mut messages_sent = 0;
84 let mut changed = None;
85
86 for _ in 0..8 {
88 if let Some(msg) = bus.try_recv() {
89 messages_recv += 1;
90
91 if msg.topic == "sensor:data" {
92 if let MessageData::U64(value) = msg.data {
93 if value == self.last_value {
94 self.stable_count += 1;
95 } else {
96 self.stable_count = 0;
97 self.last_value = value;
98 }
99
100 if self.stable_count >= self.stability_threshold {
101 changed = Some(self.last_value);
102 self.stable_count = 0;
103 }
104 }
105 }
106 } else {
107 break;
108 }
109 }
110
111 if let Some(value) = changed {
113 bus.publish(Message {
114 topic: "signal:stable",
115 data: MessageData::U64(value),
116 timestamp_ns: now_ns,
117 });
118 messages_sent = 1;
119 }
120
121 for _ in 0..self.spin_cycles {
123 spin();
124 }
125
126 TickResult {
127 cycles: 200,
128 messages_sent,
129 messages_recv,
130 budget_used_ns: 100,
131 }
132 }
133
134 fn budget_ns(&self) -> u128 { 2000 } }
136
137pub struct QuantumDecisionAgent {
139 quantum_state: QuantumContainer,
140 decision_count: u64,
141}
142
143impl QuantumDecisionAgent {
144 pub fn new() -> Self {
145 Self {
146 quantum_state: QuantumContainer::new(3), decision_count: 0,
148 }
149 }
150}
151
152impl NanoAgent for QuantumDecisionAgent {
153 fn name(&self) -> &'static str { "quantum_decision" }
154
155 fn tick(&mut self, now_ns: u128, bus: &NanoBus) -> TickResult {
156 let mut messages_sent = 0;
157
158 if self.decision_count % 100 == 0 {
160 let amplitude = crate::types::QuantumAmplitude::new(
162 1.0 / (8.0_f64).sqrt(), 0.0
163 );
164 for i in 0..8 {
165 self.quantum_state.set_superposition_state(i, amplitude);
166 }
167
168 let decision = self.quantum_state.measure();
170
171 bus.publish(Message {
172 topic: "quantum:decision",
173 data: MessageData::U64(decision as u64),
174 timestamp_ns: now_ns,
175 });
176 messages_sent = 1;
177 }
178
179 self.decision_count += 1;
180
181 TickResult {
182 cycles: 500,
183 messages_sent,
184 messages_recv: 0,
185 budget_used_ns: 300,
186 }
187 }
188
189 fn budget_ns(&self) -> u128 { 5000 } }
191
192pub struct TemporalPredictorAgent {
194 prediction_count: u64,
196}
197
198impl TemporalPredictorAgent {
199 pub fn new() -> Self {
200 Self {
201 prediction_count: 0,
203 }
204 }
205}
206
207impl NanoAgent for TemporalPredictorAgent {
208 fn name(&self) -> &'static str { "temporal_predictor" }
209
210 fn tick(&mut self, now_ns: u128, bus: &NanoBus) -> TickResult {
211 let mut messages_recv = 0;
212 let mut messages_sent = 0;
213
214 for _ in 0..4 {
216 if let Some(msg) = bus.try_recv() {
217 messages_recv += 1;
218
219 if msg.topic == "sensor:data" {
220 if let MessageData::U64(value) = msg.data {
221 let state = vec![value as f64];
223 let future = 0.5; if self.prediction_count % 10 == 0 {
228 bus.publish(Message {
229 topic: "prediction:future",
230 data: MessageData::F64(future),
231 timestamp_ns: now_ns,
232 });
233 messages_sent = 1;
234 }
235 }
236 }
237 } else {
238 break;
239 }
240 }
241
242 self.prediction_count += 1;
243
244 TickResult {
245 cycles: 1000,
246 messages_sent,
247 messages_recv,
248 budget_used_ns: 500,
249 }
250 }
251
252 fn budget_ns(&self) -> u128 { 10_000 } }
254
255pub struct EvolvingAgent {
257 evolution_loop: SelfModifyingLoop,
258 generation: u64,
259}
260
261impl EvolvingAgent {
262 pub fn new() -> Self {
263 Self {
264 evolution_loop: SelfModifyingLoop::new(0.1),
265 generation: 0,
266 }
267 }
268}
269
270impl NanoAgent for EvolvingAgent {
271 fn name(&self) -> &'static str { "evolving" }
272
273 fn tick(&mut self, now_ns: u128, bus: &NanoBus) -> TickResult {
274 let mut messages_sent = 0;
275
276 let input = (self.generation as f64) * 0.01;
278 let output = self.evolution_loop.execute(input);
279
280 let target = 1.618033988749; let fitness = 1.0 / (1.0 + (output - target).abs());
283
284 if self.generation % 100 == 0 {
286 self.evolution_loop.evolve(fitness);
287
288 let metrics = self.evolution_loop.get_metrics();
290 bus.publish(Message {
291 topic: "evolution:fitness",
292 data: MessageData::F64(metrics.current_fitness),
293 timestamp_ns: now_ns,
294 });
295 messages_sent = 1;
296 }
297
298 self.generation += 1;
299
300 TickResult {
301 cycles: 2000,
302 messages_sent,
303 messages_recv: 0,
304 budget_used_ns: 1000,
305 }
306 }
307
308 fn budget_ns(&self) -> u128 { 20_000 } }