# `PtcRunner.Prompts`
[🔗](https://github.com/andreasronge/ptc_runner/blob/main/lib/ptc_runner/prompts.ex#L1)

Centralized prompt loading for PtcRunner.

All prompt templates are loaded from `priv/prompts/` at compile time and
exposed through this module. Changes to prompt files trigger recompilation.

## Prompt Files (2-Axis Architecture)

Language specs are composed from two axes plus optional capabilities:

| Axis | File | Function |
|------|------|----------|
| Reference | `reference.md` | `reference/0` |
| Behavior | `behavior-single-shot.md` | `behavior_single_shot/0` |
| Behavior | `behavior-multi-turn.md` | `behavior_multi_turn/0` |
| Return mode | `behavior-return-explicit.md` | `behavior_return_explicit/0` |
| Capability | `capability-journal.md` | `capability_journal/0` |

## Other Prompt Files

| File | Function | Used By |
|------|----------|---------|
| `json-system.md` | `json_system/0` | `JsonMode` |
| `json-user.md` | `json_user/0` | `JsonMode` |
| `json-error.md` | `json_error/0` | `JsonMode` |
| `tool-calling-system.md` | `tool_calling_system/0` | `ToolCallingMode` |
| `ptc_text_mode_compact_reference.md` | `ptc_text_mode_compact_reference/0` | `SystemPrompt` (combined mode) |
| `turn-feedback-must-return.md` | `must_return_warning/0` | `TurnFeedback` |
| `turn-feedback-retry.md` | `retry_feedback/0` | `TurnFeedback` |

## File Format

Prompt files use HTML comment markers to separate metadata from content:

    # Title
    Description for maintainers.

    <!-- version: 1 -->
    <!-- date: 2026-01-01 -->
    <!-- prompt-guidelines: priv/prompts/README.md -->
    <!-- audience: audience-name -->
    <!-- budget: target<=1000 bytes, hard<=1500 bytes -->

    <!-- PTC_PROMPT_START -->
    Actual prompt content here.
    <!-- PTC_PROMPT_END -->

Content between `PTC_PROMPT_START` and `PTC_PROMPT_END` markers is extracted.
If no markers exist, the entire file (trimmed) is used.

## Mustache Templates

Some prompts use Mustache templating (e.g., `turn-feedback-must-return.md`):

- `{{variable}}` - Simple substitution
- `{{#section}}...{{/section}}` - Conditional/iteration
- `{{^section}}...{{/section}}` - Inverted (if falsy)

See `PtcRunner.Mustache` for expansion.

## Adding New Prompts

1. Create `priv/prompts/my-prompt.md` with markers
2. Add to this module:
   - `@my_prompt_file` path
   - `@external_resource @my_prompt_file`
   - `@my_prompt` loaded content
   - `def my_prompt, do: @my_prompt`
3. Document in the table above

# `behavior_multi_turn`

```elixir
@spec behavior_multi_turn() :: String.t()
```

Shared multi-turn core: one code block per turn, state, short programs.

# `behavior_multi_turn_with_header`

```elixir
@spec behavior_multi_turn_with_header() :: {String.t(), String.t()}
```

Raw header + content for behavior-multi-turn.md.

# `behavior_return_explicit`

```elixir
@spec behavior_return_explicit() :: String.t()
```

Explicit return fragment: use (return ...) / (fail ...).

# `behavior_return_explicit_with_header`

```elixir
@spec behavior_return_explicit_with_header() :: {String.t(), String.t()}
```

Raw header + content for behavior-return-explicit.md.

# `behavior_single_shot`

```elixir
@spec behavior_single_shot() :: String.t()
```

Single-shot behavior: last expression is the answer, one turn.

# `behavior_single_shot_with_header`

```elixir
@spec behavior_single_shot_with_header() :: {String.t(), String.t()}
```

Raw header + content for behavior-single-shot.md.

# `capability_journal`

```elixir
@spec capability_journal() :: String.t()
```

Journal capability: task caching, step-done, semantic progress.

# `capability_journal_with_header`

```elixir
@spec capability_journal_with_header() :: {String.t(), String.t()}
```

Raw header + content for capability-journal.md.

# `get`

```elixir
@spec get(atom()) :: String.t() | nil
```

Get a prompt by key.

## Examples

    iex> prompt = PtcRunner.Prompts.get(:reference)
    iex> byte_size(prompt) > 0
    true

    iex> PtcRunner.Prompts.get(:unknown)
    nil

# `json_error`

```elixir
@spec json_error() :: String.t()
```

Text mode (JSON variant) error feedback template (Mustache).

# `json_system`

```elixir
@spec json_system() :: String.t()
```

Text mode (JSON variant) system prompt.

# `json_user`

```elixir
@spec json_user() :: String.t()
```

Text mode (JSON variant) user message template (Mustache).

# `list`

```elixir
@spec list() :: [atom()]
```

List all available prompt keys.

## Examples

    iex> keys = PtcRunner.Prompts.list()
    iex> :reference in keys
    true

# `must_return_warning`

```elixir
@spec must_return_warning() :: String.t()
```

Final work turn warning template (Mustache).

Variables: `has_retries` (bool), `retry_count` (int).

# `ptc_text_mode_compact_reference`

```elixir
@spec ptc_text_mode_compact_reference() :: String.t()
```

Compact PTC-Lisp reference card for combined-mode system prompts.

Appended to the system prompt when `output: :text`, `ptc_transport:
:tool_call`, and `ptc_reference: :compact` (the default in combined
mode). Capped at ≤300 tokens. The static portion is loaded from
`priv/prompts/ptc_text_mode_compact_reference.md`; tool-inventory
entries are appended dynamically by `SystemPrompt`.

# `reference`

```elixir
@spec reference() :: String.t()
```

Language reference: tool syntax, Java interop, restrictions.

# `reference_with_header`

```elixir
@spec reference_with_header() :: {String.t(), String.t()}
```

Raw header + content for reference.md.

# `retry_feedback`

```elixir
@spec retry_feedback() :: String.t()
```

Retry phase feedback template (Mustache).

Variables: `is_final_retry`, `current_retry`, `total_retries`,
`retries_remaining`, `next_turn`.

# `tool_calling_system`

```elixir
@spec tool_calling_system() :: String.t()
```

Tool calling mode system prompt.

---

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