# `PhoenixKitAI.Prompt`
[🔗](https://github.com/BeamLabEU/phoenix_kit_ai/blob/v0.4.0/lib/phoenix_kit_ai/prompt.ex#L1)

AI prompt schema for PhoenixKit AI system.

A prompt is a reusable text template with variable substitution support.
Variables use the `{{VariableName}}` syntax and are automatically extracted
from the content when saved.

## Schema Fields

### Identity
- `name`: Display name for the prompt (unique)
- `slug`: URL-friendly identifier (auto-generated from name, unique)
- `description`: Optional description of the prompt's purpose

### Content
- `content`: The prompt template text with optional `{{variables}}`
- `variables`: Auto-extracted variable names from content

### Status
- `enabled`: Whether the prompt is active
- `sort_order`: Display order for listing

### Usage Tracking
- `usage_count`: Number of times the prompt has been used
- `last_used_at`: Timestamp of the last usage

### Metadata
- `metadata`: Flexible JSON storage for additional data

## Variable Syntax

Variables use double curly braces: `{{VariableName}}`

- Variable names must be alphanumeric with underscores
- Variables are case-sensitive
- Unmatched variables remain in the output as-is

## Usage Examples

    # Create a prompt
    {:ok, prompt} = PhoenixKitAI.create_prompt(%{
      name: "Translator",
      content: "Translate the following text to {{Language}}:\n\n{{Text}}"
    })
    # Variables auto-extracted: ["Language", "Text"]

    # Render with variables
    {:ok, text} = PhoenixKitAI.Prompt.render(prompt, %{
      "Language" => "French",
      "Text" => "Hello, world!"
    })
    # => "Translate the following text to French:\n\nHello, world!"

    # Use with AI completion
    {:ok, response} = PhoenixKitAI.ask_with_prompt(
      endpoint_uuid,
      prompt.uuid,
      %{"Language" => "Spanish", "Text" => "Good morning"}
    )

# `t`

```elixir
@type t() :: %PhoenixKitAI.Prompt{
  __meta__: term(),
  content: term(),
  description: term(),
  enabled: term(),
  inserted_at: term(),
  last_used_at: term(),
  metadata: term(),
  name: term(),
  slug: term(),
  sort_order: term(),
  system_prompt: term(),
  updated_at: term(),
  usage_count: term(),
  uuid: term(),
  variables: term()
}
```

# `changeset`

Creates a changeset for prompt creation and updates.

# `content_preview`

Returns a truncated preview of the content for display.

# `extract_variables`

Extracts variable names from content.

Variables are matched using the `{{VariableName}}` syntax.
Returns a list of unique variable names in order of appearance.

## Examples

    iex> PhoenixKitAI.Prompt.extract_variables("Hello {{Name}}, welcome to {{Place}}!")
    ["Name", "Place"]

    iex> PhoenixKitAI.Prompt.extract_variables("No variables here")
    []

    iex> PhoenixKitAI.Prompt.extract_variables("{{A}} and {{B}} and {{A}} again")
    ["A", "B"]

# `format_variables_for_display`

Formats variables for display in the UI.

Returns a string like "{{Name}}, {{Age}}" for easy display.

## Examples

    iex> prompt = %PhoenixKitAI.Prompt{variables: ["Name", "Age"]}
    iex> PhoenixKitAI.Prompt.format_variables_for_display(prompt)
    "{{Name}}, {{Age}}"

    iex> prompt = %PhoenixKitAI.Prompt{variables: []}
    iex> PhoenixKitAI.Prompt.format_variables_for_display(prompt)
    ""

# `generate_slug`

Generates a URL-friendly slug from the name.

Uses `PhoenixKit.Utils.Slug.slugify/1` for consistent slug generation.

## Examples

    iex> PhoenixKitAI.Prompt.generate_slug("My Cool Prompt!")
    "my-cool-prompt"

    iex> PhoenixKitAI.Prompt.generate_slug("Translate to French")
    "translate-to-french"

# `has_variables?`

Checks if a prompt has any variables defined.

## Examples

    iex> prompt = %PhoenixKitAI.Prompt{variables: ["Name", "Age"]}
    iex> PhoenixKitAI.Prompt.has_variables?(prompt)
    true

    iex> prompt = %PhoenixKitAI.Prompt{variables: []}
    iex> PhoenixKitAI.Prompt.has_variables?(prompt)
    false

# `invalid_variables`

Returns a list of invalid variable patterns in the content.

Useful for showing validation errors in the UI.

## Examples

    iex> PhoenixKitAI.Prompt.invalid_variables("Hello {{Name}}!")
    []

    iex> PhoenixKitAI.Prompt.invalid_variables("{{User Name}} and {{ok}}")
    ["User Name"]

# `merge_with_defaults`

Merges provided variables with defaults for missing ones.

Returns a map with all required variables, using defaults for any not provided.

## Examples

    iex> prompt = %PhoenixKitAI.Prompt{variables: ["Name", "Age"]}
    iex> PhoenixKitAI.Prompt.merge_with_defaults(prompt, %{"Name" => "John"}, %{"Age" => "Unknown"})
    %{"Name" => "John", "Age" => "Unknown"}

# `render`

Renders a prompt by replacing variables with provided values.

Variables not found in the values map remain as-is in the output.
Supports both string and atom keys in the values map.

## Examples

    iex> prompt = %PhoenixKitAI.Prompt{content: "Hello {{Name}}!"}
    iex> PhoenixKitAI.Prompt.render(prompt, %{"Name" => "World"})
    {:ok, "Hello World!"}

    iex> prompt = %PhoenixKitAI.Prompt{content: "Translate to {{Lang}}: {{Text}}"}
    iex> PhoenixKitAI.Prompt.render(prompt, %{Lang: "French", Text: "Hello"})
    {:ok, "Translate to French: Hello"}

    iex> prompt = %PhoenixKitAI.Prompt{content: "Missing {{Var}}"}
    iex> PhoenixKitAI.Prompt.render(prompt, %{})
    {:ok, "Missing {{Var}}"}

# `render_content`

Renders content string directly (without a Prompt struct).

Useful for previewing variable substitution.

## Examples

    iex> PhoenixKitAI.Prompt.render_content("Hello {{Name}}!", %{"Name" => "World"})
    {:ok, "Hello World!"}

# `render_system_prompt`

Renders the system prompt by replacing variables with provided values.

Returns `{:ok, rendered}` if system_prompt is set, or `{:ok, nil}` if not.

## Examples

    iex> prompt = %PhoenixKitAI.Prompt{system_prompt: "You are a {{Role}}"}
    iex> PhoenixKitAI.Prompt.render_system_prompt(prompt, %{"Role" => "translator"})
    {:ok, "You are a translator"}

    iex> prompt = %PhoenixKitAI.Prompt{system_prompt: nil}
    iex> PhoenixKitAI.Prompt.render_system_prompt(prompt, %{})
    {:ok, nil}

# `usage_changeset`

Creates a changeset for incrementing usage.

# `valid_content?`

Checks if content has valid variable syntax.

A valid variable name starts with a letter or underscore and contains only
letters, digits, and underscores. Leading digits are not allowed.

Returns `true` if all `{{...}}` patterns contain valid variable names,
or if there are no variables.

## Examples

    iex> PhoenixKitAI.Prompt.valid_content?("Hello {{Name}}!")
    true

    iex> PhoenixKitAI.Prompt.valid_content?("No variables here")
    true

    iex> PhoenixKitAI.Prompt.valid_content?("Hello {{User Name}}!")
    false

    iex> PhoenixKitAI.Prompt.valid_content?("Hello {{1st_name}}!")
    false

# `validate_variables`

Validates that all required variables are provided.

Returns `:ok` if all variables are present, or `{:error, missing}` with
a list of missing variable names.

## Examples

    iex> prompt = %PhoenixKitAI.Prompt{variables: ["Name", "Age"]}
    iex> PhoenixKitAI.Prompt.validate_variables(prompt, %{"Name" => "John", "Age" => "30"})
    :ok

    iex> prompt = %PhoenixKitAI.Prompt{variables: ["Name", "Age"]}
    iex> PhoenixKitAI.Prompt.validate_variables(prompt, %{"Name" => "John"})
    {:error, ["Age"]}

# `variable_count`

Returns the number of variables in a prompt.

## Examples

    iex> prompt = %PhoenixKitAI.Prompt{variables: ["Name", "Age"]}
    iex> PhoenixKitAI.Prompt.variable_count(prompt)
    2

# `variable_regex`

Returns the variable regex pattern.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
