use async_trait::async_trait;
use chrono::{DateTime, Utc};
use uuid::Uuid;
use crate::error::StorageError;
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum StoredTrustLevel {
Untrusted,
Basic,
Verified,
Trusted,
}
impl std::fmt::Display for StoredTrustLevel {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
StoredTrustLevel::Untrusted => write!(f, "untrusted"),
StoredTrustLevel::Basic => write!(f, "basic"),
StoredTrustLevel::Verified => write!(f, "verified"),
StoredTrustLevel::Trusted => write!(f, "trusted"),
}
}
}
impl std::str::FromStr for StoredTrustLevel {
type Err = StorageError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"untrusted" => Ok(StoredTrustLevel::Untrusted),
"basic" => Ok(StoredTrustLevel::Basic),
"verified" => Ok(StoredTrustLevel::Verified),
"trusted" => Ok(StoredTrustLevel::Trusted),
_ => Err(StorageError::Serialization(format!(
"unknown trust level: {s}"
))),
}
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct StoredAgent {
pub id: Uuid,
pub owner: String,
pub model: String,
pub capabilities: Vec<String>,
pub trust_level: StoredTrustLevel,
pub created_at: DateTime<Utc>,
pub expires_at: Option<DateTime<Utc>>,
pub active: bool,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct StoredDelegationLink {
pub id: i64,
pub from_agent: Uuid,
pub to_agent: Uuid,
pub scope_narrowing: Vec<String>,
pub created_at: DateTime<Utc>,
pub expires_at: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum StoredSessionStatus {
Active,
Closed,
Expired,
}
impl std::fmt::Display for StoredSessionStatus {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
StoredSessionStatus::Active => write!(f, "active"),
StoredSessionStatus::Closed => write!(f, "closed"),
StoredSessionStatus::Expired => write!(f, "expired"),
}
}
}
impl std::str::FromStr for StoredSessionStatus {
type Err = StorageError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"active" => Ok(StoredSessionStatus::Active),
"closed" => Ok(StoredSessionStatus::Closed),
"expired" => Ok(StoredSessionStatus::Expired),
_ => Err(StorageError::Serialization(format!(
"unknown session status: {s}"
))),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum StoredDataSensitivity {
Public,
Internal,
Confidential,
Restricted,
}
impl std::fmt::Display for StoredDataSensitivity {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
StoredDataSensitivity::Public => write!(f, "public"),
StoredDataSensitivity::Internal => write!(f, "internal"),
StoredDataSensitivity::Confidential => write!(f, "confidential"),
StoredDataSensitivity::Restricted => write!(f, "restricted"),
}
}
}
impl std::str::FromStr for StoredDataSensitivity {
type Err = StorageError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"public" => Ok(StoredDataSensitivity::Public),
"internal" => Ok(StoredDataSensitivity::Internal),
"confidential" => Ok(StoredDataSensitivity::Confidential),
"restricted" => Ok(StoredDataSensitivity::Restricted),
_ => Err(StorageError::Serialization(format!(
"unknown data sensitivity: {s}"
))),
}
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct StoredSession {
pub session_id: Uuid,
pub agent_id: Uuid,
pub delegation_chain_snapshot: Vec<String>,
pub declared_intent: String,
pub authorized_tools: Vec<String>,
pub time_limit_secs: i64,
pub call_budget: u64,
pub calls_made: u64,
pub rate_limit_per_minute: Option<u64>,
pub rate_window_start: DateTime<Utc>,
pub rate_window_calls: u64,
pub rate_limit_window_secs: u64,
pub data_sensitivity_ceiling: StoredDataSensitivity,
pub created_at: DateTime<Utc>,
pub status: StoredSessionStatus,
}
#[async_trait]
pub trait AgentStore: Send + Sync {
async fn insert_agent(&self, agent: &StoredAgent) -> Result<(), StorageError>;
async fn get_agent(&self, id: Uuid) -> Result<StoredAgent, StorageError>;
async fn update_trust_level(
&self,
id: Uuid,
level: StoredTrustLevel,
) -> Result<(), StorageError>;
async fn deactivate_agent(&self, id: Uuid) -> Result<(), StorageError>;
async fn list_agents(&self) -> Result<Vec<StoredAgent>, StorageError>;
}
#[async_trait]
pub trait SessionStore: Send + Sync {
async fn insert_session(&self, session: &StoredSession) -> Result<(), StorageError>;
async fn get_session(&self, session_id: Uuid) -> Result<StoredSession, StorageError>;
async fn update_session(&self, session: &StoredSession) -> Result<(), StorageError>;
async fn delete_expired_sessions(&self) -> Result<usize, StorageError>;
async fn list_sessions(&self) -> Result<Vec<StoredSession>, StorageError>;
}
#[async_trait]
pub trait DelegationStore: Send + Sync {
async fn insert_delegation(&self, link: &StoredDelegationLink) -> Result<i64, StorageError>;
async fn get_delegations_from(
&self,
agent_id: Uuid,
) -> Result<Vec<StoredDelegationLink>, StorageError>;
async fn get_delegations_to(
&self,
agent_id: Uuid,
) -> Result<Vec<StoredDelegationLink>, StorageError>;
async fn list_delegations(&self) -> Result<Vec<StoredDelegationLink>, StorageError>;
}