vv-agent 0.4.1

VectorVein agent runtime, SDK, CLI, tools, and workspace backends
Documentation
use serde_json::{json, Value};

use super::hash::sha256_hex;
use super::options::BuiltSystemPrompt;
use super::section::PromptSection;

#[derive(Clone, Default)]
pub struct SystemPromptBuilder {
    sections: Vec<PromptSection>,
}

impl SystemPromptBuilder {
    pub fn add_section(&mut self, section: PromptSection) {
        self.sections.push(section);
    }

    pub fn build(&self) -> String {
        self.sections
            .iter()
            .filter_map(|section| {
                let value = section.get_value().trim().to_string();
                (!value.is_empty()).then_some(value)
            })
            .collect::<Vec<_>>()
            .join("\n\n")
    }

    pub fn metadata_sections(&self) -> Vec<Value> {
        self.sections
            .iter()
            .filter_map(PromptSection::to_metadata)
            .collect()
    }

    pub fn invalidate_all(&self) {
        for section in &self.sections {
            section.invalidate();
        }
    }

    pub fn invalidate_volatile(&self) {
        for section in &self.sections {
            if !section.stable() {
                section.invalidate();
            }
        }
    }

    pub fn stable_hash(&self) -> String {
        let stable_text = self
            .sections
            .iter()
            .filter(|section| section.stable())
            .map(|section| section.get_value().trim().to_string())
            .collect::<String>();
        sha256_hex(stable_text.as_bytes())
    }

    pub fn build_result(&self) -> BuiltSystemPrompt {
        let mut prompt_parts = Vec::new();
        let mut sections = Vec::new();
        let mut stable_parts = Vec::new();
        for section in &self.sections {
            let value = section.get_value().trim().to_string();
            if value.is_empty() {
                continue;
            }
            prompt_parts.push(value.clone());
            sections.push(json!({
                "id": section.id,
                "text": value,
                "stable": section.stable(),
            }));
            if section.stable() {
                stable_parts.push(value);
            }
        }
        BuiltSystemPrompt {
            prompt: prompt_parts.join("\n\n"),
            sections,
            stable_hash: sha256_hex(stable_parts.join("").as_bytes()),
        }
    }
}