Jido.AI.Prompt.Template (Jido AI v0.5.2)

View Source

Enables defining a prompt template and delaying the final building of it until a later time when input values are substituted in.

This also supports the ability to create a Message from a Template.

PromptTemplates are powerful because they support Elixir's EEx templates allowing for parameter substitution. This is helpful when we want to prepare a template message and plan to later substitute in information from the user.

Here's an example of setting up a template using a parameter then later providing the input value.

template = Jido.AI.Prompt.Template.from_string!("What's a name for a company that makes <%= @product %>?")

# later, format the final text after after applying the values.
Jido.AI.Prompt.Template.format(template, %{product: "colorful socks"})
#=> "What's a name for a company that makes colorful socks?"

Summary

Functions

Compile a template to check for syntax errors.

Creates a clean copy with reset version history

Estimates the number of tokens that would be used by this template. This is useful for ensuring prompts don't exceed model token limits.

Format the template with inputs to replace with assigns. It returns the formatted text.

Same as format/2 but raises on error.

Format a template with sub-templates.

Format the template text with inputs to replace placeholders.

Build a Template struct from a string.

Build a Template struct from a string and return the struct or error if invalid.

Build a Template with default values for parameters.

Build a Template with default values for parameters. Raises an exception if the template is invalid.

Increments the version number of the template. Returns a new template with the incremented version and adds the previous version to history.

Lists all available versions of the template

Create a new Template struct using the attributes.

Create a new Template struct using the attributes. If invalid, an exception is raised with the reason.

Records usage statistics for the template.

Rolls back to a specific version if it exists in history

Sanitizes user inputs to prevent template injection attacks.

Returns the NimbleOptions schema for Template.

Convert a template to a MessageItem struct.

Convert a template to a MessageItem struct. Raises if there's an error.

Convert a list of templates, message items, and strings to a list of message items.

Updates template text and automatically increments version

Validates the syntax of a template without evaluating it.

Types

t()

@type t() :: %Jido.AI.Prompt.Template{
  cacheable: boolean() | nil,
  created_at: DateTime.t() | nil,
  engine: :eex,
  estimated_tokens: non_neg_integer() | nil,
  inputs: map(),
  performance_stats: map() | nil,
  role: :system | :user | :assistant | :function,
  sample_inputs: map(),
  text: String.t(),
  version: non_neg_integer() | nil,
  version_history: [%{version: non_neg_integer(), text: String.t()}] | nil
}

Functions

compile(template)

Compile a template to check for syntax errors.

create_clean_copy(template)

Creates a clean copy with reset version history

estimate_tokens(template, inputs \\ %{})

@spec estimate_tokens(t(), inputs :: map()) :: integer()

Estimates the number of tokens that would be used by this template. This is useful for ensuring prompts don't exceed model token limits.

Note: This is a very rough estimation - tokens vary by model.

format(template, inputs \\ %{}, opts \\ [])

@spec format(t(), inputs :: map(), opts :: keyword()) :: String.t()

Format the template with inputs to replace with assigns. It returns the formatted text.

template = Jido.AI.Prompt.Template.from_string!("Suggest a name for a company that makes <%= @product %>?")
Jido.AI.Prompt.Template.format(template, %{product: "colorful socks"})
#=> "Suggest a name for a company that makes colorful socks?"

A Template supports storing input values on the struct. These could be set when the template is defined. If an input value is not provided when the format function is called, any inputs on the struct will be used.

format!(template, inputs)

Same as format/2 but raises on error.

format_composed(template, sub_templates, inputs \\ %{})

@spec format_composed(t(), sub_templates :: map(), inputs :: map()) :: String.t()

Format a template with sub-templates.

This is useful when you want to compose a template from other templates. The sub-templates can be either Template structs or strings.

Example

main = Template.new!(%{text: "Header: <%= @intro %>

Body: <%= @body %>"})

intro = Template.new!(%{text: "Welcome <%= @name %>!"})
body = "This is the body text."

Template.format_composed(main, %{intro: intro, body: body}, %{name: "Alice"})
#=> "Header: Welcome Alice!

Body: This is the body text."

format_text(text, inputs, engine \\ :eex)

@spec format_text(text :: String.t(), inputs :: map(), engine :: :eex) :: String.t()

Format the template text with inputs to replace placeholders.

Operates directly on text to apply the inputs. This does not take the Template struct.

Jido.AI.Prompt.Template.format_text("Hi! My name is <%= @name %>.", %{name: "Jose"})
#=> "Hi! My name is Jose."

from_string(text, opts \\ [])

@spec from_string(text :: String.t(), opts :: keyword()) ::
  {:ok, t()} | {:error, String.t()}

Build a Template struct from a string.

Shortcut function for building a user prompt.

{:ok, template} = Jido.AI.Prompt.Template.from_string("Suggest a name for a company that makes <%= @product %>?")

from_string!(text, opts \\ [])

@spec from_string!(text :: String.t(), opts :: keyword()) :: t() | no_return()

Build a Template struct from a string and return the struct or error if invalid.

Shortcut function for building a user prompt.

template = Jido.AI.Prompt.Template.from_string!("Suggest a name for a company that makes <%= @product %>?")

from_string_with_defaults(text, defaults \\ %{}, opts \\ [])

@spec from_string_with_defaults(
  text :: String.t(),
  defaults :: map(),
  opts :: keyword()
) ::
  {:ok, t()} | {:error, String.t()}

Build a Template with default values for parameters.

This is useful when you want to set some default values that can be overridden later.

template = Jido.AI.Prompt.Template.from_string_with_defaults(
  "Hello <%= @name %>, welcome to <%= @service %>!",
  %{service: "Jido AI"}
)
Jido.AI.Prompt.Template.format(template, %{name: "Alice"})
#=> "Hello Alice, welcome to Jido AI!"

from_string_with_defaults!(text, defaults \\ %{}, opts \\ [])

@spec from_string_with_defaults!(
  text :: String.t(),
  defaults :: map(),
  opts :: keyword()
) ::
  t() | no_return()

Build a Template with default values for parameters. Raises an exception if the template is invalid.

template = Jido.AI.Prompt.Template.from_string_with_defaults!(
  "Hello <%= @name %>, welcome to <%= @service %>!",
  %{service: "Jido AI"}
)

increment_version(template)

Increments the version number of the template. Returns a new template with the incremented version and adds the previous version to history.

list_versions(template)

Lists all available versions of the template

new(attrs)

@spec new(attrs :: map()) :: {:ok, t()} | {:error, String.t()}

Create a new Template struct using the attributes.

Example

{:ok, template} = Jido.AI.Prompt.Template.new(%{text: "My template", role: :user})

new!(attrs)

@spec new!(attrs :: map()) :: t() | no_return()

Create a new Template struct using the attributes. If invalid, an exception is raised with the reason.

Example

A template is created using a simple map with text and role keys.

Jido.AI.Prompt.Template.new!(%{text: "My template", role: :user})

Typically a template is used with parameter substitution as that's it's primary purpose. EEx is used to render the final text.

Jido.AI.Prompt.Template.new!(%{
  text: "My name is <%= @user_name %>. Warmly welcome me.",
  role: :user
})

record_usage(template, metrics)

@spec record_usage(t(), map()) :: t()

Records usage statistics for the template.

Parameters

  • template: The template to update
  • metrics: A map containing metrics to record, such as:
    • tokens_used: Number of tokens used in the response
    • response_time_ms: Time taken to generate response
    • success: Whether the generation was successful

Example

template = record_usage(template, %{
  tokens_used: 150,
  response_time_ms: 500,
  success: true
})

rollback_to_version(template, version)

Rolls back to a specific version if it exists in history

sanitize_inputs(inputs)

Sanitizes user inputs to prevent template injection attacks.

schema()

Returns the NimbleOptions schema for Template.

to_message(template, inputs \\ %{})

@spec to_message(t(), inputs :: map()) ::
  {:ok, Jido.AI.Prompt.MessageItem.t()} | {:error, String.t()}

Convert a template to a MessageItem struct.

This is useful when you want to use a template as part of a conversation.

to_message!(template, inputs \\ %{})

@spec to_message!(t(), inputs :: map()) ::
  Jido.AI.Prompt.MessageItem.t() | no_return()

Convert a template to a MessageItem struct. Raises if there's an error.

to_messages!(templates_or_messages, inputs \\ %{})

@spec to_messages!(list(), inputs :: map()) :: [Jido.AI.Prompt.MessageItem.t()]

Convert a list of templates, message items, and strings to a list of message items.

This is useful when you want to build a conversation from a mix of templates and messages.

Example

t1 = Template.new!(%{text: "System: <%= @sysinfo %>", role: :system})
t2 = Template.new!(%{text: "Question: <%= @question %>", role: :user})

messages = Template.to_messages!([t1, t2, "A direct user string"], %{
  sysinfo: "Guide the user",
  question: "What is 2+2?"
})

update_text(template, new_text)

Updates template text and automatically increments version

validate_template_syntax(template)

Validates the syntax of a template without evaluating it.