swiftide_agents/
system_prompt.rsuse derive_builder::Builder;
use swiftide_core::{prompt::Prompt, template::Template};
#[derive(Clone, Debug, Builder)]
#[builder(setter(into, strip_option))]
pub struct SystemPrompt {
#[builder(default)]
role: Option<String>,
#[builder(default, setter(custom))]
guidelines: Vec<String>,
#[builder(default, setter(custom))]
constraints: Vec<String>,
#[builder(default = default_prompt_template())]
template: Template,
}
impl SystemPrompt {
pub fn builder() -> SystemPromptBuilder {
SystemPromptBuilder::default()
}
}
impl Default for SystemPrompt {
fn default() -> Self {
SystemPrompt {
role: None,
guidelines: Vec::new(),
constraints: Vec::new(),
template: default_prompt_template(),
}
}
}
impl SystemPromptBuilder {
pub fn guidelines<T: IntoIterator<Item = S>, S: AsRef<str>>(
&mut self,
guidelines: T,
) -> &mut Self {
self.guidelines = Some(
guidelines
.into_iter()
.map(|s| s.as_ref().to_string())
.collect(),
);
self
}
pub fn constraints<T: IntoIterator<Item = S>, S: AsRef<str>>(
&mut self,
constraints: T,
) -> &mut Self {
self.constraints = Some(
constraints
.into_iter()
.map(|s| s.as_ref().to_string())
.collect(),
);
self
}
}
fn default_prompt_template() -> Template {
include_str!("system_prompt_template.md").into()
}
#[allow(clippy::from_over_into)]
impl Into<Prompt> for SystemPrompt {
fn into(self) -> Prompt {
let SystemPrompt {
role,
guidelines,
constraints,
template,
} = self;
template
.to_prompt()
.with_context_value("role", role)
.with_context_value("guidelines", guidelines)
.with_context_value("constraints", constraints)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_customization() {
let prompt = SystemPrompt::builder()
.role("role")
.guidelines(["guideline"])
.constraints(vec!["constraint".to_string()])
.build()
.unwrap();
let prompt: Prompt = prompt.into();
let rendered = prompt.render().await.unwrap();
insta::assert_snapshot!(rendered);
}
}