Skip to main content

oxios_kernel/kernel_handle/
token_maxing_api.rs

1//! TokenMaxing facade — exposes the [`QuotaTracker`] (status/report) and the
2//! [`TokenMaxer`] (start/stop/status/sessions) to the HTTP API and Web UI
3//! (RFC-031 §9).
4//!
5//! The single live tracker and maxer are constructed once at boot
6//! (`src/kernel.rs`) and shared here, so the API, UI, and orchestrator all
7//! reach the same instances.
8
9use std::sync::Arc;
10
11use crate::token_maxing::{
12    Availability, CooldownRecord, MaxerStatus, MaxingStart, ProviderSnapshot, QuotaTracker,
13    QuotaTrackerSnapshot, RecalibrationRecord, TokenMaxer, TokenMaxingConfig, TokenMaxingSession,
14};
15
16/// KernelHandle facade for token-maxing (RFC-031).
17///
18/// Read-side surface (status panel, report, eligibility) is re-exported here
19/// for the API/UI; the underlying tracker/maxer are reachable via
20/// [`Self::tracker`] / [`Self::maxer`] for anything not covered.
21pub struct TokenMaxingApi {
22    tracker: Arc<QuotaTracker>,
23    maxer: Arc<TokenMaxer>,
24}
25
26impl TokenMaxingApi {
27    /// Wrap the shared tracker + maxer.
28    pub fn new(tracker: Arc<QuotaTracker>, maxer: Arc<TokenMaxer>) -> Self {
29        Self { tracker, maxer }
30    }
31
32    /// The underlying tracker (for the recalibration tick).
33    pub fn tracker(&self) -> &Arc<QuotaTracker> {
34        &self.tracker
35    }
36
37    /// The underlying maxer.
38    pub fn maxer(&self) -> &Arc<TokenMaxer> {
39        &self.maxer
40    }
41
42    // ── Maxer control (RFC-031 §9 start/stop/status/sessions) ─────────────
43
44    /// Launch a session (window or manual). Returns the new session id.
45    pub fn launch(&self, start: MaxingStart) -> anyhow::Result<String> {
46        self.maxer.launch(start)
47    }
48
49    /// Request a graceful stop after the in-flight task.
50    pub fn stop(&self) {
51        self.maxer.stop();
52    }
53
54    /// Live status.
55    pub fn status(&self) -> MaxerStatus {
56        self.maxer.status()
57    }
58
59    /// Past sessions (most-recent last).
60    pub fn sessions(&self) -> Vec<TokenMaxingSession> {
61        self.maxer.sessions()
62    }
63
64    /// One past or in-flight session by id.
65    pub fn session(&self, id: &str) -> Option<TokenMaxingSession> {
66        self.maxer.session(id)
67    }
68
69    // ── Tracker status (RFC-031 §9 providers / report) ────────────────────
70
71    /// Whether the mode is enabled AND has at least one eligible provider.
72    pub fn enabled(&self) -> bool {
73        let cfg = self.tracker.config();
74        cfg.enabled && cfg.providers.iter().any(|p| cfg.is_eligible(&p.provider))
75    }
76
77    /// Current config snapshot.
78    pub fn config(&self) -> TokenMaxingConfig {
79        self.tracker.config()
80    }
81
82    /// Hot-reload the config, preserving usage counters for surviving providers.
83    pub fn reload(&self, config: TokenMaxingConfig) {
84        self.tracker.reload(config);
85    }
86
87    /// Per-provider availability verdict (RFC-031 §4).
88    pub fn availability(&self, provider: &str) -> Availability {
89        self.tracker.availability(provider)
90    }
91
92    /// All providers' verdicts (status panel + report).
93    pub fn snapshots(&self) -> Vec<QuotaTrackerSnapshot> {
94        self.tracker.snapshots()
95    }
96
97    /// Self-tracked snapshot for one provider (report fidelity).
98    pub fn snapshot(&self, provider: &str) -> Option<ProviderSnapshot> {
99        self.tracker.snapshot(provider)
100    }
101
102    /// Recalibration history (report).
103    pub fn recalibration_history(&self) -> Vec<RecalibrationRecord> {
104        self.tracker.recalibration_history()
105    }
106
107    /// Cooldown history (report).
108    pub fn cooldown_history(&self) -> Vec<CooldownRecord> {
109        self.tracker.cooldown_history()
110    }
111}