Skip to main content

maple_runtime/types/
attention.rs

1//! Attention budget and allocation types
2//!
3//! CRITICAL INVARIANT: Coupling MUST always be bounded by available attention.
4
5use super::ids::CouplingId;
6use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8
9/// Attention budget for a Resonator
10///
11/// Attention is the finite capacity of a Resonator to process resonance.
12#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct AttentionBudget {
14    /// Total attention capacity
15    pub total_capacity: u64,
16
17    /// Currently allocated attention (by coupling)
18    pub allocated: HashMap<CouplingId, u64>,
19
20    /// Reserved for safety (never fully deplete)
21    pub safety_reserve: u64,
22
23    /// Threshold that triggers degradation (0.0 to 1.0)
24    pub exhaustion_threshold: f64,
25}
26
27impl AttentionBudget {
28    pub fn new(total_capacity: u64) -> Self {
29        let safety_reserve = total_capacity / 10; // Reserve 10%
30        Self {
31            total_capacity,
32            allocated: HashMap::new(),
33            safety_reserve,
34            exhaustion_threshold: 0.8,
35        }
36    }
37
38    /// Calculate currently used attention
39    pub fn used(&self) -> u64 {
40        self.allocated.values().sum()
41    }
42
43    /// Calculate available attention
44    pub fn available(&self) -> u64 {
45        self.total_capacity
46            .saturating_sub(self.used())
47            .saturating_sub(self.safety_reserve)
48    }
49
50    /// Calculate utilization (0.0 to 1.0)
51    pub fn utilization(&self) -> f64 {
52        if self.total_capacity == 0 {
53            return 0.0;
54        }
55        self.used() as f64 / self.total_capacity as f64
56    }
57
58    /// Is exhaustion imminent?
59    pub fn is_exhaustion_imminent(&self) -> bool {
60        self.utilization() > self.exhaustion_threshold
61    }
62
63    /// Can allocate this amount?
64    pub fn can_allocate(&self, amount: u64) -> bool {
65        self.available() >= amount
66    }
67}
68
69/// Attention allocation specification
70#[derive(Debug, Clone, Serialize, Deserialize)]
71pub struct AttentionBudgetSpec {
72    /// Total capacity to allocate
73    pub total_capacity: u64,
74
75    /// Custom safety reserve (optional)
76    pub safety_reserve: Option<u64>,
77
78    /// Custom exhaustion threshold (optional)
79    pub exhaustion_threshold: Option<f64>,
80}
81
82impl Default for AttentionBudgetSpec {
83    fn default() -> Self {
84        Self {
85            total_capacity: 10000,
86            safety_reserve: None,
87            exhaustion_threshold: None,
88        }
89    }
90}
91
92/// What happens when attention is exhausted?
93#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
94pub enum ExhaustionBehavior {
95    /// Reject new coupling attempts
96    Reject,
97
98    /// Gracefully degrade by weakening existing couplings
99    GracefulDegrade,
100
101    /// Queue new couplings for later
102    Queue,
103}
104
105/// Attention class for prioritization
106#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
107pub enum AttentionClass {
108    /// Critical operations (safety-related)
109    Critical,
110
111    /// High priority
112    High,
113
114    /// Normal priority
115    Normal,
116
117    /// Low priority (background tasks)
118    Low,
119}
120
121impl AttentionClass {
122    /// Get the attention cost multiplier for this class
123    pub fn cost_multiplier(&self) -> f64 {
124        match self {
125            AttentionClass::Critical => 2.0,
126            AttentionClass::High => 1.5,
127            AttentionClass::Normal => 1.0,
128            AttentionClass::Low => 0.5,
129        }
130    }
131}
132
133/// Configuration for attention allocation
134#[derive(Debug, Clone, Serialize, Deserialize)]
135pub struct AttentionConfig {
136    /// Default capacity for new Resonators
137    pub default_capacity: u64,
138
139    /// Allow unlimited attention (disable attention economics)
140    pub allow_unlimited: bool,
141
142    /// Behavior on exhaustion
143    pub exhaustion_behavior: ExhaustionBehavior,
144
145    /// Enable attention rebalancing?
146    pub enable_rebalancing: bool,
147}
148
149impl Default for AttentionConfig {
150    fn default() -> Self {
151        Self {
152            default_capacity: 10000,
153            allow_unlimited: false,
154            exhaustion_behavior: ExhaustionBehavior::GracefulDegrade,
155            enable_rebalancing: true,
156        }
157    }
158}