Skip to main content

systemprompt_runtime/optimization/
capture.rs

1//! Capture only configured authoring roots; clients cannot request arbitrary
2//! server files through source specifications.
3//!
4//! Copyright (c) systemprompt.io — Business Source License 1.1.
5//! See <https://systemprompt.io> for licensing details.
6
7use super::{OptimizationError, SkillOptimizationOrchestrator};
8use systemprompt_identifiers::{ManagedSourceId, UserId};
9use systemprompt_marketplace::managed::{ImportedSkills, ManagedError, SourceSpec, capture_skills};
10
11impl SkillOptimizationOrchestrator {
12    pub async fn capture_authoring_skills(
13        &self,
14        owner: &UserId,
15        source: &ManagedSourceId,
16        configured_root: &std::path::Path,
17        skills: Vec<String>,
18    ) -> Result<ImportedSkills, OptimizationError> {
19        let captured = self
20            .capture_authoring_input(owner, source, configured_root, skills)
21            .await?;
22        Ok(self
23            .managed
24            .import_skills(owner, source, &captured, None)
25            .await?)
26    }
27    pub async fn capture_authoring_input(
28        &self,
29        owner: &UserId,
30        source: &ManagedSourceId,
31        configured_root: &std::path::Path,
32        skills: Vec<String>,
33    ) -> Result<systemprompt_marketplace::managed::CapturedSkills, OptimizationError> {
34        let SourceSpec::LocalTree { root } = self.managed.get_source(owner, source).await? else {
35            return Err(OptimizationError::Source("Authoring capture requires a local-tree source; synchronize Git sources separately".to_owned()));
36        };
37        let expected = std::fs::canonicalize(configured_root).map_err(ManagedError::Io)?;
38        let actual = std::fs::canonicalize(root).map_err(ManagedError::Io)?;
39        if expected != actual {
40            return Err(OptimizationError::Source(
41                "Source root is not the configured authoring root".to_owned(),
42            ));
43        }
44        let captured = tokio::task::spawn_blocking(move || capture_skills(&actual, &skills))
45            .await
46            .map_err(|error| {
47                OptimizationError::Source(format!("Authoring capture task failed: {error}"))
48            })??;
49        Ok(captured)
50    }
51}