use systemprompt_identifiers::{ApiKeyId, UserId};
use systemprompt_marketplace::MarketplaceCandidate;
use systemprompt_models::bridge::host::HostKind;
use systemprompt_models::bridge::manifest::UserInfo;
use systemprompt_runtime::AppContext;
use super::super::bridge_data;
use super::super::bridge_error::BridgeError;
pub(super) async fn record_catalog_grants(
ctx: &AppContext,
user_id: &UserId,
candidate: &MarketplaceCandidate,
) -> Result<(), BridgeError> {
let owner = ctx.system_admin().id();
if user_id == owner {
return Ok(());
}
let repository = ctx.managed_repository();
for publication in candidate
.skills
.iter()
.filter_map(|skill| skill.publication.as_ref())
{
repository
.retain_consumer_catalog_grant(owner, &publication.resource_id, user_id)
.await
.map_err(|source| BridgeError::CatalogGrant {
resource: publication.resource_id.clone(),
source,
})?;
}
Ok(())
}
pub(super) struct PerUserContext {
pub user: Option<UserInfo>,
pub revocations: Vec<ApiKeyId>,
pub enabled_hosts: Vec<String>,
pub host_model_protocols: std::collections::BTreeMap<String, Vec<String>>,
}
pub(super) async fn load_per_user_context(
ctx: &AppContext,
user_id: &UserId,
instance_hosts: Vec<HostKind>,
) -> Result<PerUserContext, BridgeError> {
let user = match bridge_data::load_user(ctx, user_id).await {
Ok(u) => u,
Err(e) => {
tracing::warn!(error = %e, "manifest: user load failed; continuing without user");
None
},
};
let revocations = bridge_data::load_revocations(ctx, user_id)
.await
.map_err(|e| BridgeError::internal("manifest: revocations unavailable", e))?;
let enabled_hosts = match bridge_data::load_enabled_hosts(ctx, user_id).await {
Ok(prefs) => instance_hosts
.into_iter()
.filter(|host| prefs.admits(*host))
.map(|host| host.as_str().to_owned())
.collect(),
Err(e) => {
return Err(BridgeError::internal(
"manifest: enabled hosts unavailable",
e,
));
},
};
let host_model_protocols = match bridge_data::load_host_model_protocols(ctx, user_id).await {
Ok(rows) => rows
.into_iter()
.map(|(host, protocols)| (host.as_str().to_owned(), protocols))
.collect(),
Err(e) => {
tracing::warn!(
error = %e,
"manifest: host model-protocol prefs load failed; continuing with defaults"
);
std::collections::BTreeMap::new()
},
};
Ok(PerUserContext {
user,
revocations,
enabled_hosts,
host_model_protocols,
})
}