anchor_chain/nodes/
prompt.rs

1//! Module for handling dynamic prompts in processing chains.
2//!
3//! This module provides the `Prompt` struct, a processor for handling
4//! and displaying text prompts. The `Prompt` struct uses Tera templating
5//! to allow for dynamic input substitution in the prompt text. Tera is a
6//! template engine that allows for dynamic templating using variables with
7//! a similar syntax to Jinja2. For more information on Tera, see the
8//! [Tera documentation](https://keats.github.io/tera/docs/#templates).
9
10use std::collections::HashMap;
11
12use async_trait::async_trait;
13use tera::{Context, Tera};
14#[cfg(feature = "tracing")]
15use tracing::instrument;
16
17use crate::error::AnchorChainError;
18use crate::node::Node;
19
20/// A processor for handling text prompts within a processing chain.
21///
22/// The `Prompt` struct is a processor for handling text prompts within a
23/// processing chain using Tera templating.
24#[derive(Debug)]
25pub struct Prompt {
26    /// The Tera template used to process the prompt text.
27    tera: Tera,
28}
29
30impl Prompt {
31    /// Creates a new `Prompt` processor with the specified template.
32    ///
33    /// Templates need to be specified using the Tera syntax which is based on
34    /// Jinja2. For more information on Tera, see the
35    /// [Tera Templates documentation](https://keats.github.io/tera/docs/#templates).
36    ///
37    /// # Examples
38    /// ```rust
39    /// use anchor_chain::nodes::prompt::Prompt;
40    ///
41    /// let prompt = Prompt::new("Create a {{ language }} program that prints 'Hello, World!'");
42    /// ```
43    pub fn new(template: &str) -> Self {
44        let mut tera = Tera::default();
45        tera.add_raw_template("prompt", template)
46            .expect("Error creating template");
47        Prompt { tera }
48    }
49}
50
51/// Implements the `Node` trait for the `Prompt` struct.
52#[async_trait]
53impl Node for Prompt {
54    /// Input HashMap that will be converted to the tera::Context.
55    type Input = HashMap<String, String>;
56    /// Output string from the rendered template.
57    type Output = String;
58
59    /// Processes the input HashMap and returns the rendered template.
60    #[cfg_attr(feature = "tracing", instrument)]
61    async fn process(&self, input: Self::Input) -> Result<Self::Output, AnchorChainError> {
62        let context = Context::from_serialize(input)?;
63        Ok(self.tera.render("prompt", &context)?.to_string())
64    }
65}