loong-contracts 0.1.2-alpha.1

Internal support crate for Loong: stable shared contracts
Documentation
use std::collections::BTreeSet;

use serde::{Deserialize, Serialize};
use serde_json::Value;

#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub enum Capability {
    InvokeTool,
    InvokeConnector,
    MemoryRead,
    MemoryWrite,
    FilesystemRead,
    FilesystemWrite,
    NetworkEgress,
    ObserveTelemetry,
    ControlRead,
    ControlWrite,
    ControlApprovals,
    ControlPairing,
    ControlAcp,
}

impl Capability {
    pub const fn as_str(self) -> &'static str {
        match self {
            Self::InvokeTool => "invoke_tool",
            Self::InvokeConnector => "invoke_connector",
            Self::MemoryRead => "memory_read",
            Self::MemoryWrite => "memory_write",
            Self::FilesystemRead => "filesystem_read",
            Self::FilesystemWrite => "filesystem_write",
            Self::NetworkEgress => "network_egress",
            Self::ObserveTelemetry => "observe_telemetry",
            Self::ControlRead => "control_read",
            Self::ControlWrite => "control_write",
            Self::ControlApprovals => "control_approvals",
            Self::ControlPairing => "control_pairing",
            Self::ControlAcp => "control_acp",
        }
    }

    pub fn parse(raw: &str) -> Option<Self> {
        match raw.trim().to_ascii_lowercase().replace('-', "_").as_str() {
            "invoke_tool" => Some(Self::InvokeTool),
            "invoke_connector" => Some(Self::InvokeConnector),
            "memory_read" => Some(Self::MemoryRead),
            "memory_write" => Some(Self::MemoryWrite),
            "filesystem_read" => Some(Self::FilesystemRead),
            "filesystem_write" => Some(Self::FilesystemWrite),
            "network_egress" => Some(Self::NetworkEgress),
            "observe_telemetry" => Some(Self::ObserveTelemetry),
            "control_read" => Some(Self::ControlRead),
            "control_write" => Some(Self::ControlWrite),
            "control_approvals" => Some(Self::ControlApprovals),
            "control_pairing" => Some(Self::ControlPairing),
            "control_acp" => Some(Self::ControlAcp),
            _ => None,
        }
    }
}

#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum HarnessKind {
    EmbeddedPi,
    Acp,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ExecutionRoute {
    pub harness_kind: HarnessKind,
    pub adapter: Option<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct CapabilityToken {
    pub token_id: String,
    pub pack_id: String,
    pub agent_id: String,
    pub allowed_capabilities: BTreeSet<Capability>,
    pub issued_at_epoch_s: u64,
    pub expires_at_epoch_s: u64,
    pub generation: u64,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct TaskIntent {
    pub task_id: String,
    pub objective: String,
    pub required_capabilities: BTreeSet<Capability>,
    pub payload: Value,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct HarnessRequest {
    pub token_id: String,
    pub pack_id: String,
    pub agent_id: String,
    pub task_id: String,
    pub objective: String,
    pub payload: Value,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct HarnessOutcome {
    pub status: String,
    pub output: Value,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ConnectorCommand {
    pub connector_name: String,
    pub operation: String,
    pub required_capabilities: BTreeSet<Capability>,
    pub payload: Value,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ConnectorOutcome {
    pub status: String,
    pub payload: Value,
}

#[cfg(test)]
mod tests {
    use super::Capability;

    #[test]
    fn capability_round_trips_through_canonical_names() {
        let fixtures = [
            (Capability::InvokeTool, "invoke_tool"),
            (Capability::InvokeConnector, "invoke_connector"),
            (Capability::MemoryRead, "memory_read"),
            (Capability::MemoryWrite, "memory_write"),
            (Capability::FilesystemRead, "filesystem_read"),
            (Capability::FilesystemWrite, "filesystem_write"),
            (Capability::NetworkEgress, "network_egress"),
            (Capability::ObserveTelemetry, "observe_telemetry"),
            (Capability::ControlRead, "control_read"),
            (Capability::ControlWrite, "control_write"),
            (Capability::ControlApprovals, "control_approvals"),
            (Capability::ControlPairing, "control_pairing"),
            (Capability::ControlAcp, "control_acp"),
        ];

        for (capability, expected_name) in fixtures {
            assert_eq!(capability.as_str(), expected_name);
            assert_eq!(Capability::parse(expected_name), Some(capability));
            assert_eq!(
                Capability::parse(&expected_name.to_ascii_uppercase()),
                Some(capability)
            );
            assert_eq!(
                Capability::parse(&expected_name.replace('_', "-")),
                Some(capability)
            );
        }
    }

    #[test]
    fn capability_parse_rejects_unknown_values() {
        assert_eq!(Capability::parse("totally_unknown"), None);
        assert_eq!(Capability::parse(""), None);
        assert_eq!(Capability::parse("   "), None);
        assert_eq!(Capability::parse("schedule_task"), None);
    }
}