systemprompt_runtime/optimization/
capture.rs1use 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}