use async_trait::async_trait;
use std::sync::Arc;
use systemprompt_identifiers::{ManagedResourceId, ResourceRevisionId, SkillId, UserId};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ResolvedManagedSkill {
pub id: SkillId,
pub name: String,
pub description: String,
pub instructions: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WithheldReason {
NeverAdopted,
NotGranted,
Withdrawn,
}
impl WithheldReason {
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::NotGranted => "not granted",
Self::NeverAdopted => "never adopted",
Self::Withdrawn => "withdrawn",
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SkillResolution {
NotManaged,
Published(ResolvedManagedSkill),
Withheld(WithheldReason),
}
#[derive(Debug, thiserror::Error)]
pub enum ManagedSkillResolverError {
#[error("managed skill `{key}` failed integrity verification")]
Integrity { key: String },
#[error("managed skill resolver unavailable: {0}")]
Unavailable(String),
}
#[async_trait]
pub trait ManagedSkillResolver: Send + Sync + std::fmt::Debug {
async fn resolve_skill(
&self,
owner: &UserId,
key: &str,
) -> Result<SkillResolution, ManagedSkillResolverError>;
}
pub type DynManagedSkillResolver = Arc<dyn ManagedSkillResolver>;
#[async_trait]
pub trait ManagedRevisionOwnership: Send + Sync {
async fn revision_resource(
&self,
owner: &UserId,
revision: &ResourceRevisionId,
) -> Result<Option<ManagedResourceId>, ManagedSkillResolverError>;
}
pub type DynManagedRevisionOwnership = Arc<dyn ManagedRevisionOwnership>;