use super::{ProviderItem, ProviderResult};
pub trait ContextProvider: Send + Sync {
fn id(&self) -> &'static str;
fn display_name(&self) -> &'static str;
fn supported_actions(&self) -> &[&str];
fn execute(&self, action: &str, params: &ProviderParams) -> Result<ProviderResult, String>;
fn reuse_binding(&self, _action: &str, _params: &ProviderParams) -> Option<String> {
None
}
fn reacquire_item(
&self,
_action: &str,
_params: &ProviderParams,
_item_id: &str,
) -> Result<ProviderResult, String> {
Err("provider does not support current item authorization".into())
}
fn cache_ttl_secs(&self) -> u64 {
120
}
fn consolidates(&self, _action: &str) -> bool {
true
}
fn descriptor(&self) -> ConnectorDescriptor {
ConnectorDescriptor::list_only("token or none")
}
fn requires_auth(&self) -> bool {
true
}
fn is_available(&self) -> bool;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize)]
#[serde(rename_all = "snake_case")]
pub enum CapabilityLevel {
Supported,
Partial,
Unsupported,
}
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize)]
pub struct ConnectorDescriptor {
pub principal_binding: &'static str,
pub search: CapabilityLevel,
pub list: CapabilityLevel,
pub get: CapabilityLevel,
pub delta: CapabilityLevel,
pub revalidate_acl: CapabilityLevel,
pub revalidate_revision: CapabilityLevel,
pub delete_event: CapabilityLevel,
pub content_trust: &'static str,
pub write_surface: &'static str,
pub failure_policy: &'static str,
pub notes: &'static str,
}
impl ConnectorDescriptor {
pub(crate) const UNTRUSTED: &'static str = "untrusted data";
pub(crate) const NO_WRITES: &'static str = "none";
pub(crate) const FAIL_CLOSED: &'static str = "deny; no stale or cached answer";
pub(crate) fn list_only(principal_binding: &'static str) -> Self {
Self {
principal_binding,
search: CapabilityLevel::Unsupported,
list: CapabilityLevel::Supported,
get: CapabilityLevel::Unsupported,
delta: CapabilityLevel::Unsupported,
revalidate_acl: CapabilityLevel::Unsupported,
revalidate_revision: CapabilityLevel::Unsupported,
delete_event: CapabilityLevel::Unsupported,
content_trust: Self::UNTRUSTED,
write_surface: Self::NO_WRITES,
failure_policy: Self::FAIL_CLOSED,
notes: "no item re-check: personal-local use only, withheld from governed reuse",
}
}
pub fn allows_shared_reuse(&self) -> bool {
self.revalidate_acl == CapabilityLevel::Supported
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
pub struct ProviderParams {
pub project: Option<String>,
pub state: Option<String>,
pub limit: Option<usize>,
pub query: Option<String>,
pub id: Option<String>,
}
#[derive(Debug, Clone)]
pub struct ContextPacket {
pub provider_id: String,
pub action: String,
pub items: Vec<ProviderItem>,
pub token_count_raw: usize,
pub token_count_compressed: usize,
pub cache_hit: bool,
}