strange_loop/nano_agent/
agents.rs1use super::{NanoAgent, NanoBus, Message, TickResult, spin};
4use super::bus::MessageData;
5use crate::TemporalLeadPredictor;
6use 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 predictor: TemporalLeadPredictor,
195 prediction_count: u64,
196}
197
198impl TemporalPredictorAgent {
199 pub fn new() -> Self {
200 Self {
201 predictor: TemporalLeadPredictor::new(100_000, 50),
202 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 = self.predictor.predict_future(state);
224
225 if self.prediction_count % 10 == 0 {
227 bus.publish(Message {
228 topic: "prediction:future",
229 data: MessageData::F64(future[0]),
230 timestamp_ns: now_ns,
231 });
232 messages_sent = 1;
233 }
234 }
235 }
236 } else {
237 break;
238 }
239 }
240
241 self.prediction_count += 1;
242
243 TickResult {
244 cycles: 1000,
245 messages_sent,
246 messages_recv,
247 budget_used_ns: 500,
248 }
249 }
250
251 fn budget_ns(&self) -> u128 { 10_000 } }
253
254pub struct EvolvingAgent {
256 evolution_loop: SelfModifyingLoop,
257 generation: u64,
258}
259
260impl EvolvingAgent {
261 pub fn new() -> Self {
262 Self {
263 evolution_loop: SelfModifyingLoop::new(0.1),
264 generation: 0,
265 }
266 }
267}
268
269impl NanoAgent for EvolvingAgent {
270 fn name(&self) -> &'static str { "evolving" }
271
272 fn tick(&mut self, now_ns: u128, bus: &NanoBus) -> TickResult {
273 let mut messages_sent = 0;
274
275 let input = (self.generation as f64) * 0.01;
277 let output = self.evolution_loop.execute(input);
278
279 let target = 1.618033988749; let fitness = 1.0 / (1.0 + (output - target).abs());
282
283 if self.generation % 100 == 0 {
285 self.evolution_loop.evolve(fitness);
286
287 let metrics = self.evolution_loop.get_metrics();
289 bus.publish(Message {
290 topic: "evolution:fitness",
291 data: MessageData::F64(metrics.current_fitness),
292 timestamp_ns: now_ns,
293 });
294 messages_sent = 1;
295 }
296
297 self.generation += 1;
298
299 TickResult {
300 cycles: 2000,
301 messages_sent,
302 messages_recv: 0,
303 budget_used_ns: 1000,
304 }
305 }
306
307 fn budget_ns(&self) -> u128 { 20_000 } }