Skip to main content

rskit_ai/prompt/
render.rs

1//! Prompt rendering helpers.
2
3use std::collections::BTreeSet;
4
5use rskit_util::template::{DynamicTemplate, TemplateError};
6
7use crate::chat::{Message, SystemMessage};
8
9use super::template::{PromptError, PromptTemplate, RenderContext};
10
11/// Render a template string using `{{var}}` placeholders. Handles optional whitespace: `{{ var }}`
12/// and `{{var}}` are equivalent.
13pub fn render(template: &str, context: &RenderContext) -> Result<String, PromptError> {
14    DynamicTemplate::parse(template)
15        .render(|name| {
16            context.get(name).map(|value| {
17                value
18                    .as_str()
19                    .map_or_else(|| value.to_string(), ToString::to_string)
20            })
21        })
22        .map_err(|error| match error {
23            TemplateError::MissingVariable(name) => PromptError::MissingVariable(name),
24            other => PromptError::MissingVariable(other.to_string()),
25        })
26}
27
28/// Convert rendered prompts into AI messages.
29pub trait RenderToMessage {
30    /// Render into a system message.
31    fn render_to_message(&self, context: &RenderContext) -> Result<Message, PromptError>;
32}
33
34impl RenderToMessage for PromptTemplate {
35    fn render_to_message(&self, context: &RenderContext) -> Result<Message, PromptError> {
36        Ok(Message::System(SystemMessage {
37            content: self.render(context)?,
38        }))
39    }
40}
41
42pub(crate) fn placeholders(template: &str) -> BTreeSet<String> {
43    DynamicTemplate::parse(template).variables()
44}