Skip to main content

lean_ctx_protocol/
fleet_control.rs

1//! Multi-agent authorization and budget-control contracts.
2
3use crate::{AgentId, MoneyV1};
4use serde::{Deserialize, Serialize};
5
6/// Policy constraining one agent's model and provider access.
7#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
8#[serde(deny_unknown_fields)]
9pub struct AgentPolicy {
10    pub agent_id: AgentId,
11    pub budget_limit: MoneyV1,
12    pub allowed_models: Vec<String>,
13    pub allowed_providers: Vec<String>,
14    pub priority: u8,
15}
16
17/// Current authorization and spend state for an agent fleet.
18#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
19#[serde(deny_unknown_fields)]
20pub struct FleetState {
21    pub active_agents: Vec<AgentId>,
22    pub total_spend: MoneyV1,
23    pub budget_remaining: MoneyV1,
24}
25
26/// Extension point for Enterprise fleet controllers such as `BudgetedFleetControl`.
27pub trait FleetControlContract {
28    /// Authorize an agent's estimated cost before it is incurred.
29    fn authorize(&self, agent_id: &AgentId, cost_estimate: &MoneyV1) -> bool;
30}
31
32/// OSS single-user fleet controller that imposes no authorization limits.
33#[derive(Debug, Default, Clone, Copy)]
34pub struct LocalFleetControl;
35
36impl FleetControlContract for LocalFleetControl {
37    fn authorize(&self, _agent_id: &AgentId, _cost_estimate: &MoneyV1) -> bool {
38        true
39    }
40}
41
42#[cfg(test)]
43mod tests {
44    use super::*;
45
46    fn cost() -> MoneyV1 {
47        MoneyV1 {
48            currency: "USD".to_owned(),
49            coefficient: 1,
50            scale: 4,
51        }
52    }
53
54    #[test]
55    fn local_fleet_control_always_authorizes() {
56        let agent_id = AgentId::try_from("agent-1".to_owned()).expect("identifier should be valid");
57        assert!(LocalFleetControl.authorize(&agent_id, &cost()));
58    }
59
60    #[test]
61    fn contract_is_object_safe() {
62        let fleet_control: &dyn FleetControlContract = &LocalFleetControl;
63        let agent_id = AgentId::try_from("agent-1".to_owned()).expect("identifier should be valid");
64        assert!(fleet_control.authorize(&agent_id, &cost()));
65    }
66}