# `Anubis.Server.Component.Prompt`

Defines the behaviour for MCP prompts.

Prompts are reusable templates that generate messages based on provided arguments.
They help standardize common interactions and can be customized with parameters.

## Example

    defmodule MyServer.Prompts.CodeReview do
      @behaviour Anubis.Server.Behaviour.Prompt
      
      alias Anubis.Server.{Frame, Response}
      
      @impl true
      def name, do: "code_review"
      
      @impl true
      def description do
        "Generate a code review prompt for the given programming language and code"
      end
      
      @impl true
      def arguments do
        [
          %{
            "name" => "language",
            "description" => "The programming language of the code",
            "required" => true
          },
          %{
            "name" => "code",
            "description" => "The code to review",
            "required" => true
          },
          %{
            "name" => "focus_areas",
            "description" => "Specific areas to focus on (e.g., performance, security)",
            "required" => false
          }
        ]
      end
      
      @impl true
      def get_messages(%{"language" => lang, "code" => code} = args, frame) do
        focus = Map.get(args, "focus_areas", "general quality")
        
        messages = [
          %{
            "role" => "user",
            "content" => %{
              "type" => "text",
              "text" => """
              Please review the following #{lang} code, focusing on #{focus}:
              
              ```#{lang}
              #{code}
              ```
              
              Provide constructive feedback on:
              1. Code quality and readability
              2. Potential bugs or issues
              3. Performance considerations
              4. Best practices for #{lang}
              """
            }
          }
        ]
        
        # Can track prompt usage
        new_frame = Frame.assign(frame, :last_prompt_used, "code_review")
        
        response =
          Response.prompt()
          |> Response.user_message(Enum.map_join(messages, "
", & &1["content"]["text"]))

        {:reply, response, new_frame}
      end
    end

# `argument_def`

```elixir
@type argument_def() :: %{
  required(String.t()) =&gt; String.t(),
  optional(String.t()) =&gt; boolean()
}
```

# `arguments`

```elixir
@type arguments() :: map()
```

# `message`

```elixir
@type message() :: map()
```

# `t`

```elixir
@type t() :: %Anubis.Server.Component.Prompt{
  arguments: map() | nil,
  description: String.t() | nil,
  handler: module() | nil,
  name: String.t(),
  title: String.t() | nil,
  validate_input: (map() -&gt; {:ok, map()} | {:error, [Peri.Error.t()]}) | nil
}
```

# `arguments`

```elixir
@callback arguments() :: [argument_def()]
```

Returns the list of arguments this prompt accepts.

Each argument should include:
- `"name"` - The argument name
- `"description"` - What the argument is for
- `"required"` - Whether the argument is required (optional, defaults to false)

## Example

    [
      %{
        "name" => "topic",
        "description" => "The topic to generate content about",
        "required" => true
      },
      %{
        "name" => "tone",
        "description" => "The tone of voice (formal, casual, etc.)",
        "required" => false
      }
    ]

# `description`
*optional* 

```elixir
@callback description() :: String.t()
```

Returns the description of this prompt.

The description helps AI assistants understand what the prompt does and when to use it.
If not provided, the module's `@moduledoc` will be used automatically.

## Examples

    def description do
      "Generate a code review with best practices"
    end

    # With dynamic content
    def description do
      model = Application.get_env(:my_app, :analysis_model, "default")
      "Analyze code using #{model} model"
    end

# `get_messages`

```elixir
@callback get_messages(args :: arguments(), frame :: Anubis.Server.Frame.t()) ::
  {:reply, response :: Anubis.Server.Response.t(),
   new_state :: Anubis.Server.Frame.t()}
  | {:noreply, new_state :: Anubis.Server.Frame.t()}
  | {:error, error :: Anubis.MCP.Error.t(),
     new_state :: Anubis.Server.Frame.t()}
```

Generates messages based on the provided arguments.

## Parameters

- `args` - The arguments provided by the client
- `frame` - The server frame containing context and state

## Return Values

- `{:reply, %Response{}, frame}` - Messages generated successfully
- `{:noreply, frame}` - No reply needed
- `{:error, %Error{}, frame}` - Failed to generate messages

## Building Responses

Use `Response.prompt/0` to create a prompt response, then add messages with
`Response.user_message/2` or `Response.system_message/2`:

    response =
      Response.prompt()
      |> Response.user_message("Please review this code")
      |> Response.system_message("You are a code reviewer")

    {:reply, response, frame}

# `title`
*optional* 

```elixir
@callback title() :: String.t()
```

Returns the title that identifies this resource.

Intended for UI and end-user contexts — optimized to be human-readable and easily understood,
even by those unfamiliar with domain-specific terminology.

If not provided, the name should be used for display.

---

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