87 lines
2.3 KiB
Rust
87 lines
2.3 KiB
Rust
use anyhow::Result;
|
|
use gpui::SharedString;
|
|
use handlebars::Handlebars;
|
|
use rust_embed::RustEmbed;
|
|
use serde::Serialize;
|
|
use std::sync::Arc;
|
|
|
|
#[derive(RustEmbed)]
|
|
#[folder = "src/templates"]
|
|
#[include = "*.hbs"]
|
|
struct Assets;
|
|
|
|
pub struct Templates(Handlebars<'static>);
|
|
|
|
impl Templates {
|
|
pub fn new() -> Arc<Self> {
|
|
let mut handlebars = Handlebars::new();
|
|
handlebars.set_strict_mode(true);
|
|
handlebars.register_helper("contains", Box::new(contains));
|
|
handlebars.register_embed_templates::<Assets>().unwrap();
|
|
Arc::new(Self(handlebars))
|
|
}
|
|
}
|
|
|
|
pub trait Template: Sized {
|
|
const TEMPLATE_NAME: &'static str;
|
|
|
|
fn render(&self, templates: &Templates) -> Result<String>
|
|
where
|
|
Self: Serialize + Sized,
|
|
{
|
|
Ok(templates.0.render(Self::TEMPLATE_NAME, self)?)
|
|
}
|
|
}
|
|
|
|
#[derive(Serialize)]
|
|
pub struct SystemPromptTemplate<'a> {
|
|
#[serde(flatten)]
|
|
pub project: &'a prompt_store::ProjectContext,
|
|
pub available_tools: Vec<SharedString>,
|
|
}
|
|
|
|
impl Template for SystemPromptTemplate<'_> {
|
|
const TEMPLATE_NAME: &'static str = "system_prompt.hbs";
|
|
}
|
|
|
|
/// Handlebars helper for checking if an item is in a list
|
|
fn contains(
|
|
h: &handlebars::Helper,
|
|
_: &handlebars::Handlebars,
|
|
_: &handlebars::Context,
|
|
_: &mut handlebars::RenderContext,
|
|
out: &mut dyn handlebars::Output,
|
|
) -> handlebars::HelperResult {
|
|
let list = h
|
|
.param(0)
|
|
.and_then(|v| v.value().as_array())
|
|
.ok_or_else(|| {
|
|
handlebars::RenderError::new("contains: missing or invalid list parameter")
|
|
})?;
|
|
let query = h.param(1).map(|v| v.value()).ok_or_else(|| {
|
|
handlebars::RenderError::new("contains: missing or invalid query parameter")
|
|
})?;
|
|
|
|
if list.contains(&query) {
|
|
out.write("true")?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_system_prompt_template() {
|
|
let project = prompt_store::ProjectContext::default();
|
|
let template = SystemPromptTemplate {
|
|
project: &project,
|
|
available_tools: vec!["echo".into()],
|
|
};
|
|
let templates = Templates::new();
|
|
let rendered = template.render(&templates).unwrap();
|
|
assert!(rendered.contains("## Fixing Diagnostics"));
|
|
}
|
|
}
|