Skip to main content

vtcode_core/skills/
injection.rs

1use crate::skills::model::SkillLoadOutcome;
2use tokio::fs;
3
4use super::instructions::SkillInstructions;
5
6#[derive(Debug, Default)]
7pub struct SkillInjections {
8    pub items: Vec<SkillInstructions>,
9    pub warnings: Vec<String>,
10}
11
12/// Builds injections for the specified skills.
13///
14/// `skill_names` is a list of skill names that should be loaded (e.g. detected from user input).
15pub async fn build_skill_injections(
16    skill_names: &[String],
17    skills: Option<&SkillLoadOutcome>,
18) -> SkillInjections {
19    if skill_names.is_empty() {
20        return SkillInjections::default();
21    }
22
23    let Some(outcome) = skills else {
24        return SkillInjections::default();
25    };
26
27    let mut result = SkillInjections {
28        items: Vec::with_capacity(skill_names.len()),
29        warnings: Vec::new(),
30    };
31
32    for name in skill_names {
33        if let Some(skill) = outcome.skills.iter().find(|s| s.name == *name) {
34            match fs::read_to_string(&skill.path).await {
35                Ok(contents) => {
36                    result.items.push(SkillInstructions {
37                        name: skill.name.clone(),
38                        path: skill.path.clone(),
39                        contents,
40                    });
41                }
42                Err(err) => {
43                    let message = format!(
44                        "Failed to load skill {} at {}: {err:#}",
45                        skill.name,
46                        skill.path.display()
47                    );
48                    result.warnings.push(message);
49                }
50            }
51        }
52    }
53
54    result
55}