Skip to main content

systemprompt_runtime/managed/
inventory.rs

1//! Core inventory orchestration uses configured services roots and
2//! organizational ownership.
3//!
4//! Copyright (c) systemprompt.io — Business Source License 1.1.
5//! See <https://systemprompt.io> for licensing details.
6
7use super::OrchestrationError;
8use crate::AppContext;
9use systemprompt_identifiers::UserId;
10use systemprompt_marketplace::inventory::{BaselineScope, InventoryService, InventoryStatus};
11pub use systemprompt_marketplace::inventory::{LatestPublication, LatestPublicationStatus};
12
13pub async fn refresh(
14    ctx: &AppContext,
15    owner: &UserId,
16) -> Result<InventoryStatus, OrchestrationError> {
17    let services = load_services(ctx, owner).await?;
18    Ok(
19        InventoryService::new(ctx.managed_repository().as_ref().clone())
20            .refresh(owner, ctx.app_paths().system().services(), &services)
21            .await?,
22    )
23}
24
25pub async fn publish_latest(
26    ctx: &AppContext,
27    owner: &UserId,
28    actor: &UserId,
29) -> Result<Vec<LatestPublication>, OrchestrationError> {
30    let services = load_services(ctx, owner).await?;
31    let service = InventoryService::new(ctx.managed_repository().as_ref().clone());
32    service
33        .refresh(owner, ctx.app_paths().system().services(), &services)
34        .await?;
35    let mut guard = ctx.publish_guard().lock().await;
36    Ok(service
37        .publish_latest(
38            &BaselineScope {
39                owner,
40                actor,
41                root: ctx.app_paths().system().services(),
42                services: &services,
43            },
44            &mut guard,
45        )
46        .await?)
47}
48
49async fn load_services(
50    ctx: &AppContext,
51    owner: &UserId,
52) -> Result<systemprompt_manifest::services::ServicesConfig, OrchestrationError> {
53    match systemprompt_loader::ConfigLoader::load() {
54        Ok(services) => Ok(services),
55        Err(error) => {
56            tracing::warn!(%error, "Configured inventory could not be loaded; previous inventory retained");
57            ctx.managed_repository()
58                .record_inventory_failure(owner)
59                .await?;
60            Err(OrchestrationError::InventoryLoad(error))
61        },
62    }
63}