Skip to main content

vtcode_core/prompts/
output_styles.rs

1use std::path::Path;
2use std::sync::Arc;
3use tokio::sync::RwLock;
4use vtcode_config::{OutputStyleManager, VTCodeConfig};
5
6pub struct OutputStyleApplier {
7    manager: Arc<RwLock<OutputStyleManager>>,
8}
9
10impl OutputStyleApplier {
11    pub fn new() -> Self {
12        Self {
13            manager: Arc::new(RwLock::new(OutputStyleManager::new())),
14        }
15    }
16
17    pub async fn load_styles_from_config(
18        &self,
19        _config: &VTCodeConfig,
20        workspace: &Path,
21    ) -> Result<(), Box<dyn std::error::Error>> {
22        let output_styles_dir = workspace.join(".vtcode").join("output-styles");
23        let manager = OutputStyleManager::load_from_directory(&output_styles_dir)?;
24
25        {
26            let mut guard = self.manager.write().await;
27            *guard = manager;
28        }
29
30        Ok(())
31    }
32
33    pub async fn apply_style(
34        &self,
35        style_name: &str,
36        base_prompt: &str,
37        config: &VTCodeConfig,
38    ) -> String {
39        let guard = self.manager.read().await;
40
41        if let Some(style) = guard.get_style(style_name) {
42            if style.config.keep_coding_instructions {
43                // Combine base prompt with style content
44                format!("{}\n\n{}", base_prompt, style.content)
45            } else {
46                // Replace base prompt with style content
47                style.content.clone()
48            }
49        } else {
50            // If the requested style doesn't exist, use the active style from config
51            if let Some(active_style) = guard.get_style(&config.output_style.active_style) {
52                if active_style.config.keep_coding_instructions {
53                    format!("{}\n\n{}", base_prompt, active_style.content)
54                } else {
55                    active_style.content.clone()
56                }
57            } else {
58                // Fallback to base prompt if no style is found
59                base_prompt.to_string()
60            }
61        }
62    }
63
64    pub async fn get_available_styles(&self) -> Vec<String> {
65        let guard = self.manager.read().await;
66        guard
67            .list_styles()
68            .into_iter()
69            .map(|(name, _)| name.to_string())
70            .collect()
71    }
72}
73
74impl Default for OutputStyleApplier {
75    fn default() -> Self {
76        Self::new()
77    }
78}